Merge branch 'master' into dev-karaf-4.2.1
Change-Id: If6c7d5f1dc6434ac8ea2fd9716b8ebeee38daa50
diff --git a/.gitreview b/.gitreview
index b86ceb3..328aec6 100644
--- a/.gitreview
+++ b/.gitreview
@@ -3,4 +3,4 @@
port=29418
project=onos.git
defaultremote=origin
-defaultbranch=dev-karaf-4.2.1
+defaultbranch=master
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayCommand.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayCommand.java
index 4145cd2..da6a4ac 100644
--- a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayCommand.java
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayCommand.java
@@ -199,7 +199,13 @@
});
}
- private String ip4State(DhcpRecord record) {
+ /**
+ * To return ipv4state.
+ *
+ * @param record DhcpRecord object
+ * @return ipState type String
+ */
+ public String ip4State(DhcpRecord record) {
String nextHopIp = findNextHopIp(IpAddress::isIp4,
record.nextHop().orElse(null),
record.vlanId());
@@ -209,7 +215,14 @@
nextHopIp);
}
- private String ip6State(DhcpRecord record) {
+ /**
+ * To return ipv6state.
+ *
+ * @param record DhcpRecord object
+ * @return ipState type String
+ */
+
+ public String ip6State(DhcpRecord record) {
String nextHopIp = findNextHopIp6(IpAddress::isIp6,
record.nextHop().orElse(null),
record.vlanId());
diff --git a/apps/dhcprelay/web/src/main/java/org/onosproject/dhcprelay/rest/DhcpRelayWebResource.java b/apps/dhcprelay/web/src/main/java/org/onosproject/dhcprelay/rest/DhcpRelayWebResource.java
index 9338a4b..1a48ea5 100644
--- a/apps/dhcprelay/web/src/main/java/org/onosproject/dhcprelay/rest/DhcpRelayWebResource.java
+++ b/apps/dhcprelay/web/src/main/java/org/onosproject/dhcprelay/rest/DhcpRelayWebResource.java
@@ -19,7 +19,15 @@
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
+import org.onlab.util.Tools;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.dhcprelay.api.DhcpRelayService;
+import org.onosproject.dhcprelay.api.DhcpServerInfo;
+import org.onosproject.dhcprelay.cli.DhcpRelayCommand;
+import org.onosproject.dhcprelay.store.DhcpRecord;
+import org.onosproject.dhcprelay.store.DhcpRelayCounters;
import org.onosproject.rest.AbstractWebResource;
import org.onosproject.routeservice.Route;
import org.onosproject.routeservice.RouteStore;
@@ -27,11 +35,18 @@
import org.slf4j.Logger;
import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;
+import java.util.Collection;
+import java.util.Map;
+import java.util.List;
import java.util.Optional;
import static org.slf4j.LoggerFactory.getLogger;
@@ -42,6 +57,13 @@
@Path("fpm-delete")
public class DhcpRelayWebResource extends AbstractWebResource {
private static final Logger LOG = getLogger(DhcpRelayWebResource.class);
+ private final ObjectMapper mapper = new ObjectMapper();
+ private final DhcpRelayService dhcpDelayService = get(DhcpRelayService.class);
+ private static final String NA = "N/A";
+ List<DhcpServerInfo> defaultDhcpServerInfoList = dhcpDelayService.getDefaultDhcpServerInfoList();
+ List<DhcpServerInfo> indirectDhcpServerInfoList = dhcpDelayService.getIndirectDhcpServerInfoList();
+ Collection<DhcpRecord> records = dhcpDelayService.getDhcpRecords();
+
/**
* Deletes the fpm route from fpm record.
@@ -74,5 +96,170 @@
return Response.noContent().build();
}
+ /**
+ * Returns the response object with list of dhcp servers without counters.
+ *
+ * @return 200 OK with component properties of given component and variable
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("dhcp-relay")
+ public Response getDhcpServers() {
+ ObjectNode node = getdhcpRelayJsonOutput(null, null);
+ return Response.status(200).entity(node).build();
+ }
+
+ /**
+ * Returns dhcp servers details with counters.
+ *
+ * @param counter source ip identifier
+ * @return 200 OK with component properties of given component and variable
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("dhcp-relay/{counter}")
+ public Response getDhcpRelayCounter(@PathParam("counter") String counter) {
+ ObjectNode node = getdhcpRelayJsonOutput(counter, null);
+ return Response.status(200).entity(node).build();
+ }
+
+ /**
+ * To reset the dhcp relay counters.
+ *
+ * @param counter type String
+ * @param reset type String
+ * @return 200 OK with component properties of given component and variable
+ */
+ @PUT
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("dhcp-relay/{counter}/{reset}")
+ public Response resetDhcpRelayCounter(@PathParam("counter") String counter, @PathParam("reset") String reset) {
+ ObjectNode node = getdhcpRelayJsonOutput(counter, reset);
+ return Response.status(200).entity(node).build();
+ }
+
+
+ /**
+ * To create json output.
+ *
+ * @param counter type String
+ * @param reset type String
+ * @return node type ObjectNode.
+ */
+ private ObjectNode getdhcpRelayJsonOutput(String counter, String reset) {
+ ObjectNode node = mapper.createObjectNode();
+ ObjectNode dhcpRelayServerNode = mapper.createObjectNode();
+ if (!defaultDhcpServerInfoList.isEmpty()) {
+ ArrayNode defaultDhcpServers = listServers(defaultDhcpServerInfoList);
+ dhcpRelayServerNode.put("Default-DHCP-Server", defaultDhcpServers);
+ }
+ if (!indirectDhcpServerInfoList.isEmpty()) {
+ ArrayNode indirectDhcpServers = listServers(indirectDhcpServerInfoList);
+ dhcpRelayServerNode.put("Indirect-DHCP-Server", indirectDhcpServers);
+ }
+
+ ArrayNode dhcpRecords = dhcpRelayRecords(records);
+ dhcpRelayServerNode.put("DHCP-Relay-Records([D]:Directly-Connected)", dhcpRecords);
+ if (counter != null && !counter.equals("counter")) {
+ ArrayNode counterArray = dhcpRelayCounters(reset);
+ dhcpRelayServerNode.put("DHCP-Relay-Counter", counterArray);
+ }
+ node.put("Default-DHCP-Servers", dhcpRelayServerNode);
+
+ return node;
+
+ }
+ /**
+ * To get the liset of dhcp servers.
+ *
+ * @param dhcpServerInfoList type List
+ * @return servers type ArrayNode.
+ */
+ private ArrayNode listServers(List<DhcpServerInfo> dhcpServerInfoList) {
+ ArrayNode servers = mapper.createArrayNode();
+ dhcpServerInfoList.forEach(dhcpServerInfo -> {
+ ObjectNode serverNode = mapper.createObjectNode();
+ String connectPoint = dhcpServerInfo.getDhcpServerConnectPoint()
+ .map(cp -> cp.toString()).orElse(NA);
+ String serverMac = dhcpServerInfo.getDhcpConnectMac()
+ .map(mac -> mac.toString()).orElse(NA);
+ String gatewayAddress;
+ String serverIp;
+
+ switch (dhcpServerInfo.getVersion()) {
+ case DHCP_V4:
+ gatewayAddress = dhcpServerInfo.getDhcpGatewayIp4()
+ .map(gw -> gw.toString()).orElse(null);
+ serverIp = dhcpServerInfo.getDhcpServerIp4()
+ .map(ip -> ip.toString()).orElse(NA);
+ break;
+ case DHCP_V6:
+ gatewayAddress = dhcpServerInfo.getDhcpGatewayIp6()
+ .map(gw -> gw.toString()).orElse(null);
+ serverIp = dhcpServerInfo.getDhcpServerIp6()
+ .map(ip -> ip.toString()).orElse(NA);
+ break;
+ default:
+ return;
+ }
+
+ serverNode.put("connectPoint", connectPoint);
+ if (gatewayAddress != null) {
+ serverNode.put("server", serverIp.concat(" via ").concat(gatewayAddress));
+ } else {
+ serverNode.put("server", serverIp);
+ }
+ serverNode.put("mac", serverMac);
+ servers.add(serverNode);
+ });
+ return servers;
+}
+
+ /**
+ * To get the list of dhcp relay records.
+ *
+ * @param records type Collections
+ * @return dhcpRelayRecords type ArrayNode.
+ */
+ private ArrayNode dhcpRelayRecords(Collection<DhcpRecord> records) {
+ DhcpRelayCommand dhcpRelayCommand = new DhcpRelayCommand();
+ ArrayNode dhcpRelayRecords = mapper.createArrayNode();
+ records.forEach(record -> {
+ ObjectNode dhcpRecord = mapper.createObjectNode();
+ dhcpRecord.put("id", record.macAddress() + "/" + record.vlanId());
+ dhcpRecord.put("locations", record.locations().toString());
+ dhcpRecord.put("last-seen", Tools.timeAgo(record.lastSeen()));
+ dhcpRecord.put("IPv4", dhcpRelayCommand.ip4State(record));
+ dhcpRecord.put("IPv6", dhcpRelayCommand.ip6State(record));
+ dhcpRelayRecords.add(dhcpRecord);
+ });
+ return dhcpRelayRecords;
+ }
+
+ /**
+ * To get the details of dhcp relay counters.
+ *
+ * @param reset type String
+ * @return counterArray type ArrayNode.
+ */
+ private ArrayNode dhcpRelayCounters(String reset) {
+ ObjectNode counters = mapper.createObjectNode();
+ ObjectNode counterPackets = mapper.createObjectNode();
+ ArrayNode counterArray = mapper.createArrayNode();
+ records.forEach(record -> {
+ DhcpRelayCounters v6Counters = record.getV6Counters();
+ if (reset != null && reset.equals("reset")) {
+ v6Counters.resetCounters();
+ }
+ Map<String, Integer> countersMap = v6Counters.getCounters();
+ countersMap.forEach((name, value) -> {
+ counterPackets.put(name, value);
+
+ });
+ counters.put(record.locations().toString(), counterPackets);
+ counterArray.add(counters);
+ });
+ return counterArray;
+ }
}
diff --git a/apps/kafka-integration/BUILD b/apps/kafka-integration/BUILD
index c0b04d9..9077b7e 100644
--- a/apps/kafka-integration/BUILD
+++ b/apps/kafka-integration/BUILD
@@ -1,19 +1,17 @@
-# FIXME: Work in progress
-
BUNDLES = [
- "@kafka-clients//jar",
- "@protobuf-java-3.2.0//jar",
+ "@kafka_clients//jar",
+ "@runtime_protobuf//jar",
"//incubator/protobuf/models:onos-incubator-protobuf-models",
- "//incubator/protobuf/models:onos-incubator-protobuf-models-proto",
+ "//incubator/protobuf/models/proto:onos-incubator-protobuf-models-proto",
"//apps/kafka-integration/api:onos-apps-kafka-integration-api",
"//apps/kafka-integration/app:onos-apps-kafka-integration-app",
]
-#onos_app (
-# title = "Kafka Integration",
-# category = "Integration",
-# url = "http://onosproject.org",
-# description = "Provides integration of ONOS and Kafka message bus so that internal ONOS events " +
-# "can be broadcast over the Kafka message bus to off-platform applications.",
-# included_bundles = BUNDLES,
-#)
+onos_app(
+ category = "Integration",
+ description = "Provides integration of ONOS and Kafka message bus so that internal ONOS events " +
+ "can be broadcast over the Kafka message bus to off-platform applications.",
+ included_bundles = BUNDLES,
+ title = "Kafka Integration",
+ url = "http://onosproject.org",
+)
diff --git a/apps/kafka-integration/app/BUILD b/apps/kafka-integration/app/BUILD
index d711987..2b39734 100644
--- a/apps/kafka-integration/app/BUILD
+++ b/apps/kafka-integration/app/BUILD
@@ -1,21 +1,20 @@
-# FIXME: Work in progress
-
COMPILE_DEPS = CORE_DEPS + JACKSON + KRYO + CLI + [
"//apps/kafka-integration/api:onos-apps-kafka-integration-api",
"//core/store/serializers:onos-core-serializers",
"@kafka_clients//jar",
- "@protobuf-java-3.2.0//jar",
- "//lib:GRPC_1.3",
+ "@javax_ws_rs_api//jar",
+ "//utils/rest:onlab-rest",
+ "@com_google_protobuf//:protobuf_java",
"//incubator/protobuf/models:onos-incubator-protobuf-models",
- "//incubator/protobuf/models:onos-incubator-protobuf-models-proto",
+ "//incubator/protobuf/models/proto:onos-incubator-protobuf-models-proto",
]
-#osgi_jar_with_tests (
-# deps = COMPILE_DEPS,
-# test_deps = TEST_ADAPTERS,
-# web_context = "/onos/kafka-integration",
-# api_title = "Kafka Integration",
-# api_version = "1.0",
-# api_description = "REST API for Kafka Integration",
-# api_package = "org.onosproject.kafkaintegration.rest",
-#)
+osgi_jar_with_tests(
+ api_description = "REST API for Kafka Integration",
+ api_package = "org.onosproject.kafkaintegration.rest",
+ api_title = "Kafka Integration",
+ api_version = "1.0",
+ test_deps = TEST_ADAPTERS,
+ web_context = "/onos/kafka-integration",
+ deps = COMPILE_DEPS,
+)
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java
index 2021aa8..ec7204e 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java
@@ -63,7 +63,6 @@
import org.onosproject.openstacknode.api.OpenstackNodeEvent;
import org.onosproject.openstacknode.api.OpenstackNodeListener;
import org.onosproject.openstacknode.api.OpenstackNodeService;
-import org.openstack4j.model.network.ExternalGateway;
import org.openstack4j.model.network.IP;
import org.openstack4j.model.network.NetFloatingIP;
import org.openstack4j.model.network.Network;
@@ -98,11 +97,13 @@
import static org.onosproject.openstacknetworking.impl.OsgiPropertyConstants.ARP_MODE_DEFAULT;
import static org.onosproject.openstacknetworking.impl.OsgiPropertyConstants.GATEWAY_MAC_DEFAULT;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.associatedFloatingIp;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.externalPeerRouterForNetwork;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.floatingIpByInstancePort;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getGwByComputeDevId;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getGwByInstancePort;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getPropertyValue;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.isAssociatedWithVM;
-import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.processGratuitousArpPacketForFloatingIp;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.processGarpPacketForFloatingIp;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.swapStaleLocation;
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
@@ -245,14 +246,16 @@
targetMac = instPort.macAddress();
}
- OpenstackNode gw = getGwByInstancePort(osNodeService.completeNodes(GATEWAY), instPort);
+ OpenstackNode gw =
+ getGwByInstancePort(osNodeService.completeNodes(GATEWAY), instPort);
if (gw == null) {
return;
}
// if the ARP packet_in received from non-relevant GWs, we simply ignore it
- if (!Objects.equals(gw.intgBridge(), context.inPacket().receivedFrom().deviceId())) {
+ if (!Objects.equals(gw.intgBridge(),
+ context.inPacket().receivedFrom().deviceId())) {
return;
}
}
@@ -290,8 +293,10 @@
try {
- Set<String> extRouterIps = osNetworkService.externalPeerRouters().
- stream().map(r -> r.ipAddress().toString()).collect(Collectors.toSet());
+ Set<String> extRouterIps = osNetworkService.externalPeerRouters()
+ .stream()
+ .map(r -> r.ipAddress().toString())
+ .collect(Collectors.toSet());
// if SPA is NOT contained in existing external router IP set, we ignore it
if (!extRouterIps.contains(spa.toString())) {
@@ -358,7 +363,8 @@
* @param gateway gateway node
* @param install flow rule installation flag
*/
- private void setFloatingIpArpRuleForGateway(OpenstackNode gateway, boolean install) {
+ private void setFloatingIpArpRuleForGateway(OpenstackNode gateway,
+ boolean install) {
if (ARP_BROADCAST_MODE.equals(getArpMode())) {
Set<OpenstackNode> completedGws = osNodeService.completeNodes(GATEWAY);
@@ -371,14 +377,16 @@
finalGws.remove(gateway);
osRouterAdminService.floatingIps().forEach(fip -> {
if (fip.getPortId() != null) {
- setFloatingIpArpRule(fip, fip.getPortId(), finalGws, false);
+ setFloatingIpArpRule(fip, fip.getPortId(),
+ finalGws, false);
finalGws.add(gateway);
}
});
}
osRouterAdminService.floatingIps().forEach(fip -> {
if (fip.getPortId() != null) {
- setFloatingIpArpRule(fip, fip.getPortId(), finalGws, true);
+ setFloatingIpArpRule(fip, fip.getPortId(),
+ finalGws, true);
}
});
} else {
@@ -389,14 +397,16 @@
finalGws.add(gateway);
osRouterAdminService.floatingIps().forEach(fip -> {
if (fip.getPortId() != null) {
- setFloatingIpArpRule(fip, fip.getPortId(), finalGws, false);
+ setFloatingIpArpRule(fip, fip.getPortId(),
+ finalGws, false);
}
});
finalGws.remove(gateway);
if (completedGws.size() >= 1) {
osRouterAdminService.floatingIps().forEach(fip -> {
if (fip.getPortId() != null) {
- setFloatingIpArpRule(fip, fip.getPortId(), finalGws, true);
+ setFloatingIpArpRule(fip, fip.getPortId(),
+ finalGws, true);
}
});
}
@@ -520,15 +530,16 @@
}
private void setFakeGatewayArpRuleByRouter(Router router, boolean install) {
- setFakeGatewayArpRuleByGateway(router.getId(), router.getExternalGatewayInfo(), install);
+ setFakeGatewayArpRuleByGateway(router.getId(), install);
}
- private Set<IP> getExternalGatewaySnatIps(String routerId, ExternalGateway extGw) {
+ private Set<IP> getExternalGatewaySnatIps(String routerId) {
if (routerId == null) {
return ImmutableSet.of();
}
- Set<String> portIds = osRouterAdminService.routerInterfaces(routerId).stream()
+ Set<String> portIds = osRouterAdminService.routerInterfaces(routerId)
+ .stream()
.map(RouterInterface::getPortId)
.collect(Collectors.toSet());
@@ -539,14 +550,9 @@
.collect(Collectors.toSet());
}
- private void setFakeGatewayArpRuleByGateway(String routerId, ExternalGateway extGw, boolean install) {
+ private void setFakeGatewayArpRuleByGateway(String routerId, boolean install) {
if (ARP_BROADCAST_MODE.equals(getArpMode())) {
-
- if (extGw == null) {
- return;
- }
-
- setFakeGatewayArpRuleByIps(getExternalGatewaySnatIps(routerId, extGw), install);
+ setFakeGatewayArpRuleByIps(getExternalGatewaySnatIps(routerId), install);
}
}
@@ -611,12 +617,14 @@
case OPENSTACK_PORT_CREATED:
case OPENSTACK_PORT_UPDATED:
eventExecutor.execute(() ->
- setFakeGatewayArpRuleByIps((Set<IP>) event.port().getFixedIps(), true)
+ setFakeGatewayArpRuleByIps(
+ (Set<IP>) event.port().getFixedIps(), true)
);
break;
case OPENSTACK_PORT_REMOVED:
eventExecutor.execute(() ->
- setFakeGatewayArpRuleByIps((Set<IP>) event.port().getFixedIps(), false)
+ setFakeGatewayArpRuleByIps(
+ (Set<IP>) event.port().getFixedIps(), false)
);
break;
default:
@@ -660,58 +668,60 @@
case OPENSTACK_ROUTER_GATEWAY_ADDED:
eventExecutor.execute(() ->
// add a gateway manually after adding a router
- setFakeGatewayArpRuleByGateway(event.subject().getId(),
- event.externalGateway(), true)
+ setFakeGatewayArpRuleByGateway(event.subject().getId(), true)
);
break;
case OPENSTACK_ROUTER_GATEWAY_REMOVED:
eventExecutor.execute(() ->
// remove a gateway from an existing router
- setFakeGatewayArpRuleByGateway(event.subject().getId(),
- event.externalGateway(), false)
+ setFakeGatewayArpRuleByGateway(event.subject().getId(), false)
);
break;
case OPENSTACK_FLOATING_IP_ASSOCIATED:
- if (getValidPortId(event) != null) {
- eventExecutor.execute(() -> {
- // associate a floating IP with an existing VM
- setFloatingIpArpRule(event.floatingIp(), getValidPortId(event),
- completedGws, true);
- });
- }
+ eventExecutor.execute(() -> {
+ if (getValidPortId(event) == null) {
+ return;
+ }
+ // associate a floating IP with an existing VM
+ setFloatingIpArpRule(event.floatingIp(),
+ getValidPortId(event), completedGws, true);
+ });
break;
case OPENSTACK_FLOATING_IP_DISASSOCIATED:
- if (getValidPortId(event) != null) {
- eventExecutor.execute(() -> {
- // disassociate a floating IP with an existing VM
- setFloatingIpArpRule(event.floatingIp(), getValidPortId(event),
- completedGws, false);
- });
- }
+ eventExecutor.execute(() -> {
+ if (getValidPortId(event) == null) {
+ return;
+ }
+ // disassociate a floating IP with an existing VM
+ setFloatingIpArpRule(event.floatingIp(),
+ getValidPortId(event), completedGws, false);
+ });
break;
case OPENSTACK_FLOATING_IP_CREATED:
// during floating IP creation, if the floating IP is
// associated with any port of VM, then we will set
// floating IP related ARP rules to gateway node
- if (getValidPortId(event) != null) {
- eventExecutor.execute(() -> {
- // associate a floating IP with an existing VM
- setFloatingIpArpRule(event.floatingIp(), getValidPortId(event),
- completedGws, true);
- });
- }
+ eventExecutor.execute(() -> {
+ if (getValidPortId(event) == null) {
+ return;
+ }
+ // associate a floating IP with an existing VM
+ setFloatingIpArpRule(event.floatingIp(),
+ getValidPortId(event), completedGws, true);
+ });
break;
case OPENSTACK_FLOATING_IP_REMOVED:
// during floating IP deletion, if the floating IP is
// still associated with any port of VM, then we will
// remove floating IP related ARP rules from gateway node
- if (getValidPortId(event) != null) {
- eventExecutor.execute(() -> {
- // associate a floating IP with an existing VM
- setFloatingIpArpRule(event.floatingIp(), getValidPortId(event),
- completedGws, false);
- });
- }
+ eventExecutor.execute(() -> {
+ if (getValidPortId(event) == null) {
+ return;
+ }
+ // associate a floating IP with an existing VM
+ setFloatingIpArpRule(event.floatingIp(),
+ getValidPortId(event), completedGws, false);
+ });
break;
default:
// do nothing for the other events
@@ -754,50 +764,52 @@
switch (event.type()) {
case OPENSTACK_INSTANCE_PORT_DETECTED:
-
- osRouterAdminService.floatingIps().stream()
- .filter(f -> f.getPortId() != null)
- .filter(f -> f.getPortId().equals(instPort.portId()))
- .forEach(f -> setFloatingIpArpRule(f, instPort.portId(), gateways, true));
-
+ eventExecutor.execute(() ->
+ osRouterAdminService.floatingIps().stream()
+ .filter(f -> f.getPortId() != null)
+ .filter(f -> f.getPortId().equals(instPort.portId()))
+ .forEach(f -> setFloatingIpArpRule(f,
+ instPort.portId(), gateways, true))
+ );
break;
case OPENSTACK_INSTANCE_MIGRATION_STARTED:
-
- if (gateways.size() == 1) {
- return;
- }
-
- if (fip != null && isAssociatedWithVM(osNetworkService, fip)) {
- eventExecutor.execute(() ->
- setFloatingIpArpRuleWithPortEvent(fip, event.subject(),
- gateways, true)
- );
- }
-
- break;
- case OPENSTACK_INSTANCE_MIGRATION_ENDED:
-
- InstancePort revisedInstPort = swapStaleLocation(event.subject());
-
- if (gateways.size() == 1) {
- return;
- }
-
- if (fip != null && isAssociatedWithVM(osNetworkService, fip)) {
- DeviceId newDeviceId = event.subject().deviceId();
- DeviceId oldDeviceId = revisedInstPort.deviceId();
-
- OpenstackNode oldGw = getGwByComputeDevId(gateways, oldDeviceId);
- OpenstackNode newGw = getGwByComputeDevId(gateways, newDeviceId);
-
- if (oldGw != null && oldGw.equals(newGw)) {
+ eventExecutor.execute(() -> {
+ if (gateways.size() == 1) {
return;
}
- eventExecutor.execute(() ->
- setFloatingIpArpRuleWithPortEvent(fip,
- revisedInstPort, gateways, false));
- }
+ if (fip != null && isAssociatedWithVM(osNetworkService, fip)) {
+ setFloatingIpArpRuleWithPortEvent(fip,
+ event.subject(), gateways, true);
+ }
+ });
+
+ break;
+ case OPENSTACK_INSTANCE_MIGRATION_ENDED:
+ eventExecutor.execute(() -> {
+ InstancePort revisedInstPort = swapStaleLocation(event.subject());
+
+ if (gateways.size() == 1) {
+ return;
+ }
+
+ if (fip != null && isAssociatedWithVM(osNetworkService, fip)) {
+ DeviceId newDeviceId = event.subject().deviceId();
+ DeviceId oldDeviceId = revisedInstPort.deviceId();
+
+ OpenstackNode oldGw =
+ getGwByComputeDevId(gateways, oldDeviceId);
+ OpenstackNode newGw =
+ getGwByComputeDevId(gateways, newDeviceId);
+
+ if (oldGw != null && oldGw.equals(newGw)) {
+ return;
+ }
+
+ setFloatingIpArpRuleWithPortEvent(fip,
+ revisedInstPort, gateways, false);
+ }
+ });
break;
default:
break;
@@ -819,44 +831,52 @@
OpenstackNode osNode = event.subject();
switch (event.type()) {
case OPENSTACK_NODE_COMPLETE:
- setDefaultArpRule(osNode, true);
- setFloatingIpArpRuleForGateway(osNode, true);
- sendGratuitousArpToSwitch(event.subject(), true);
+ eventExecutor.execute(() -> {
+ setDefaultArpRule(osNode, true);
+ setFloatingIpArpRuleForGateway(osNode, true);
+ sendGratuitousArpToSwitch(event.subject(), true);
+ });
break;
case OPENSTACK_NODE_INCOMPLETE:
- setDefaultArpRule(osNode, false);
- setFloatingIpArpRuleForGateway(osNode, false);
- sendGratuitousArpToSwitch(event.subject(), false);
+ eventExecutor.execute(() -> {
+ setDefaultArpRule(osNode, false);
+ setFloatingIpArpRuleForGateway(osNode, false);
+ sendGratuitousArpToSwitch(event.subject(), false);
+ });
break;
case OPENSTACK_NODE_REMOVED:
- sendGratuitousArpToSwitch(event.subject(), false);
+ eventExecutor.execute(() -> {
+ sendGratuitousArpToSwitch(event.subject(), false);
+ });
break;
-
default:
break;
}
}
- private void sendGratuitousArpToSwitch(OpenstackNode gatewayNode, boolean isCompleteCase) {
- Set<OpenstackNode> completeGws = ImmutableSet.copyOf(osNodeService.completeNodes(GATEWAY));
+ private void sendGratuitousArpToSwitch(OpenstackNode gatewayNode,
+ boolean isCompleteCase) {
+ Set<OpenstackNode> completeGws =
+ ImmutableSet.copyOf(osNodeService.completeNodes(GATEWAY));
if (isCompleteCase) {
- osNodeService.completeNodes(COMPUTE)
- .stream()
- .filter(node -> isGwSelectedByComputeNode(completeGws, node, gatewayNode))
- .forEach(node -> processGratuitousArpPacketForComputeNode(node, gatewayNode));
+ osNodeService.completeNodes(COMPUTE).stream()
+ .filter(node -> isGwSelectedByComputeNode(completeGws,
+ node, gatewayNode))
+ .forEach(node -> processGarpPacketForComputeNode(node, gatewayNode));
} else {
Set<OpenstackNode> oldCompleteGws = Sets.newConcurrentHashSet();
oldCompleteGws.addAll(ImmutableSet.copyOf(osNodeService.completeNodes(GATEWAY)));
oldCompleteGws.add(gatewayNode);
- osNodeService.completeNodes(COMPUTE)
- .stream()
- .filter(node -> isGwSelectedByComputeNode(oldCompleteGws, node, gatewayNode))
+ osNodeService.completeNodes(COMPUTE).stream()
+ .filter(node -> isGwSelectedByComputeNode(oldCompleteGws,
+ node, gatewayNode))
.forEach(node -> {
- OpenstackNode newSelectedGatewayNode = getGwByComputeDevId(completeGws, node.intgBridge());
- processGratuitousArpPacketForComputeNode(node, newSelectedGatewayNode);
+ OpenstackNode newSelectedGatewayNode =
+ getGwByComputeDevId(completeGws, node.intgBridge());
+ processGarpPacketForComputeNode(node, newSelectedGatewayNode);
});
}
}
@@ -869,16 +889,20 @@
.intgBridge().equals(gwNode.intgBridge());
}
- private void processGratuitousArpPacketForComputeNode(OpenstackNode computeNode, OpenstackNode gatewayNode) {
- instancePortService.instancePort(computeNode.intgBridge()).forEach(instancePort -> {
- NetFloatingIP floatingIP = OpenstackNetworkingUtil.floatingIpByInstancePort(instancePort,
- osRouterAdminService);
+ private void processGarpPacketForComputeNode(OpenstackNode computeNode,
+ OpenstackNode gatewayNode) {
+ instancePortService.instancePort(computeNode.intgBridge())
+ .forEach(instancePort -> {
+ NetFloatingIP floatingIP =
+ floatingIpByInstancePort(instancePort, osRouterAdminService);
Network network = osNetworkService.network(instancePort.networkId());
- ExternalPeerRouter externalPeerRouter = OpenstackNetworkingUtil.externalPeerRouterForNetwork(network,
- osNetworkService, osRouterAdminService);
+ ExternalPeerRouter externalPeerRouter =
+ externalPeerRouterForNetwork(network, osNetworkService,
+ osRouterAdminService);
if (floatingIP != null && externalPeerRouter != null) {
- processGratuitousArpPacketForFloatingIp(
- floatingIP, instancePort, externalPeerRouter.vlanId(), gatewayNode, packetService);
+ processGarpPacketForFloatingIp(
+ floatingIP, instancePort, externalPeerRouter.vlanId(),
+ gatewayNode, packetService);
}
});
}
@@ -903,7 +927,8 @@
}
}
- private void setDefaultArpRuleForProxyMode(OpenstackNode osNode, boolean install) {
+ private void setDefaultArpRuleForProxyMode(OpenstackNode osNode,
+ boolean install) {
TrafficSelector selector = DefaultTrafficSelector.builder()
.matchEthType(EthType.EtherType.ARP.ethType().toShort())
.build();
@@ -923,7 +948,8 @@
);
}
- private void setDefaultArpRuleForBroadcastMode(OpenstackNode osNode, boolean install) {
+ private void setDefaultArpRuleForBroadcastMode(OpenstackNode osNode,
+ boolean install) {
// we only match ARP_REPLY in gateway node, because controller
// somehow need to process ARP_REPLY which is issued from
// external router...
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
index b2cb36e..f04e14a 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
@@ -85,7 +85,7 @@
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getGwByComputeDevId;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getGwByInstancePort;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.isAssociatedWithVM;
-import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.processGratuitousArpPacketForFloatingIp;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.processGarpPacketForFloatingIp;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.swapStaleLocation;
import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.buildExtension;
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
@@ -440,7 +440,8 @@
}
private void setUpstreamRules(NetFloatingIP floatingIp, Network osNet,
- InstancePort instPort, ExternalPeerRouter externalPeerRouter,
+ InstancePort instPort,
+ ExternalPeerRouter externalPeerRouter,
boolean install) {
IpAddress floating = IpAddress.valueOf(floatingIp.getFloatingIpAddress());
TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
@@ -515,12 +516,13 @@
ExternalPeerRouter externalPeerRouter =
externalPeerRouterForNetwork(osNet, osNetworkService, osRouterAdminService);
if (externalPeerRouter == null) {
- log.error("Failed to process GARP packet for floating ip {} because no external peer router found");
+ log.error("Failed to process GARP packet for floating ip {} " +
+ "because no external peer router found");
return;
}
- processGratuitousArpPacketForFloatingIp(floatingIP, instancePort, externalPeerRouter.vlanId(),
- selectedGw, packetService);
+ processGarpPacketForFloatingIp(floatingIP, instancePort,
+ externalPeerRouter.vlanId(), selectedGw, packetService);
}
@@ -604,7 +606,8 @@
preCommitPortService.unsubscribePreCommit(osFip.getPortId(),
OPENSTACK_PORT_PRE_REMOVE, instancePortService,
this.getClass().getName());
- log.info("Unsubscribed the port {} on listening pre-remove event", osFip.getPortId());
+ log.info("Unsubscribed the port {} on listening pre-remove event",
+ osFip.getPortId());
}
log.info("Removed floating IP {}", osFip.getFloatingIpAddress());
});
@@ -746,17 +749,19 @@
switch (event.type()) {
case OPENSTACK_INSTANCE_PORT_DETECTED:
- if (instPort != null && instPort.portId() != null) {
- osRouterAdminService.floatingIps().stream()
- .filter(f -> f.getPortId() != null)
- .filter(f -> f.getPortId().equals(instPort.portId()))
- .forEach(f -> setFloatingIpRules(f, instPort, null, true));
- }
+ eventExecutor.execute(() -> {
+ if (instPort != null && instPort.portId() != null) {
+ osRouterAdminService.floatingIps().stream()
+ .filter(f -> f.getPortId() != null)
+ .filter(f -> f.getPortId().equals(instPort.portId()))
+ .forEach(f -> setFloatingIpRules(f,
+ instPort, null, true));
+ }
+ });
break;
case OPENSTACK_INSTANCE_MIGRATION_STARTED:
-
fip = associatedFloatingIp(event.subject(), ips);
if (fip == null) {
@@ -765,7 +770,8 @@
osPort = osNetworkService.port(fip.getPortId());
osNet = osNetworkService.network(osPort.getNetworkId());
- externalPeerRouter = externalPeerRouterForNetwork(osNet, osNetworkService, osRouterAdminService);
+ externalPeerRouter = externalPeerRouterForNetwork(osNet,
+ osNetworkService, osRouterAdminService);
if (externalPeerRouter == null) {
final String errorFormat = ERR_FLOW + "no external peer router found";
@@ -798,7 +804,8 @@
osPort = osNetworkService.port(fip.getPortId());
osNet = osNetworkService.network(osPort.getNetworkId());
- externalPeerRouter = externalPeerRouterForNetwork(osNet, osNetworkService, osRouterAdminService);
+ externalPeerRouter = externalPeerRouterForNetwork(osNet,
+ osNetworkService, osRouterAdminService);
if (externalPeerRouter == null) {
final String errorFormat = ERR_FLOW + "no external peer router found";
@@ -859,29 +866,31 @@
public void event(OpenstackNetworkEvent event) {
switch (event.type()) {
case OPENSTACK_PORT_PRE_REMOVE:
- InstancePort instPort =
- instancePortService.instancePort(event.port().getId());
-
- if (instPort == null) {
- break;
- }
-
- NetFloatingIP fip =
- associatedFloatingIp(instPort, osRouterAdminService.floatingIps());
-
- if (fip != null) {
- instancePortService.updateInstancePort(
- instPort.updateState(REMOVE_PENDING));
- eventExecutor.execute(() -> updateFipStore(event.port().getId()));
- } else {
- instancePortService.removeInstancePort(instPort.portId());
- }
+ eventExecutor.execute(() -> processPortPreRemove(event));
break;
default:
break;
}
}
+ private void processPortPreRemove(OpenstackNetworkEvent event) {
+ InstancePort instPort = instancePortService.instancePort(
+ event.port().getId());
+ if (instPort == null) {
+ return;
+ }
+ NetFloatingIP fip = associatedFloatingIp(instPort,
+ osRouterAdminService.floatingIps());
+
+ if (fip != null) {
+ instancePortService.updateInstancePort(
+ instPort.updateState(REMOVE_PENDING));
+ updateFipStore(event.port().getId());
+ } else {
+ instancePortService.removeInstancePort(instPort.portId());
+ }
+ }
+
private void updateFipStore(String portId) {
if (portId == null) {
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
index 70d75cc..af81c2f 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
@@ -101,6 +101,7 @@
import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.buildExtension;
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
+import static org.openstack4j.model.network.NetworkType.FLAT;
/**
* Handles OpenStack router events.
@@ -280,7 +281,7 @@
}
setInternalRoutes(osRouter, osSubnet, true);
- setGatewayIcmp(osSubnet, true);
+ setGatewayIcmp(osSubnet, osRouter, true);
ExternalGateway exGateway = osRouter.getExternalGatewayInfo();
if (exGateway != null && exGateway.isEnableSnat()) {
setSourceNat(osRouterIface, true);
@@ -304,7 +305,7 @@
}
setInternalRoutes(osRouter, osSubnet, false);
- setGatewayIcmp(osSubnet, false);
+ setGatewayIcmp(osSubnet, osRouter, false);
ExternalGateway exGateway = osRouter.getExternalGatewayInfo();
if (exGateway != null && exGateway.isEnableSnat()) {
setSourceNat(osRouterIface, false);
@@ -336,7 +337,7 @@
Subnet osSubnet = osNetworkAdminService.subnet(routerIface.getSubnetId());
Network osNet = osNetworkAdminService.network(osSubnet.getNetworkId());
- if (osNet.getNetworkType() == NetworkType.FLAT) {
+ if (osNet.getNetworkType() == FLAT) {
return;
}
@@ -423,7 +424,7 @@
}
}
- private void setGatewayIcmp(Subnet osSubnet, boolean install) {
+ private void setGatewayIcmp(Subnet osSubnet, Router osRouter, boolean install) {
OpenstackNode sourceNatGateway = osNodeService.completeNodes(GATEWAY).stream().findFirst().orElse(null);
if (sourceNatGateway == null) {
@@ -437,26 +438,30 @@
// take ICMP request to a subnet gateway through gateway node group
Network network = osNetworkAdminService.network(osSubnet.getNetworkId());
+ Set<Subnet> routableSubnets = routableSubnets(osRouter, osSubnet.getId());
+
switch (network.getNetworkType()) {
case VXLAN:
osNodeService.completeNodes(COMPUTE).stream()
.filter(cNode -> cNode.dataIp() != null)
- .forEach(cNode -> setRulesToGatewayWithDstIp(
+ .forEach(cNode -> setRulesToGatewayWithRoutableSubnets(
cNode,
sourceNatGateway,
network.getProviderSegID(),
- IpAddress.valueOf(osSubnet.getGateway()),
+ osSubnet,
+ routableSubnets,
NetworkMode.VXLAN,
install));
break;
case VLAN:
osNodeService.completeNodes(COMPUTE).stream()
.filter(cNode -> cNode.vlanPortNum() != null)
- .forEach(cNode -> setRulesToGatewayWithDstIp(
+ .forEach(cNode -> setRulesToGatewayWithRoutableSubnets(
cNode,
sourceNatGateway,
network.getProviderSegID(),
- IpAddress.valueOf(osSubnet.getGateway()),
+ osSubnet,
+ routableSubnets,
NetworkMode.VLAN,
install));
break;
@@ -663,7 +668,6 @@
private void setRulesToGateway(OpenstackNode osNode, String segmentId, IpPrefix srcSubnet,
NetworkType networkType, boolean install) {
- TrafficTreatment treatment;
OpenstackNode sourceNatGateway = osNodeService.completeNodes(GATEWAY).stream().findFirst().orElse(null);
if (sourceNatGateway == null) {
@@ -747,6 +751,26 @@
install);
}
+ private void setRulesToGatewayWithRoutableSubnets(OpenstackNode osNode, OpenstackNode sourceNatGateway,
+ String segmentId, Subnet updatedSubnet,
+ Set<Subnet> routableSubnets, NetworkMode networkMode,
+ boolean install) {
+ //At first we install flow rules to gateway with segId and gatewayIp of updated subnet
+ setRulesToGatewayWithDstIp(osNode, sourceNatGateway, segmentId, IpAddress.valueOf(updatedSubnet.getGateway()),
+ networkMode, install);
+
+ routableSubnets.forEach(subnet -> {
+ setRulesToGatewayWithDstIp(osNode, sourceNatGateway,
+ segmentId, IpAddress.valueOf(subnet.getGateway()),
+ networkMode, install);
+
+ Network network = osNetworkAdminService.network(subnet.getNetworkId());
+ setRulesToGatewayWithDstIp(osNode, sourceNatGateway,
+ network.getProviderSegID(), IpAddress.valueOf(updatedSubnet.getGateway()),
+ networkMode, install);
+ });
+ }
+
private void setRulesToGatewayWithDstIp(OpenstackNode osNode, OpenstackNode sourceNatGateway,
String segmentId, IpAddress dstIp,
NetworkMode networkMode, boolean install) {
@@ -758,6 +782,7 @@
switch (networkMode) {
case VXLAN:
+ sBuilder.matchTunnelId(Long.parseLong(segmentId));
tBuilder.extension(buildExtension(
deviceService,
osNode.intgBridge(),
@@ -767,6 +792,7 @@
break;
case VLAN:
+ sBuilder.matchVlanId(VlanId.vlanId(segmentId));
tBuilder.setOutput(osNode.vlanPortNum());
break;
@@ -975,10 +1001,12 @@
event.routerIface()));
break;
case OPENSTACK_ROUTER_GATEWAY_ADDED:
- log.debug("Router external gateway {} added", event.externalGateway().getNetworkId());
+ log.debug("Router external gateway {} added",
+ event.externalGateway().getNetworkId());
break;
case OPENSTACK_ROUTER_GATEWAY_REMOVED:
- log.debug("Router external gateway {} removed", event.externalGateway().getNetworkId());
+ log.debug("Router external gateway {} removed",
+ event.externalGateway().getNetworkId());
break;
case OPENSTACK_FLOATING_IP_CREATED:
case OPENSTACK_FLOATING_IP_UPDATED:
@@ -1083,7 +1111,7 @@
}
private void instPortDetected(InstancePort instPort) {
- if (osNetworkAdminService.network(instPort.networkId()).getNetworkType() == NetworkType.FLAT) {
+ if (osNetworkAdminService.network(instPort.networkId()).getNetworkType() == FLAT) {
return;
}
@@ -1099,7 +1127,7 @@
}
private void instPortRemoved(InstancePort instPort) {
- if (osNetworkAdminService.network(instPort.networkId()).getNetworkType() == NetworkType.FLAT) {
+ if (osNetworkAdminService.network(instPort.networkId()).getNetworkType() == FLAT) {
return;
}
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java
index dc734a9..6558410 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java
@@ -770,20 +770,22 @@
case OPENSTACK_INSTANCE_PORT_UPDATED:
case OPENSTACK_INSTANCE_PORT_DETECTED:
case OPENSTACK_INSTANCE_MIGRATION_STARTED:
- installSecurityGroupRules(event, instPort);
+ eventExecutor.execute(() ->
+ installSecurityGroupRules(event, instPort));
break;
case OPENSTACK_INSTANCE_PORT_VANISHED:
- Port osPort = removedOsPortStore.asJavaMap().get(instPort.portId());
- eventExecutor.execute(() ->
- setSecurityGroupRules(instPort, osPort, false)
- );
- removedOsPortStore.remove(instPort.portId());
+ eventExecutor.execute(() -> {
+ Port osPort = removedOsPortStore.asJavaMap().get(instPort.portId());
+ setSecurityGroupRules(instPort, osPort, false);
+ removedOsPortStore.remove(instPort.portId());
+ });
break;
case OPENSTACK_INSTANCE_MIGRATION_ENDED:
- InstancePort revisedInstPort = swapStaleLocation(instPort);
- Port port = osNetService.port(instPort.portId());
- eventExecutor.execute(() ->
- setSecurityGroupRules(revisedInstPort, port, false));
+ eventExecutor.execute(() -> {
+ InstancePort revisedInstPort = swapStaleLocation(instPort);
+ Port port = osNetService.port(instPort.portId());
+ setSecurityGroupRules(revisedInstPort, port, false);
+ });
break;
default:
break;
@@ -825,7 +827,8 @@
switch (event.type()) {
case OPENSTACK_PORT_PRE_REMOVE:
- removedOsPortStore.put(osPort.getId(), osPort);
+ eventExecutor.execute(() ->
+ removedOsPortStore.put(osPort.getId(), osPort));
break;
default:
// do nothing for the other events
@@ -948,7 +951,8 @@
public void event(OpenstackNodeEvent event) {
switch (event.type()) {
case OPENSTACK_NODE_COMPLETE:
- resetSecurityGroupRules();
+ eventExecutor.execute(OpenstackSecurityGroupHandler.this::
+ resetSecurityGroupRules);
break;
case OPENSTACK_NODE_CREATED:
case OPENSTACK_NODE_REMOVED:
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingArpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingArpHandler.java
index d88c05d..a4696d5 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingArpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingArpHandler.java
@@ -70,8 +70,11 @@
import java.util.Dictionary;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.ExecutorService;
import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.concurrent.Executors.newSingleThreadExecutor;
+import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.openstacknetworking.api.Constants.ARP_BROADCAST_MODE;
import static org.onosproject.openstacknetworking.api.Constants.ARP_PROXY_MODE;
import static org.onosproject.openstacknetworking.api.Constants.ARP_TABLE;
@@ -150,6 +153,9 @@
private final InstancePortListener instancePortListener = new InternalInstancePortListener();
private final OpenstackNodeListener osNodeListener = new InternalNodeEventListener();
+ private final ExecutorService eventExecutor = newSingleThreadExecutor(
+ groupedThreads(this.getClass().getSimpleName(), "event-handler", log));
+
private ApplicationId appId;
private NodeId localNodeId;
@@ -177,6 +183,7 @@
instancePortService.removeListener(instancePortListener);
leadershipService.withdraw(appId.name());
configService.unregisterProperties(getClass(), false);
+ eventExecutor.shutdown();
log.info("Stopped");
}
@@ -545,7 +552,8 @@
if (ethPacket == null || ethPacket.getEtherType() != Ethernet.TYPE_ARP) {
return;
}
- processPacketIn(context, ethPacket);
+
+ eventExecutor.execute(() -> processPacketIn(context, ethPacket));
}
}
@@ -588,10 +596,14 @@
switch (event.type()) {
case OPENSTACK_SUBNET_CREATED:
case OPENSTACK_SUBNET_UPDATED:
- setFakeGatewayArpRule(event.subnet(), true, null);
+ eventExecutor.execute(() -> {
+ setFakeGatewayArpRule(event.subnet(), true, null);
+ });
break;
case OPENSTACK_SUBNET_REMOVED:
- setFakeGatewayArpRule(event.subnet(), false, null);
+ eventExecutor.execute(() -> {
+ setFakeGatewayArpRule(event.subnet(), false, null);
+ });
break;
case OPENSTACK_NETWORK_CREATED:
case OPENSTACK_NETWORK_UPDATED:
@@ -626,12 +638,16 @@
OpenstackNode osNode = event.subject();
switch (event.type()) {
case OPENSTACK_NODE_COMPLETE:
- setDefaultArpRule(osNode, true);
- setAllArpRules(osNode, true);
+ eventExecutor.execute(() -> {
+ setDefaultArpRule(osNode, true);
+ setAllArpRules(osNode, true);
+ });
break;
case OPENSTACK_NODE_INCOMPLETE:
- setDefaultArpRule(osNode, false);
- setAllArpRules(osNode, false);
+ eventExecutor.execute(() -> {
+ setDefaultArpRule(osNode, false);
+ setAllArpRules(osNode, false);
+ });
break;
default:
break;
@@ -747,20 +763,28 @@
switch (event.type()) {
case OPENSTACK_INSTANCE_PORT_DETECTED:
case OPENSTACK_INSTANCE_PORT_UPDATED:
- setArpRequestRule(event.subject(), true);
- setArpReplyRule(event.subject(), true);
+ eventExecutor.execute(() -> {
+ setArpRequestRule(event.subject(), true);
+ setArpReplyRule(event.subject(), true);
+ });
break;
case OPENSTACK_INSTANCE_PORT_VANISHED:
- setArpRequestRule(event.subject(), false);
- setArpReplyRule(event.subject(), false);
+ eventExecutor.execute(() -> {
+ setArpRequestRule(event.subject(), false);
+ setArpReplyRule(event.subject(), false);
+ });
break;
case OPENSTACK_INSTANCE_MIGRATION_STARTED:
- setArpRequestRule(event.subject(), true);
- setArpReplyRule(event.subject(), true);
+ eventExecutor.execute(() -> {
+ setArpRequestRule(event.subject(), true);
+ setArpReplyRule(event.subject(), true);
+ });
break;
case OPENSTACK_INSTANCE_MIGRATION_ENDED:
- InstancePort revisedInstPort = swapStaleLocation(event.subject());
- setArpRequestRule(revisedInstPort, false);
+ eventExecutor.execute(() -> {
+ InstancePort revisedInstPort = swapStaleLocation(event.subject());
+ setArpRequestRule(revisedInstPort, false);
+ });
break;
default:
break;
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingDhcpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingDhcpHandler.java
index 71fa4d1..113feb9 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingDhcpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingDhcpHandler.java
@@ -71,8 +71,10 @@
import java.util.Dictionary;
import java.util.List;
import java.util.Objects;
+import java.util.concurrent.ExecutorService;
import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.concurrent.Executors.newSingleThreadExecutor;
import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_BroadcastAddress;
import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_Classless_Static_Route;
import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_DHCPServerIp;
@@ -84,6 +86,7 @@
import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_SubnetMask;
import static org.onlab.packet.DHCP.MsgType.DHCPACK;
import static org.onlab.packet.DHCP.MsgType.DHCPOFFER;
+import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.openstacknetworking.api.Constants.DHCP_TABLE;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_DHCP_RULE;
import static org.onosproject.openstacknetworking.impl.OsgiPropertyConstants.DHCP_SERVER_MAC;
@@ -153,6 +156,9 @@
private final PacketProcessor packetProcessor = new InternalPacketProcessor();
private final OpenstackNodeListener osNodeListener = new InternalNodeEventListener();
+ private final ExecutorService eventExecutor = newSingleThreadExecutor(
+ groupedThreads(this.getClass().getSimpleName(), "event-handler"));
+
private ApplicationId appId;
private NodeId localNodeId;
@@ -174,6 +180,7 @@
osNodeService.removeListener(osNodeListener);
configService.unregisterProperties(getClass(), false);
leadershipService.withdraw(appId.name());
+ eventExecutor.shutdown();
log.info("Stopped");
}
@@ -215,7 +222,8 @@
}
DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
- processDhcp(context, dhcpPacket);
+
+ eventExecutor.execute(() -> processDhcp(context, dhcpPacket));
}
private void processDhcp(PacketContext context, DHCP dhcpPacket) {
@@ -550,10 +558,10 @@
OpenstackNode osNode = event.subject();
switch (event.type()) {
case OPENSTACK_NODE_COMPLETE:
- setDhcpRule(osNode, true);
+ eventExecutor.execute(() -> setDhcpRule(osNode, true));
break;
case OPENSTACK_NODE_INCOMPLETE:
- setDhcpRule(osNode, false);
+ eventExecutor.execute(() -> setDhcpRule(osNode, false));
break;
case OPENSTACK_NODE_CREATED:
case OPENSTACK_NODE_UPDATED:
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
index f6977a3..47fad9d 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
@@ -47,7 +47,6 @@
import org.onosproject.openstacknetworking.api.OpenstackNetworkEvent;
import org.onosproject.openstacknetworking.api.OpenstackNetworkListener;
import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
-import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupService;
import org.onosproject.openstacknode.api.OpenstackNode;
import org.onosproject.openstacknode.api.OpenstackNodeService;
import org.openstack4j.model.network.Network;
@@ -130,9 +129,6 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY)
protected OpenstackNodeService osNodeService;
- @Reference(cardinality = ReferenceCardinality.MANDATORY)
- protected OpenstackSecurityGroupService securityGroupService;
-
private final ExecutorService eventExecutor = newSingleThreadExecutor(
groupedThreads(this.getClass().getSimpleName(), "event-handler"));
private final InstancePortListener instancePortListener = new InternalInstancePortListener();
@@ -798,7 +794,7 @@
boolean isNwAdminStateUp = event.subject().isAdminStateUp();
boolean isPortAdminStateUp = event.port().isAdminStateUp();
- InstancePort instPort = instancePortService.instancePort(event.port().getId());
+ String portId = event.port().getId();
switch (event.type()) {
case OPENSTACK_NETWORK_CREATED:
@@ -813,20 +809,20 @@
break;
case OPENSTACK_PORT_CREATED:
case OPENSTACK_PORT_UPDATED:
-
- if (instPort != null) {
- eventExecutor.execute(() ->
- setPortBlockRules(instPort, !isPortAdminStateUp));
- }
-
+ eventExecutor.execute(() -> {
+ InstancePort instPort = instancePortService.instancePort(portId);
+ if (instPort != null) {
+ setPortBlockRules(instPort, !isPortAdminStateUp);
+ }
+ });
break;
case OPENSTACK_PORT_REMOVED:
-
- if (instPort != null) {
- eventExecutor.execute(() ->
- setPortBlockRules(instPort, false));
- }
-
+ eventExecutor.execute(() -> {
+ InstancePort instPort = instancePortService.instancePort(portId);
+ if (instPort != null) {
+ setPortBlockRules(instPort, false);
+ }
+ });
break;
default:
break;
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java
index 92005cf..8b190d0 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java
@@ -304,11 +304,11 @@
@Override
public boolean isRelevant(DeviceEvent event) {
- Device device = event.subject();
- if (!mastershipService.isLocalMaster(device.id())) {
+ if (!mastershipService.isLocalMaster(event.subject().id())) {
// do not allow to proceed without mastership
return false;
}
+
Port port = event.port();
if (port == null) {
return false;
@@ -388,8 +388,10 @@
private void processCompleteNode(OpenstackNode osNode) {
deviceService.getPorts(osNode.intgBridge()).stream()
- .filter(port -> vnicType(port.annotations().value(PORT_NAME)).equals(Constants.VnicType.NORMAL) ||
- vnicType(port.annotations().value(PORT_NAME)).equals(Constants.VnicType.DIRECT))
+ .filter(port -> vnicType(port.annotations().value(PORT_NAME))
+ .equals(Constants.VnicType.NORMAL) ||
+ vnicType(port.annotations().value(PORT_NAME))
+ .equals(Constants.VnicType.DIRECT))
.filter(Port::isEnabled)
.forEach(port -> {
log.debug("Instance port {} is detected from {}",
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
index db15e15..25a7e41 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
@@ -884,11 +884,11 @@
* @param gatewayNode gateway node
* @param packetService packet service
*/
- public static void processGratuitousArpPacketForFloatingIp(NetFloatingIP floatingIP,
- InstancePort instancePort,
- VlanId vlanId,
- OpenstackNode gatewayNode,
- PacketService packetService) {
+ public static void processGarpPacketForFloatingIp(NetFloatingIP floatingIP,
+ InstancePort instancePort,
+ VlanId vlanId,
+ OpenstackNode gatewayNode,
+ PacketService packetService) {
Ethernet ethernet = buildGratuitousArpPacket(floatingIP, instancePort, vlanId);
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
diff --git a/cli/src/main/java/org/onosproject/cli/net/ResourcesCommand.java b/cli/src/main/java/org/onosproject/cli/net/ResourcesCommand.java
index d4c1a40..cddf7e1 100644
--- a/cli/src/main/java/org/onosproject/cli/net/ResourcesCommand.java
+++ b/cli/src/main/java/org/onosproject/cli/net/ResourcesCommand.java
@@ -177,10 +177,18 @@
List<Resource> nonAggregatable = new ArrayList<>();
for (Resource r : children) {
- if (!isPrintTarget(r)) {
+ if (!isPrintTarget(r)) { // A
continue;
}
+ if (r instanceof DiscreteResource) {
+
+ if (resourceService.getRegisteredResources(((DiscreteResource) r).id()).isEmpty()) {
+ // resource which has children should be printed
+ continue;
+ }
+ }
+
if (r instanceof ContinuousResource) {
// non-aggregatable terminal node
nonAggregatable.add(r);
@@ -193,6 +201,7 @@
}
}
+
// print aggregated (terminal)
aggregatables.asMap().entrySet()
.forEach(e -> {
@@ -241,12 +250,7 @@
String resourceName = resource.simpleTypeName();
if (resource instanceof DiscreteResource) {
- // TODO This distributed store access incurs overhead.
- // This should be merged with the one in printResource()
- if (!resourceService.getRegisteredResources(((DiscreteResource) resource).id()).isEmpty()) {
- // resource which has children should be printed
- return true;
- }
+
if (availablesOnly && !resourceService.isAvailable(resource)) {
// don't print unavailable discrete resource
return false;
@@ -255,7 +259,6 @@
log.warn("Unexpected resource class: {}", resource.getClass().getSimpleName());
return false;
}
-
return typesToPrint.contains(resourceName);
}
}
diff --git a/core/api/src/main/java/org/onosproject/net/AnnotationKeys.java b/core/api/src/main/java/org/onosproject/net/AnnotationKeys.java
index 5af7f7a..ce3c094 100644
--- a/core/api/src/main/java/org/onosproject/net/AnnotationKeys.java
+++ b/core/api/src/main/java/org/onosproject/net/AnnotationKeys.java
@@ -216,6 +216,11 @@
public static final String SSHKEY = "sshkey";
/**
+ * Annotation key for the protocol layer.
+ */
+ public static final String LAYER = "layer";
+
+ /**
* Returns the value annotated object for the specified annotation key.
* The annotated value is expected to be String that can be parsed as double.
* If parsing fails, the returned value will be {@value #DEFAULT_VALUE}.
diff --git a/core/api/src/main/java/org/onosproject/net/intent/PointToPointIntent.java b/core/api/src/main/java/org/onosproject/net/intent/PointToPointIntent.java
index 1a38bfd..d0a9d54 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/PointToPointIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/PointToPointIntent.java
@@ -19,6 +19,7 @@
import com.google.common.base.MoreObjects;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.FilteredConnectPoint;
+import org.onosproject.net.Link;
import org.onosproject.net.ResourceGroup;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
@@ -38,6 +39,8 @@
private final FilteredConnectPoint ingressPoint;
private final FilteredConnectPoint egressPoint;
+ private final List<Link> suggestedPath;
+
/**
* Returns a new point to point intent builder. The application id,
* ingress point and egress point are required fields. If they are
@@ -57,6 +60,8 @@
FilteredConnectPoint ingressPoint;
FilteredConnectPoint egressPoint;
+ List<Link> suggestedPath;
+
private Builder() {
// Hide constructor
}
@@ -121,12 +126,36 @@
}
/**
+ * Sets the suggested path as list of links.
+ *
+ * @param links list of suggested links
+ * @return this builder
+ */
+ public Builder suggestedPath(List<Link> links) {
+ this.suggestedPath = links;
+ return this;
+ }
+
+ /**
* Builds a point to point intent from the accumulated parameters.
*
* @return point to point intent
*/
public PointToPointIntent build() {
-
+ if (suggestedPath != null &&
+ suggestedPath.size() > 0 &&
+ (!suggestedPath.get(0)
+ .src()
+ .deviceId()
+ .equals(ingressPoint.connectPoint().deviceId()) ||
+ !suggestedPath.get(suggestedPath.size() - 1)
+ .dst()
+ .deviceId()
+ .equals(egressPoint.connectPoint().deviceId()))
+ ) {
+ throw new IllegalArgumentException(
+ "Suggested path not compatible with ingress and egress connect points");
+ }
return new PointToPointIntent(
appId,
key,
@@ -136,6 +165,7 @@
egressPoint,
constraints,
priority,
+ suggestedPath,
resourceGroup
);
}
@@ -147,16 +177,17 @@
* Creates a new point-to-point intent with the supplied ingress/egress
* ports and constraints.
*
- * @param appId application identifier
- * @param key key of the intent
- * @param selector traffic selector
- * @param treatment treatment
- * @param ingressPoint filtered ingress port
- * @param egressPoint filtered egress port
- * @param constraints optional list of constraints
- * @param priority priority to use for flows generated by this intent
+ * @param appId application identifier
+ * @param key key of the intent
+ * @param selector traffic selector
+ * @param treatment treatment
+ * @param ingressPoint filtered ingress port
+ * @param egressPoint filtered egress port
+ * @param constraints optional list of constraints
+ * @param priority priority to use for flows generated by this intent
+ * @param suggestedPath suggested path
* @throws NullPointerException if {@code ingressPoint} or
- * {@code egressPoints} or {@code appId} is null.
+ * {@code egressPoints} or {@code appId} is null or {@code path} is null.
*/
private PointToPointIntent(ApplicationId appId,
Key key,
@@ -166,15 +197,24 @@
FilteredConnectPoint egressPoint,
List<Constraint> constraints,
int priority,
+ List<Link> suggestedPath,
ResourceGroup resourceGroup) {
- super(appId, key, Collections.emptyList(), selector, treatment, constraints,
- priority, resourceGroup);
+ super(appId,
+ key,
+ suggestedPath != null ? resources(suggestedPath) : Collections.emptyList(),
+ selector,
+ treatment,
+ constraints,
+ priority,
+ resourceGroup);
checkArgument(!ingressPoint.equals(egressPoint),
"ingress and egress should be different (ingress: %s, egress: %s)", ingressPoint, egressPoint);
this.ingressPoint = checkNotNull(ingressPoint);
this.egressPoint = checkNotNull(egressPoint);
+ this.suggestedPath = suggestedPath;
+
}
/**
@@ -184,6 +224,7 @@
super();
this.ingressPoint = null;
this.egressPoint = null;
+ this.suggestedPath = null;
}
/**
@@ -205,6 +246,16 @@
return egressPoint;
}
+
+ /**
+ * Return the suggested path (as a list of links) that the compiler should use.
+ *
+ * @return suggested path
+ */
+ public List<Link> suggestedPath() {
+ return suggestedPath;
+ }
+
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
@@ -218,6 +269,7 @@
.add("ingress", filteredIngressPoint())
.add("egress", filteredEgressPoint())
.add("constraints", constraints())
+ .add("links", suggestedPath())
.add("resourceGroup", resourceGroup())
.toString();
}
diff --git a/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java b/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java
index 48b4a87..2b8c6d7 100644
--- a/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java
+++ b/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java
@@ -20,6 +20,8 @@
import org.onlab.graph.ScalarWeight;
import org.onlab.graph.Weight;
import org.onosproject.core.GroupId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultLink;
import org.onosproject.net.DefaultPath;
import org.onosproject.net.DeviceId;
import org.onosproject.net.ElementId;
@@ -41,6 +43,7 @@
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.flow.instructions.Instructions.MetadataInstruction;
+import org.onosproject.net.link.LinkServiceAdapter;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.net.topology.DefaultTopologyEdge;
import org.onosproject.net.topology.DefaultTopologyVertex;
@@ -58,7 +61,10 @@
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import static org.onosproject.net.Link.Type.DIRECT;
import static org.onosproject.net.NetTestTools.*;
/**
@@ -189,6 +195,71 @@
}
/**
+ * Mock path service for creating paths within the test with multiple possible paths.
+ */
+ public static class MockMultiplePathService extends PathServiceAdapter {
+
+ final String[][] pathsHops;
+
+ /**
+ * Constructor that provides a set of hops to mock.
+ *
+ * @param pathHops multiple path hops to mock
+ */
+ public MockMultiplePathService(String[][] pathHops) {
+ this.pathsHops = pathHops;
+ }
+
+ @Override
+ public Set<Path> getPaths(ElementId src, ElementId dst) {
+
+ //Extracts all the paths that goes from src to dst
+ Set<Path> allPaths = new HashSet<>();
+ allPaths.addAll(IntStream.range(0, pathsHops.length)
+ .filter(i -> src.toString().endsWith(pathsHops[i][0])
+ && dst.toString().endsWith(pathsHops[i][pathsHops[i].length - 1]))
+ .mapToObj(i -> createPath(src instanceof HostId,
+ dst instanceof HostId,
+ pathsHops[i]))
+ .collect(Collectors.toSet()));
+
+ // Maintain only the shortest paths
+ int minPathLength = allPaths.stream()
+ .mapToInt(o -> o.links().size())
+ .min()
+ .orElse(Integer.MAX_VALUE);
+ Set<Path> shortestPaths = allPaths.stream()
+ .filter(path -> path.links().size() <= minPathLength)
+ .collect(Collectors.toSet());
+
+ return shortestPaths;
+ }
+
+
+ @Override
+ public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeigher weigher) {
+ Set<Path> paths = getPaths(src, dst);
+
+ for (Path path : paths) {
+ DeviceId srcDevice = path.src().elementId() instanceof DeviceId ? path.src().deviceId() : null;
+ DeviceId dstDevice = path.dst().elementId() instanceof DeviceId ? path.dst().deviceId() : null;
+ if (srcDevice != null && dstDevice != null) {
+ TopologyVertex srcVertex = new DefaultTopologyVertex(srcDevice);
+ TopologyVertex dstVertex = new DefaultTopologyVertex(dstDevice);
+ Link link = link(src.toString(), 1, dst.toString(), 1);
+
+ Weight weightValue = weigher.weight(new DefaultTopologyEdge(srcVertex, dstVertex, link));
+ if (weightValue.isNegative()) {
+ return new HashSet<>();
+ }
+ }
+ }
+ return paths;
+ }
+ }
+
+
+ /**
* Mock path service for creating paths within the test.
*
*/
@@ -249,6 +320,22 @@
}
/**
+ * Mock active and direct link.
+ */
+ public static class FakeLink extends DefaultLink {
+
+ /**
+ * Constructor that provides source and destination of the fake link.
+ *
+ * @param src Source connect point of the fake link
+ * @param dst Destination connect point of the fake link
+ */
+ public FakeLink(ConnectPoint src, ConnectPoint dst) {
+ super(null, src, dst, DIRECT, Link.State.ACTIVE);
+ }
+ }
+
+ /**
* Mock path service for creating paths for MP2SP intent tests, returning
* pre-determined paths.
*/
@@ -319,6 +406,38 @@
}
}
+ /**
+ * Mock link service for getting links to check path availability
+ * when a suggested path is submitted.
+ */
+ public static class MockLinkService extends LinkServiceAdapter {
+ final String[][] linksHops;
+
+ /**
+ * Constructor that provides a set of links (as a list of hops).
+ *
+ * @param linksHops links to to mock (link as a set of hops)
+ */
+ public MockLinkService(String[][] linksHops) {
+ this.linksHops = linksHops;
+ }
+
+ @Override
+ public Set<Link> getLinks() {
+ return Arrays.asList(linksHops).stream()
+ .map(path -> createPath(path).links())
+ .flatMap(List::stream)
+ .collect(Collectors.toSet());
+ }
+ @Override
+ public Set<Link> getLinks(ConnectPoint connectPoint) {
+ return getLinks().stream()
+ .filter(link -> link.src().deviceId().equals(connectPoint.deviceId())
+ || link.dst().deviceId().equals(connectPoint.deviceId()))
+ .collect(Collectors.toSet());
+ }
+ }
+
private static final IntentTestsMocks.MockSelector SELECTOR =
new IntentTestsMocks.MockSelector();
private static final IntentTestsMocks.MockTreatment TREATMENT =
diff --git a/core/api/src/test/java/org/onosproject/net/intent/PointToPointIntentTest.java b/core/api/src/test/java/org/onosproject/net/intent/PointToPointIntentTest.java
index 3b170a0..c0257c0 100644
--- a/core/api/src/test/java/org/onosproject/net/intent/PointToPointIntentTest.java
+++ b/core/api/src/test/java/org/onosproject/net/intent/PointToPointIntentTest.java
@@ -17,8 +17,15 @@
import org.junit.Test;
import org.onosproject.net.FilteredConnectPoint;
+import org.onosproject.net.Link;
+import java.util.LinkedList;
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutableBaseClass;
/**
@@ -59,6 +66,34 @@
assertEquals("incorrect egress", FP2, intent.filteredEgressPoint());
}
+ @Test
+ public void suggestedPath() {
+ List<Link> suggestedPath = new LinkedList<>();
+ suggestedPath.add(new IntentTestsMocks.FakeLink(FP1.connectPoint(), FP2.connectPoint()));
+
+ PointToPointIntent intent = createWithSuggestedPath(suggestedPath);
+ assertEquals("incorrect id", APPID, intent.appId());
+ assertEquals("incorrect match", MATCH, intent.selector());
+ assertEquals("incorrect ingress", FP1, intent.filteredIngressPoint());
+ assertEquals("incorrect egress", FP2, intent.filteredEgressPoint());
+ assertEquals("incorrect suggested path", suggestedPath, intent.suggestedPath());
+
+ }
+
+ @Test
+ public void failSuggestedPath() {
+ List<Link> suggestedPath = new LinkedList<>();
+ try {
+ suggestedPath.add(new IntentTestsMocks.FakeLink(FP3.connectPoint(), FP2.connectPoint()));
+
+ createWithSuggestedPath(suggestedPath);
+ fail("Point to Point intent building with incompatible suggested path "
+ + "not throw exception.");
+ } catch (IllegalArgumentException exception) {
+ assertThat(exception.getMessage(), containsString("Suggested path not compatible"));
+ }
+ }
+
@Override
protected PointToPointIntent createOne() {
return PointToPointIntent.builder()
@@ -101,4 +136,15 @@
.filteredEgressPoint(FP2)
.build();
}
+
+ protected PointToPointIntent createWithSuggestedPath(List<Link> suggestedPath) {
+ return PointToPointIntent.builder()
+ .appId(APPID)
+ .selector(MATCH)
+ .treatment(NOP)
+ .filteredIngressPoint(FP1)
+ .filteredEgressPoint(FP2)
+ .suggestedPath(suggestedPath)
+ .build();
+ }
}
diff --git a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/InOrderFlowObjectiveManager.java b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/InOrderFlowObjectiveManager.java
index a90f84c..16b0e69 100644
--- a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/InOrderFlowObjectiveManager.java
+++ b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/InOrderFlowObjectiveManager.java
@@ -318,13 +318,17 @@
if (obj instanceof FilteringObjective) {
FilteringObjQueueKey k = new FilteringObjQueueKey(deviceId, priority, ((FilteringObjective) obj).key());
- filtObjQueueHead.invalidate(k);
+ if (!ObjectiveError.INSTALLATIONTIMEOUT.equals(error)) {
+ filtObjQueueHead.invalidate(k);
+ }
filtObjQueue.remove(k, obj);
remaining = filtObjQueue.get(k);
} else if (obj instanceof ForwardingObjective) {
ForwardingObjQueueKey k =
new ForwardingObjQueueKey(deviceId, priority, ((ForwardingObjective) obj).selector());
- fwdObjQueueHead.invalidate(k);
+ if (!ObjectiveError.INSTALLATIONTIMEOUT.equals(error)) {
+ fwdObjQueueHead.invalidate(k);
+ }
fwdObjQueue.remove(k, obj);
remaining = fwdObjQueue.get(k);
} else if (obj instanceof NextObjective) {
@@ -345,7 +349,9 @@
}
}
NextObjQueueKey k = new NextObjQueueKey(deviceId, obj.id());
- nextObjQueueHead.invalidate(k);
+ if (!ObjectiveError.INSTALLATIONTIMEOUT.equals(error)) {
+ nextObjQueueHead.invalidate(k);
+ }
nextObjQueue.remove(k, obj);
remaining = nextObjQueue.get(k);
} else {
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/ConnectivityIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/ConnectivityIntentCompiler.java
index 666128c..a35af7b 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/ConnectivityIntentCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/ConnectivityIntentCompiler.java
@@ -161,6 +161,28 @@
}
/**
+ * Computes all the paths between two ConnectPoints.
+ *
+ * @param intent intent on which behalf path is being computed
+ * @param one start of the path
+ * @param two end of the path
+ * @return Paths between the two, or null if no path can be found
+ */
+ protected List<Path> getPaths(ConnectivityIntent intent,
+ ElementId one, ElementId two) {
+ Set<Path> paths = pathService.getPaths(one, two, weigher(intent.constraints()));
+ final List<Constraint> constraints = intent.constraints();
+ ImmutableList<Path> filtered = FluentIterable.from(paths)
+ .filter(path -> checkPath(path, constraints))
+ .toList();
+ if (filtered.isEmpty()) {
+ return null;
+ }
+
+ return filtered;
+ }
+
+ /**
* Computes a disjoint path between two ConnectPoints.
*
* @param intent intent on which behalf path is being computed
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PointToPointIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PointToPointIntentCompiler.java
index ad65e46..0079fe5 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PointToPointIntentCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PointToPointIntentCompiler.java
@@ -16,6 +16,7 @@
package org.onosproject.net.intent.impl.compiler;
import com.google.common.collect.ImmutableSet;
+import org.apache.commons.lang3.tuple.Pair;
import org.onlab.graph.ScalarWeight;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultPath;
@@ -74,6 +75,7 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;
+import java.util.stream.IntStream;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
@@ -124,6 +126,18 @@
ConnectPoint ingressPoint = intent.filteredIngressPoint().connectPoint();
ConnectPoint egressPoint = intent.filteredEgressPoint().connectPoint();
+ //TODO: handle protected path case with suggested path!!
+ //Idea: use suggested path as primary and another path from path service as protection
+ if (intent.suggestedPath() != null && intent.suggestedPath().size() > 0) {
+ Path path = new DefaultPath(PID, intent.suggestedPath(), new ScalarWeight(1));
+ //Check intent constraints against suggested path and suggested path availability
+ if (checkPath(path, intent.constraints()) && pathAvailable(intent)) {
+ allocateIntentBandwidth(intent, path);
+ return asList(createLinkCollectionIntent(ImmutableSet.copyOf(intent.suggestedPath()),
+ DEFAULT_COST, intent));
+ }
+ }
+
if (ingressPoint.deviceId().equals(egressPoint.deviceId())) {
return createZeroHopLinkCollectionIntent(intent);
}
@@ -143,6 +157,21 @@
}
}
+ private void allocateIntentBandwidth(PointToPointIntent intent, Path path) {
+ ConnectPoint ingressCP = intent.filteredIngressPoint().connectPoint();
+ ConnectPoint egressCP = intent.filteredEgressPoint().connectPoint();
+
+ List<ConnectPoint> pathCPs =
+ path.links().stream()
+ .flatMap(l -> Stream.of(l.src(), l.dst()))
+ .collect(Collectors.toList());
+
+ pathCPs.add(ingressCP);
+ pathCPs.add(egressCP);
+
+ allocateBandwidth(intent, pathCPs);
+ }
+
private List<Intent> createZeroHopIntent(ConnectPoint ingressPoint,
ConnectPoint egressPoint,
PointToPointIntent intent) {
@@ -161,18 +190,7 @@
intent.filteredEgressPoint().connectPoint().deviceId());
// Allocate bandwidth if a bandwidth constraint is set
- ConnectPoint ingressCP = intent.filteredIngressPoint().connectPoint();
- ConnectPoint egressCP = intent.filteredEgressPoint().connectPoint();
-
- List<ConnectPoint> pathCPs =
- path.links().stream()
- .flatMap(l -> Stream.of(l.src(), l.dst()))
- .collect(Collectors.toList());
-
- pathCPs.add(ingressCP);
- pathCPs.add(egressCP);
-
- allocateBandwidth(intent, pathCPs);
+ allocateIntentBandwidth(intent, path);
return asList(createLinkCollectionIntent(ImmutableSet.copyOf(path.links()),
path.cost(),
@@ -291,19 +309,7 @@
return reusableIntents;
} else {
// Allocate bandwidth if a bandwidth constraint is set
- ConnectPoint ingressCP = intent.filteredIngressPoint().connectPoint();
- ConnectPoint egressCP = intent.filteredEgressPoint().connectPoint();
-
- List<ConnectPoint> pathCPs =
- onlyPath.links().stream()
- .flatMap(l -> Stream.of(l.src(), l.dst()))
- .collect(Collectors.toList());
-
- pathCPs.add(ingressCP);
- pathCPs.add(egressCP);
-
- // Allocate bandwidth if a bandwidth constraint is set
- allocateBandwidth(intent, pathCPs);
+ allocateIntentBandwidth(intent, onlyPath);
links.add(createEdgeLink(ingressPoint, true));
links.addAll(onlyPath.links());
@@ -694,4 +700,47 @@
groupService.addBucketsToGroup(src.deviceId(), groupKey, addBuckets, groupKey, intent.appId());
}
+
+ /**
+ * Checks suggested path availability.
+ * It checks:
+ * - single links availability;
+ * - that first and last device of the path are coherent with ingress and egress devices;
+ * - links contiguity.
+ *
+ * @param intent Intent with suggested path to check
+ * @return true if the suggested path is available
+ */
+ private boolean pathAvailable(PointToPointIntent intent) {
+ // Check links availability
+ List<Link> suggestedPath = intent.suggestedPath();
+ for (Link link : suggestedPath) {
+ if (!(link instanceof EdgeLink) && !linkService.getLinks(link.src()).contains(link)) {
+ return false;
+ }
+ }
+
+ //Check that first and last device of the path are intent ingress and egress devices
+ if (!suggestedPath.get(0).src()
+ .deviceId().equals(intent.filteredIngressPoint().connectPoint().deviceId())) {
+ return false;
+ }
+ if (!suggestedPath.get(suggestedPath.size() - 1).dst()
+ .deviceId().equals(intent.filteredEgressPoint().connectPoint().deviceId())) {
+ return false;
+ }
+
+ // Check contiguity
+ List<Pair<Link, Link>> linkPairs = IntStream.
+ range(0, suggestedPath.size() - 1)
+ .mapToObj(i -> Pair.of(suggestedPath.get(i), suggestedPath.get(i + 1)))
+ .collect(Collectors.toList());
+
+ for (Pair<Link, Link> linkPair : linkPairs) {
+ if (!linkPair.getKey().dst().deviceId().equals(linkPair.getValue().src().deviceId())) {
+ return false;
+ }
+ }
+ return true;
+ }
}
diff --git a/core/net/src/main/java/org/onosproject/net/packet/impl/PacketManager.java b/core/net/src/main/java/org/onosproject/net/packet/impl/PacketManager.java
index ff63efe..78dd986 100644
--- a/core/net/src/main/java/org/onosproject/net/packet/impl/PacketManager.java
+++ b/core/net/src/main/java/org/onosproject/net/packet/impl/PacketManager.java
@@ -345,6 +345,7 @@
}
private DefaultForwardingObjective.Builder createBuilder(PacketRequest request) {
+ ApplicationId requestedAppId = coreService.getAppId(request.appId().name()); // Validate app id
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
.punt()
.wipeDeferred()
@@ -353,7 +354,7 @@
return DefaultForwardingObjective.builder()
.withPriority(request.priority().priorityValue())
.withSelector(request.selector())
- .fromApp(appId)
+ .fromApp(requestedAppId == null ? appId : requestedAppId)
.withFlag(ForwardingObjective.Flag.VERSATILE)
.withTreatment(treatment)
.makePermanent();
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/PointToPointIntentCompilerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/PointToPointIntentCompilerTest.java
index a811ad6..31c15ee 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/PointToPointIntentCompilerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/PointToPointIntentCompilerTest.java
@@ -25,6 +25,7 @@
import org.onosproject.net.DeviceId;
import org.onosproject.net.FilteredConnectPoint;
import org.onosproject.net.Link;
+import org.onosproject.net.NetTestTools;
import org.onosproject.net.PortNumber;
import org.onosproject.net.ResourceGroup;
import org.onosproject.net.flow.TrafficSelector;
@@ -200,6 +201,54 @@
}
/**
+ * Creates a PointToPoint intent based on ingress and egress deviceIds
+ * and a suggested path.
+ * @param ingress the ingress connect point
+ * @param egress the egress connect point
+ * @param suggestedPath the suggested path
+ * @return the PointToPointIntent connecting the two connect points with
+ * the suggested path (if available)
+ */
+ private PointToPointIntent makeIntentSuggestedPath(ConnectPoint ingress,
+ ConnectPoint egress,
+ List<Link> suggestedPath) {
+ return PointToPointIntent.builder()
+ .appId(APPID)
+ .selector(selector)
+ .treatment(treatment)
+ .filteredIngressPoint(new FilteredConnectPoint(ingress))
+ .filteredEgressPoint(new FilteredConnectPoint(egress))
+ .suggestedPath(suggestedPath)
+ .build();
+ }
+
+ /**
+ * Creates a PointToPoint intent based on ingress and egress deviceIds and
+ * constraints with a suggested path.
+ *
+ * @param ingress the ingress connect point
+ * @param egress the egress connect point
+ * @param suggestedPath the suggested path
+ * @param constraints constraints
+ * @return the PointToPointIntent connecting the two connect points with
+ * constraints and a suggested path
+ */
+ private PointToPointIntent makeIntentSuggestedPath(ConnectPoint ingress,
+ ConnectPoint egress,
+ List<Link> suggestedPath,
+ List<Constraint> constraints) {
+ return PointToPointIntent.builder()
+ .appId(APPID)
+ .selector(selector)
+ .treatment(treatment)
+ .filteredIngressPoint(new FilteredConnectPoint(ingress))
+ .filteredEgressPoint(new FilteredConnectPoint(egress))
+ .constraints(constraints)
+ .suggestedPath(suggestedPath)
+ .build();
+ }
+
+ /**
* Creates a compiler for HostToHost intents.
*
* @param hops string array describing the path hops to use when compiling
@@ -210,6 +259,41 @@
}
/**
+ * Creates a compiler for PointToPoint intents with suggested paths.
+ *
+ * @param paths all the possible paths in the network
+ * @return PointToPoint intent compiler
+ */
+ private PointToPointIntentCompiler makeCompilerSuggestedPath(String[][] paths) {
+ final PointToPointIntentCompiler compiler = new PointToPointIntentCompiler();
+ compiler.pathService = new IntentTestsMocks.MockMultiplePathService(paths);
+ compiler.linkService = new IntentTestsMocks.MockLinkService(paths);
+ return compiler;
+ }
+
+ /**
+ * Creates a point to point intent compiler for suggested path case.
+ *
+ * @param paths all the possible paths in the network
+ * @param resourceService service to use for resource allocation requests
+ * @return point to point compiler
+ */
+ private PointToPointIntentCompiler makeCompilerSuggestedPath(String[][] paths,
+ ResourceService resourceService) {
+ final PointToPointIntentCompiler compiler = new PointToPointIntentCompiler();
+ compiler.pathService = new IntentTestsMocks.MockMultiplePathService(paths);
+ compiler.linkService = new IntentTestsMocks.MockLinkService(paths);
+
+ if (resourceService == null) {
+ compiler.resourceService = new MockResourceService();
+ } else {
+ compiler.resourceService = resourceService;
+ }
+
+ return compiler;
+ }
+
+ /**
* Creates a point to point intent compiler for a three switch linear
* topology.
*
@@ -582,4 +666,151 @@
assertThat(resourceAllocations, hasSize(6));
assertEquals(expectedresourceAllocations, resourceAllocations);
}
+
+ /**
+ * Test if a suggested path is correctly applied.
+ */
+ @Test
+ public void testSuggestedPath() {
+ String[] suggestedPathHops = {S1, S3, S4, S5, S6, S8};
+ List<Link> suggestedPath = NetTestTools.createPath(suggestedPathHops).links();
+
+ PointToPointIntent intent = makeIntentSuggestedPath(new ConnectPoint(DID_1, PORT_1),
+ new ConnectPoint(DID_8, PORT_2),
+ suggestedPath);
+
+ String[][] paths = {{S1, S2, S8}, suggestedPathHops};
+ PointToPointIntentCompiler compiler = makeCompilerSuggestedPath(paths);
+
+ List<Intent> result = compiler.compile(intent, null);
+ assertThat(result, is(Matchers.notNullValue()));
+ assertThat(result, hasSize(1));
+ Intent resultIntent = result.get(0);
+ assertThat(resultIntent instanceof LinkCollectionIntent, is(true));
+
+ if (resultIntent instanceof LinkCollectionIntent) {
+ LinkCollectionIntent resultLinkIntent = (LinkCollectionIntent) resultIntent;
+ FilteredConnectPoint ingressPoint = new FilteredConnectPoint(new ConnectPoint(DID_1, PORT_1));
+ FilteredConnectPoint egressPoint = new FilteredConnectPoint(new ConnectPoint(DID_8, PORT_2));
+ // 5 links for the hops, plus one default link on ingress and egress
+ assertThat(resultLinkIntent.links(), hasSize(suggestedPathHops.length - 1));
+ assertThat(resultLinkIntent.links(), linksHasPath(S1, S3));
+ assertThat(resultLinkIntent.links(), linksHasPath(S3, S4));
+ assertThat(resultLinkIntent.links(), linksHasPath(S4, S5));
+ assertThat(resultLinkIntent.links(), linksHasPath(S5, S6));
+ assertThat(resultLinkIntent.links(), linksHasPath(S6, S8));
+ assertThat(resultLinkIntent.filteredIngressPoints(), is(ImmutableSet.of(ingressPoint)));
+ assertThat(resultLinkIntent.filteredEgressPoints(), is(ImmutableSet.of(egressPoint)));
+ }
+ assertThat("key is inherited", resultIntent.key(), is(intent.key()));
+ }
+
+ /**
+ * Test that if a suggested path isn't available it applies another available path.
+ */
+ @Test
+ public void testSuggestedPathNotAvailable() {
+ String[] suggestedPathHops = {S1, S3, S8};
+ String[] shortestPath = {S1, S2, S8};
+ List<Link> suggestedPath = NetTestTools.createPath(suggestedPathHops).links();
+
+ PointToPointIntent intent = makeIntentSuggestedPath(new ConnectPoint(DID_1, PORT_1),
+ new ConnectPoint(DID_8, PORT_2),
+ suggestedPath);
+
+ String[][] path = {shortestPath};
+ PointToPointIntentCompiler compiler = makeCompilerSuggestedPath(path);
+
+ List<Intent> result = compiler.compile(intent, null);
+ assertThat(result, is(Matchers.notNullValue()));
+ assertThat(result, hasSize(1));
+ Intent resultIntent = result.get(0);
+ assertThat(resultIntent instanceof LinkCollectionIntent, is(true));
+
+ if (resultIntent instanceof LinkCollectionIntent) {
+ LinkCollectionIntent resultLinkIntent = (LinkCollectionIntent) resultIntent;
+ FilteredConnectPoint ingressPoint = new FilteredConnectPoint(new ConnectPoint(DID_1, PORT_1));
+ FilteredConnectPoint egressPoint = new FilteredConnectPoint(new ConnectPoint(DID_8, PORT_2));
+ // 5 links for the hops, plus one default link on ingress and egress
+ assertThat(resultLinkIntent.links(), hasSize(shortestPath.length - 1));
+ assertThat(resultLinkIntent.links(), linksHasPath(S1, S2));
+ assertThat(resultLinkIntent.links(), linksHasPath(S2, S8));
+ assertThat(resultLinkIntent.filteredIngressPoints(), is(ImmutableSet.of(ingressPoint)));
+ assertThat(resultLinkIntent.filteredEgressPoints(), is(ImmutableSet.of(egressPoint)));
+ }
+ assertThat("key is inherited", resultIntent.key(), is(intent.key()));
+ }
+
+ /**
+ * Tests that requests with suggested path
+ * and with sufficient available bandwidth succeed.
+ */
+ @Test
+ public void testSuggestedPathBandwidthConstrainedIntentSuccess() {
+ final double bpsTotal = 1000.0;
+ final double bpsToReserve = 100.0;
+
+ final ResourceService resourceService =
+ MockResourceService.makeCustomBandwidthResourceService(bpsTotal);
+ final List<Constraint> constraints =
+ Collections.singletonList(new BandwidthConstraint(Bandwidth.bps(bpsToReserve)));
+
+ String[] suggestedPathHops = {S1, S4, S5, S3};
+ List<Link> suggestedPath = NetTestTools.createPath(suggestedPathHops).links();
+
+ final PointToPointIntent intent = makeIntentSuggestedPath(
+ new ConnectPoint(DID_1, PORT_1),
+ new ConnectPoint(DID_3, PORT_2),
+ suggestedPath,
+ constraints);
+
+ String[][] hops = {{S1, S2, S3}, suggestedPathHops};
+ final PointToPointIntentCompiler compiler = makeCompilerSuggestedPath(hops,
+ resourceService);
+
+ final List<Intent> compiledIntents = compiler.compile(intent, null);
+
+ assertThat(compiledIntents, Matchers.notNullValue());
+ assertThat(compiledIntents, hasSize(1));
+
+ assertThat("key is inherited",
+ compiledIntents.stream().map(Intent::key).collect(Collectors.toList()),
+ everyItem(is(intent.key())));
+
+ }
+
+ /**
+ * Tests that requests with insufficient available bandwidth fail.
+ */
+ @Test
+ public void testSuggestedPathBandwidthConstrainedIntentFailure() {
+ final double bpsTotal = 10.0;
+
+ final ResourceService resourceService =
+ MockResourceService.makeCustomBandwidthResourceService(bpsTotal);
+ final List<Constraint> constraints =
+ Collections.singletonList(new BandwidthConstraint(Bandwidth.bps(BPS_TO_RESERVE)));
+
+ String[] suggestedPathHops = {S1, S4, S5, S3};
+ List<Link> suggestedPath = NetTestTools.createPath(suggestedPathHops).links();
+
+ try {
+ final PointToPointIntent intent = makeIntentSuggestedPath(
+ new ConnectPoint(DID_1, PORT_1),
+ new ConnectPoint(DID_3, PORT_2),
+ suggestedPath,
+ constraints);
+
+ String[][] paths = {{S1, S2, S3}, suggestedPathHops};
+ final PointToPointIntentCompiler compiler = makeCompilerSuggestedPath(paths,
+ resourceService);
+
+ compiler.compile(intent, null);
+
+ fail("Point to Point compilation with insufficient bandwidth does "
+ + "not throw exception.");
+ } catch (PathNotFoundException noPath) {
+ assertThat(noPath.getMessage(), containsString("No path"));
+ }
+ }
}
diff --git a/drivers/arista/src/main/java/org/onosproject/drivers/arista/LinkDiscoveryAristaImpl.java b/drivers/arista/src/main/java/org/onosproject/drivers/arista/LinkDiscoveryAristaImpl.java
index 49ed615..a32c6b7 100644
--- a/drivers/arista/src/main/java/org/onosproject/drivers/arista/LinkDiscoveryAristaImpl.java
+++ b/drivers/arista/src/main/java/org/onosproject/drivers/arista/LinkDiscoveryAristaImpl.java
@@ -261,7 +261,7 @@
ConnectPoint local = new ConnectPoint(localDevId, localPort.number());
ConnectPoint remote = new ConnectPoint(remoteDevId, remotePort.number());
DefaultAnnotations annotations = DefaultAnnotations.builder()
- .set("layer", "ETHERNET")
+ .set(AnnotationKeys.LAYER, "ETHERNET")
.build();
linkDescriptions.add(new DefaultLinkDescription(
diff --git a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/FlowRuleJuniperImpl.java b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/FlowRuleJuniperImpl.java
index cb07843..3f4adb6 100644
--- a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/FlowRuleJuniperImpl.java
+++ b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/FlowRuleJuniperImpl.java
@@ -381,7 +381,7 @@
DeviceService deviceService = this.handler().get(DeviceService.class);
//Using only links with adjacency discovered by the LLDP protocol (see LinkDiscoveryJuniperImpl)
Map<DeviceId, Port> dstPorts = links.stream().filter(l ->
- IP_STRING.toUpperCase().equals(l.annotations().value("layer")))
+ IP_STRING.toUpperCase().equals(l.annotations().value(AnnotationKeys.LAYER)))
.collect(Collectors.toMap(
l -> l.dst().deviceId(),
l -> deviceService.getPort(l.dst().deviceId(), l.dst().port())));
diff --git a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/JuniperUtils.java b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/JuniperUtils.java
index fca4697..d6a6f65 100644
--- a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/JuniperUtils.java
+++ b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/JuniperUtils.java
@@ -502,12 +502,37 @@
ConnectPoint local = new ConnectPoint(localDevId, localPort.number());
ConnectPoint remote = new ConnectPoint(remoteDevId, remotePort.number());
DefaultAnnotations annotations = DefaultAnnotations.builder()
- .set("layer", "IP")
+ .set(AnnotationKeys.LAYER, "ETHERNET")
.build();
descs.add(new DefaultLinkDescription(
- local, remote, Link.Type.INDIRECT, false, annotations));
+ local, remote, Link.Type.DIRECT, true, annotations));
descs.add(new DefaultLinkDescription(
- remote, local, Link.Type.INDIRECT, false, annotations));
+ remote, local, Link.Type.DIRECT, true, annotations));
+ }
+
+ /**
+ * Create one way LinkDescriptions.
+ *
+ * @param localDevId the identity of the local device
+ * @param localPort the port of the local device
+ * @param remoteDevId the identity of the remote device
+ * @param remotePort the port of the remote device
+ * @param descs the collection to which the link descriptions
+ * should be added
+ */
+ public static void createOneWayLinkDescription(DeviceId localDevId,
+ Port localPort,
+ DeviceId remoteDevId,
+ Port remotePort,
+ Set<LinkDescription> descs) {
+
+ ConnectPoint local = new ConnectPoint(localDevId, localPort.number());
+ ConnectPoint remote = new ConnectPoint(remoteDevId, remotePort.number());
+ DefaultAnnotations annotations = DefaultAnnotations.builder()
+ .set(AnnotationKeys.LAYER, "ETHERNET")
+ .build();
+ descs.add(new DefaultLinkDescription(
+ remote, local, Link.Type.DIRECT, true, annotations));
}
/**
diff --git a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/LinkDiscoveryJuniperImpl.java b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/LinkDiscoveryJuniperImpl.java
index 37e655a..e78779e 100644
--- a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/LinkDiscoveryJuniperImpl.java
+++ b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/LinkDiscoveryJuniperImpl.java
@@ -136,12 +136,11 @@
continue;
}
- JuniperUtils.createBiDirLinkDescription(localDeviceId,
- localPort.get(),
- remoteDevice.id(),
- remotePort.get(),
- descriptions);
-
+ JuniperUtils.createOneWayLinkDescription(localDeviceId,
+ localPort.get(),
+ remoteDevice.id(),
+ remotePort.get(),
+ descriptions);
}
return descriptions;
}
diff --git a/incubator/protobuf/models/BUILD b/incubator/protobuf/models/BUILD
new file mode 100644
index 0000000..a46e781
--- /dev/null
+++ b/incubator/protobuf/models/BUILD
@@ -0,0 +1,7 @@
+COMPILE_DEPS = CORE_DEPS + [
+ "//incubator/protobuf/models/proto:onos-incubator-protobuf-models-proto",
+]
+
+osgi_jar_with_tests(
+ deps = COMPILE_DEPS,
+)
diff --git a/incubator/protobuf/models/proto/BUILD b/incubator/protobuf/models/proto/BUILD
new file mode 100644
index 0000000..e0d5c37
--- /dev/null
+++ b/incubator/protobuf/models/proto/BUILD
@@ -0,0 +1,495 @@
+load("//tools/build/bazel:osgi_java_library.bzl", "osgi_proto_jar")
+
+PROTO_SOURCE_ROOT = "incubator/protobuf/models/proto"
+
+osgi_proto_jar(
+ proto_libs = [
+ ":ApplicationsEnums_proto",
+ ":ConfigPropertyEnums_proto",
+ ":ConfigProperty_proto",
+ ":NodeId_proto",
+ ":RoleInfo_proto",
+ ":ApplicationId_proto",
+ ":ApplicationProto_proto",
+ ":Version_proto",
+ ":DeviceDescription_proto",
+ ":DeviceEnums_proto",
+ ":DeviceEvent_proto",
+ ":PortDescription_proto",
+ ":PortEnums_proto",
+ ":PortStatistics_proto",
+ ":Criterion_proto",
+ ":Instruction_proto",
+ ":Instructions_proto",
+ ":FlowEntryEnums_proto",
+ ":FlowEntry_proto",
+ ":FlowRuleEnums_proto",
+ ":FlowRule_proto",
+ ":TraficSelector_proto",
+ ":TrafficTreatment_proto",
+ ":HostDescription_proto",
+ ":HostEnums_proto",
+ ":HostEvent_proto",
+ ":LinkDescription_proto",
+ ":LinkEnums_proto",
+ ":LinkEvent_proto",
+ ":BandEnums_proto",
+ ":Band_proto",
+ ":MeterEnums_proto",
+ ":MeterEvent_proto",
+ ":Meter_proto",
+ ":MeterRequest_proto",
+ ":OutboundPacket_proto",
+ ":PacketEnums_proto",
+ ":PacketEvent_proto",
+ ":PacketProcessorEntry_proto",
+ ":PacketProcessor_proto",
+ ":PacketRequest_proto",
+ ":RegionEnums_proto",
+ ":ConnectPoint_proto",
+ ":Device_proto",
+ ":DisjointPath_proto",
+ ":HostId_proto",
+ ":HostLocation_proto",
+ ":Host_proto",
+ ":Link_proto",
+ ":MastershipRole_proto",
+ ":Path_proto",
+ ":Port_proto",
+ ":ProviderId_proto",
+ ":Region_proto",
+ ":Permission_proto",
+ ],
+)
+
+### app ###
+proto_library(
+ name = "ApplicationsEnums_proto",
+ srcs = ["app/ApplicationEnumsProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+### cfg ###
+proto_library(
+ name = "ConfigPropertyEnums_proto",
+ srcs = ["cfg/ConfigPropertyEnumsProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+proto_library(
+ name = "ConfigProperty_proto",
+ srcs = ["cfg/ConfigPropertyProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [":ConfigPropertyEnums_proto"],
+)
+
+### cluster ###
+proto_library(
+ name = "NodeId_proto",
+ srcs = ["cluster/NodeIdProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+proto_library(
+ name = "RoleInfo_proto",
+ srcs = ["cluster/RoleInfoProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [":NodeId_proto"],
+)
+
+### core ###
+
+proto_library(
+ name = "ApplicationId_proto",
+ srcs = ["core/ApplicationIdProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+proto_library(
+ name = "ApplicationProto_proto",
+ srcs = ["core/ApplicationProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [
+ ":ApplicationId_proto",
+ ":ApplicationsEnums_proto",
+ ":Permission_proto",
+ ":Version_proto",
+ ],
+)
+
+proto_library(
+ name = "Version_proto",
+ srcs = ["core/VersionProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+### net ###
+
+### device ###
+proto_library(
+ name = "DeviceDescription_proto",
+ srcs = ["net/device/DeviceDescriptionProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [":DeviceEnums_proto"],
+)
+
+proto_library(
+ name = "DeviceEnums_proto",
+ srcs = ["net/device/DeviceEnumsProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+proto_library(
+ name = "DeviceEvent_proto",
+ srcs = ["net/device/DeviceEventProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [
+ ":DeviceEnums_proto",
+ ":Device_proto",
+ ":Port_proto",
+ ],
+)
+
+proto_library(
+ name = "PortDescription_proto",
+ srcs = ["net/device/PortDescriptionProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [":PortEnums_proto"],
+)
+
+proto_library(
+ name = "PortEnums_proto",
+ srcs = ["net/device/PortEnumsProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+proto_library(
+ name = "PortStatistics_proto",
+ srcs = ["net/device/PortStatisticsProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+### flow ###
+## criteria ##
+proto_library(
+ name = "Criterion_proto",
+ srcs = ["net/flow/criteria/CriterionProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+## instrcutions ##
+proto_library(
+ name = "Instruction_proto",
+ srcs = ["net/flow/instructions/InstructionProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+proto_library(
+ name = "Instructions_proto",
+ srcs = ["net/flow/instructions/InstructionsProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+proto_library(
+ name = "FlowEntryEnums_proto",
+ srcs = ["net/flow/FlowEntryEnumsProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+proto_library(
+ name = "FlowEntry_proto",
+ srcs = ["net/flow/FlowEntryProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = ["FlowEntryEnums_proto"],
+)
+
+proto_library(
+ name = "FlowRuleEnums_proto",
+ srcs = ["net/flow/FlowRuleEnumsProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+proto_library(
+ name = "FlowRule_proto",
+ srcs = ["net/flow/FlowRuleProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [
+ ":FlowRuleEnums_proto",
+ ":TrafficTreatment_proto",
+ ":TraficSelector_proto",
+ ],
+)
+
+proto_library(
+ name = "TraficSelector_proto",
+ srcs = ["net/flow/TrafficSelectorProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [":Criterion_proto"],
+)
+
+proto_library(
+ name = "TrafficTreatment_proto",
+ srcs = ["net/flow/TrafficTreatmentProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [
+ "Instruction_proto",
+ ":Instructions_proto",
+ ],
+)
+
+#### host ####
+
+proto_library(
+ name = "HostDescription_proto",
+ srcs = ["net/host/HostDescriptionProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [":HostLocation_proto"],
+)
+
+proto_library(
+ name = "HostEnums_proto",
+ srcs = ["net/host/HostEnumsProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+proto_library(
+ name = "HostEvent_proto",
+ srcs = ["net/host/HostEventProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [
+ ":HostEnums_proto",
+ ":Host_proto",
+ ],
+)
+
+#### link ####
+
+proto_library(
+ name = "LinkDescription_proto",
+ srcs = ["net/link/LinkDescriptionProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [
+ ":ConnectPoint_proto",
+ ":LinkEnums_proto",
+ ],
+)
+
+proto_library(
+ name = "LinkEnums_proto",
+ srcs = ["net/link/LinkEnumsProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+proto_library(
+ name = "LinkEvent_proto",
+ srcs = ["net/link/LinkEventProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [
+ ":LinkEnums_proto",
+ ":Link_proto",
+ ],
+)
+
+### meter ####
+
+proto_library(
+ name = "BandEnums_proto",
+ srcs = ["net/meter/BandEnumsProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+proto_library(
+ name = "Band_proto",
+ srcs = ["net/meter/BandProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [":BandEnums_proto"],
+)
+
+proto_library(
+ name = "MeterEnums_proto",
+ srcs = ["net/meter/MeterEnumsProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+proto_library(
+ name = "MeterEvent_proto",
+ srcs = ["net/meter/MeterEventProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [
+ ":MeterEnums_proto",
+ ":Meter_proto",
+ ],
+)
+
+proto_library(
+ name = "Meter_proto",
+ srcs = ["net/meter/MeterProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [
+ "MeterEnums_proto",
+ ":ApplicationId_proto",
+ ":Band_proto",
+ ],
+)
+
+proto_library(
+ name = "MeterRequest_proto",
+ srcs = ["net/meter/MeterRequestProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [
+ ":ApplicationId_proto",
+ ":Band_proto",
+ ":MeterEnums_proto",
+ ],
+)
+
+### packet ####
+
+proto_library(
+ name = "OutboundPacket_proto",
+ srcs = ["net/packet/OutboundPacketProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [":TrafficTreatment_proto"],
+)
+
+proto_library(
+ name = "PacketEnums_proto",
+ srcs = ["net/packet/PacketEnumsProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+proto_library(
+ name = "PacketEvent_proto",
+ srcs = ["net/packet/PacketEventProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [
+ ":OutboundPacket_proto",
+ ":PacketEnums_proto",
+ ],
+)
+
+proto_library(
+ name = "PacketProcessorEntry_proto",
+ srcs = ["net/packet/PacketProcessorEntryProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [":PacketProcessor_proto"],
+)
+
+proto_library(
+ name = "PacketProcessor_proto",
+ srcs = ["net/packet/PacketProcessorProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+proto_library(
+ name = "PacketRequest_proto",
+ srcs = ["net/packet/PacketRequestProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [
+ ":ApplicationId_proto",
+ ":NodeId_proto",
+ ":TraficSelector_proto",
+ ],
+)
+
+#### region ####
+
+proto_library(
+ name = "RegionEnums_proto",
+ srcs = ["net/region/RegionEnumsProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+proto_library(
+ name = "ConnectPoint_proto",
+ srcs = ["net/ConnectPointProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+proto_library(
+ name = "Device_proto",
+ srcs = ["net/DeviceProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [":DeviceEnums_proto"],
+)
+
+proto_library(
+ name = "DisjointPath_proto",
+ srcs = ["net/DisjointPathProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [":Path_proto"],
+)
+
+proto_library(
+ name = "HostId_proto",
+ srcs = ["net/HostIdProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+proto_library(
+ name = "HostLocation_proto",
+ srcs = ["net/HostLocationProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [":ConnectPoint_proto"],
+)
+
+proto_library(
+ name = "Host_proto",
+ srcs = ["net/HostProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [
+ ":HostId_proto",
+ ":HostLocation_proto",
+ ":ProviderId_proto",
+ ],
+)
+
+proto_library(
+ name = "Link_proto",
+ srcs = ["net/LinkProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [
+ ":ConnectPoint_proto",
+ ":LinkEnums_proto",
+ ":ProviderId_proto",
+ ],
+)
+
+proto_library(
+ name = "MastershipRole_proto",
+ srcs = ["net/MastershipRoleProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+proto_library(
+ name = "Path_proto",
+ srcs = ["net/PathProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [":Link_proto"],
+)
+
+proto_library(
+ name = "Port_proto",
+ srcs = ["net/PortProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [":PortEnums_proto"],
+)
+
+proto_library(
+ name = "ProviderId_proto",
+ srcs = ["net/ProviderIdProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
+
+proto_library(
+ name = "Region_proto",
+ srcs = ["net/RegionProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+ deps = [":RegionEnums_proto"],
+)
+
+proto_library(
+ name = "Permission_proto",
+ srcs = ["security/PermissionProto.proto"],
+ proto_source_root = PROTO_SOURCE_ROOT,
+)
diff --git a/incubator/protobuf/models/src/main/proto/app/ApplicationEnumsProto.proto b/incubator/protobuf/models/proto/app/ApplicationEnumsProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/app/ApplicationEnumsProto.proto
rename to incubator/protobuf/models/proto/app/ApplicationEnumsProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/cfg/ConfigPropertyEnumsProto.proto b/incubator/protobuf/models/proto/cfg/ConfigPropertyEnumsProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/cfg/ConfigPropertyEnumsProto.proto
rename to incubator/protobuf/models/proto/cfg/ConfigPropertyEnumsProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/cfg/ConfigPropertyProto.proto b/incubator/protobuf/models/proto/cfg/ConfigPropertyProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/cfg/ConfigPropertyProto.proto
rename to incubator/protobuf/models/proto/cfg/ConfigPropertyProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/cluster/NodeIdProto.proto b/incubator/protobuf/models/proto/cluster/NodeIdProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/cluster/NodeIdProto.proto
rename to incubator/protobuf/models/proto/cluster/NodeIdProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/cluster/RoleInfoProto.proto b/incubator/protobuf/models/proto/cluster/RoleInfoProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/cluster/RoleInfoProto.proto
rename to incubator/protobuf/models/proto/cluster/RoleInfoProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/core/ApplicationIdProto.proto b/incubator/protobuf/models/proto/core/ApplicationIdProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/core/ApplicationIdProto.proto
rename to incubator/protobuf/models/proto/core/ApplicationIdProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/core/ApplicationProto.proto b/incubator/protobuf/models/proto/core/ApplicationProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/core/ApplicationProto.proto
rename to incubator/protobuf/models/proto/core/ApplicationProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/core/VersionProto.proto b/incubator/protobuf/models/proto/core/VersionProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/core/VersionProto.proto
rename to incubator/protobuf/models/proto/core/VersionProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/ConnectPointProto.proto b/incubator/protobuf/models/proto/net/ConnectPointProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/ConnectPointProto.proto
rename to incubator/protobuf/models/proto/net/ConnectPointProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/DeviceProto.proto b/incubator/protobuf/models/proto/net/DeviceProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/DeviceProto.proto
rename to incubator/protobuf/models/proto/net/DeviceProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/DisjointPathProto.proto b/incubator/protobuf/models/proto/net/DisjointPathProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/DisjointPathProto.proto
rename to incubator/protobuf/models/proto/net/DisjointPathProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/HostIdProto.proto b/incubator/protobuf/models/proto/net/HostIdProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/HostIdProto.proto
rename to incubator/protobuf/models/proto/net/HostIdProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/HostLocationProto.proto b/incubator/protobuf/models/proto/net/HostLocationProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/HostLocationProto.proto
rename to incubator/protobuf/models/proto/net/HostLocationProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/HostProto.proto b/incubator/protobuf/models/proto/net/HostProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/HostProto.proto
rename to incubator/protobuf/models/proto/net/HostProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/LinkProto.proto b/incubator/protobuf/models/proto/net/LinkProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/LinkProto.proto
rename to incubator/protobuf/models/proto/net/LinkProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/MastershipRoleProto.proto b/incubator/protobuf/models/proto/net/MastershipRoleProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/MastershipRoleProto.proto
rename to incubator/protobuf/models/proto/net/MastershipRoleProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/PathProto.proto b/incubator/protobuf/models/proto/net/PathProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/PathProto.proto
rename to incubator/protobuf/models/proto/net/PathProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/PortProto.proto b/incubator/protobuf/models/proto/net/PortProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/PortProto.proto
rename to incubator/protobuf/models/proto/net/PortProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/ProviderIdProto.proto b/incubator/protobuf/models/proto/net/ProviderIdProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/ProviderIdProto.proto
rename to incubator/protobuf/models/proto/net/ProviderIdProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/RegionProto.proto b/incubator/protobuf/models/proto/net/RegionProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/RegionProto.proto
rename to incubator/protobuf/models/proto/net/RegionProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/device/DeviceDescriptionProto.proto b/incubator/protobuf/models/proto/net/device/DeviceDescriptionProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/device/DeviceDescriptionProto.proto
rename to incubator/protobuf/models/proto/net/device/DeviceDescriptionProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/device/DeviceEnumsProto.proto b/incubator/protobuf/models/proto/net/device/DeviceEnumsProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/device/DeviceEnumsProto.proto
rename to incubator/protobuf/models/proto/net/device/DeviceEnumsProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/device/DeviceEventProto.proto b/incubator/protobuf/models/proto/net/device/DeviceEventProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/device/DeviceEventProto.proto
rename to incubator/protobuf/models/proto/net/device/DeviceEventProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/device/PortDescriptionProto.proto b/incubator/protobuf/models/proto/net/device/PortDescriptionProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/device/PortDescriptionProto.proto
rename to incubator/protobuf/models/proto/net/device/PortDescriptionProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/device/PortEnumsProto.proto b/incubator/protobuf/models/proto/net/device/PortEnumsProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/device/PortEnumsProto.proto
rename to incubator/protobuf/models/proto/net/device/PortEnumsProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/device/PortStatisticsProto.proto b/incubator/protobuf/models/proto/net/device/PortStatisticsProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/device/PortStatisticsProto.proto
rename to incubator/protobuf/models/proto/net/device/PortStatisticsProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/flow/FlowEntryEnumsProto.proto b/incubator/protobuf/models/proto/net/flow/FlowEntryEnumsProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/flow/FlowEntryEnumsProto.proto
rename to incubator/protobuf/models/proto/net/flow/FlowEntryEnumsProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/flow/FlowEntryProto.proto b/incubator/protobuf/models/proto/net/flow/FlowEntryProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/flow/FlowEntryProto.proto
rename to incubator/protobuf/models/proto/net/flow/FlowEntryProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/flow/FlowRuleEnumsProto.proto b/incubator/protobuf/models/proto/net/flow/FlowRuleEnumsProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/flow/FlowRuleEnumsProto.proto
rename to incubator/protobuf/models/proto/net/flow/FlowRuleEnumsProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/flow/FlowRuleProto.proto b/incubator/protobuf/models/proto/net/flow/FlowRuleProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/flow/FlowRuleProto.proto
rename to incubator/protobuf/models/proto/net/flow/FlowRuleProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/flow/TrafficSelectorProto.proto b/incubator/protobuf/models/proto/net/flow/TrafficSelectorProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/flow/TrafficSelectorProto.proto
rename to incubator/protobuf/models/proto/net/flow/TrafficSelectorProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/flow/TrafficTreatmentProto.proto b/incubator/protobuf/models/proto/net/flow/TrafficTreatmentProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/flow/TrafficTreatmentProto.proto
rename to incubator/protobuf/models/proto/net/flow/TrafficTreatmentProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/flow/criteria/CriterionProto.proto b/incubator/protobuf/models/proto/net/flow/criteria/CriterionProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/flow/criteria/CriterionProto.proto
rename to incubator/protobuf/models/proto/net/flow/criteria/CriterionProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/flow/instructions/InstructionProto.proto b/incubator/protobuf/models/proto/net/flow/instructions/InstructionProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/flow/instructions/InstructionProto.proto
rename to incubator/protobuf/models/proto/net/flow/instructions/InstructionProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/flow/instructions/InstructionsProto.proto b/incubator/protobuf/models/proto/net/flow/instructions/InstructionsProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/flow/instructions/InstructionsProto.proto
rename to incubator/protobuf/models/proto/net/flow/instructions/InstructionsProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/host/HostDescriptionProto.proto b/incubator/protobuf/models/proto/net/host/HostDescriptionProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/host/HostDescriptionProto.proto
rename to incubator/protobuf/models/proto/net/host/HostDescriptionProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/host/HostEnumsProto.proto b/incubator/protobuf/models/proto/net/host/HostEnumsProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/host/HostEnumsProto.proto
rename to incubator/protobuf/models/proto/net/host/HostEnumsProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/host/HostEventProto.proto b/incubator/protobuf/models/proto/net/host/HostEventProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/host/HostEventProto.proto
rename to incubator/protobuf/models/proto/net/host/HostEventProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/link/LinkDescriptionProto.proto b/incubator/protobuf/models/proto/net/link/LinkDescriptionProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/link/LinkDescriptionProto.proto
rename to incubator/protobuf/models/proto/net/link/LinkDescriptionProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/link/LinkEnumsProto.proto b/incubator/protobuf/models/proto/net/link/LinkEnumsProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/link/LinkEnumsProto.proto
rename to incubator/protobuf/models/proto/net/link/LinkEnumsProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/link/LinkEventProto.proto b/incubator/protobuf/models/proto/net/link/LinkEventProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/link/LinkEventProto.proto
rename to incubator/protobuf/models/proto/net/link/LinkEventProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/meter/BandEnumsProto.proto b/incubator/protobuf/models/proto/net/meter/BandEnumsProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/meter/BandEnumsProto.proto
rename to incubator/protobuf/models/proto/net/meter/BandEnumsProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/meter/BandProto.proto b/incubator/protobuf/models/proto/net/meter/BandProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/meter/BandProto.proto
rename to incubator/protobuf/models/proto/net/meter/BandProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/meter/MeterEnumsProto.proto b/incubator/protobuf/models/proto/net/meter/MeterEnumsProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/meter/MeterEnumsProto.proto
rename to incubator/protobuf/models/proto/net/meter/MeterEnumsProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/meter/MeterEventProto.proto b/incubator/protobuf/models/proto/net/meter/MeterEventProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/meter/MeterEventProto.proto
rename to incubator/protobuf/models/proto/net/meter/MeterEventProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/meter/MeterProto.proto b/incubator/protobuf/models/proto/net/meter/MeterProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/meter/MeterProto.proto
rename to incubator/protobuf/models/proto/net/meter/MeterProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/meter/MeterRequestProto.proto b/incubator/protobuf/models/proto/net/meter/MeterRequestProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/meter/MeterRequestProto.proto
rename to incubator/protobuf/models/proto/net/meter/MeterRequestProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/packet/OutboundPacketProto.proto b/incubator/protobuf/models/proto/net/packet/OutboundPacketProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/packet/OutboundPacketProto.proto
rename to incubator/protobuf/models/proto/net/packet/OutboundPacketProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/packet/PacketEnumsProto.proto b/incubator/protobuf/models/proto/net/packet/PacketEnumsProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/packet/PacketEnumsProto.proto
rename to incubator/protobuf/models/proto/net/packet/PacketEnumsProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/packet/PacketEventProto.proto b/incubator/protobuf/models/proto/net/packet/PacketEventProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/packet/PacketEventProto.proto
rename to incubator/protobuf/models/proto/net/packet/PacketEventProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/packet/PacketProcessorEntryProto.proto b/incubator/protobuf/models/proto/net/packet/PacketProcessorEntryProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/packet/PacketProcessorEntryProto.proto
rename to incubator/protobuf/models/proto/net/packet/PacketProcessorEntryProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/packet/PacketProcessorProto.proto b/incubator/protobuf/models/proto/net/packet/PacketProcessorProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/packet/PacketProcessorProto.proto
rename to incubator/protobuf/models/proto/net/packet/PacketProcessorProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/packet/PacketRequestProto.proto b/incubator/protobuf/models/proto/net/packet/PacketRequestProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/packet/PacketRequestProto.proto
rename to incubator/protobuf/models/proto/net/packet/PacketRequestProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/net/region/RegionEnumsProto.proto b/incubator/protobuf/models/proto/net/region/RegionEnumsProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/net/region/RegionEnumsProto.proto
rename to incubator/protobuf/models/proto/net/region/RegionEnumsProto.proto
diff --git a/incubator/protobuf/models/src/main/proto/security/PermissionProto.proto b/incubator/protobuf/models/proto/security/PermissionProto.proto
similarity index 100%
rename from incubator/protobuf/models/src/main/proto/security/PermissionProto.proto
rename to incubator/protobuf/models/proto/security/PermissionProto.proto
diff --git a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/cluster/RoleInfoProtoTranslator.java b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/cluster/RoleInfoProtoTranslator.java
index ddea094..d879a08 100644
--- a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/cluster/RoleInfoProtoTranslator.java
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/cluster/RoleInfoProtoTranslator.java
@@ -38,7 +38,7 @@
NodeId master = NodeIdProtoTranslator.translate(roleInfo.getMaster());
List<NodeId> backups = Lists.newArrayList();
- roleInfo.getBackupsList().stream().map(r ->
+ backups = roleInfo.getBackupsList().stream().map(r ->
NodeIdProtoTranslator.translate(r)).collect(Collectors.toList());
return new RoleInfo(master, backups);
}
diff --git a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/LinkProtoTranslator.java b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/LinkProtoTranslator.java
index fd139da..770d835 100644
--- a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/LinkProtoTranslator.java
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/LinkProtoTranslator.java
@@ -15,8 +15,8 @@
*/
package org.onosproject.incubator.protobuf.models.net;
-import org.onosproject.grpc.net.models.LinkProtoOuterClass;
import org.onosproject.incubator.protobuf.models.net.link.LinkEnumsProtoTranslator;
+import org.onosproject.grpc.net.models.LinkProtoOuterClass;
import org.onosproject.net.Annotations;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
diff --git a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/RegionProtoTranslator.java b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/RegionProtoTranslator.java
index 7512ebf..f426982 100644
--- a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/RegionProtoTranslator.java
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/RegionProtoTranslator.java
@@ -16,9 +16,9 @@
package org.onosproject.incubator.protobuf.models.net;
import com.google.common.base.Strings;
+import org.onosproject.incubator.protobuf.models.net.region.RegionEnumsProtoTranslator;
import org.onosproject.cluster.NodeId;
import org.onosproject.grpc.net.models.RegionProtoOuterClass;
-import org.onosproject.incubator.protobuf.models.net.region.RegionEnumsProtoTranslator;
import org.onosproject.net.Annotations;
import org.onosproject.net.region.DefaultRegion;
import org.onosproject.net.region.Region;
diff --git a/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LldpLinkProvider.java b/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LldpLinkProvider.java
index 6849119..8be22f9 100644
--- a/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LldpLinkProvider.java
+++ b/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LldpLinkProvider.java
@@ -788,6 +788,11 @@
}
@Override
+ public void setTtl(LinkKey key, short ttl) {
+ linkTimes.put(key, System.currentTimeMillis() - staleLinkAge + SECONDS.toMillis(ttl));
+ }
+
+ @Override
public DeviceService deviceService() {
return deviceService;
}
diff --git a/providers/lldpcommon/src/main/java/org/onosproject/provider/lldpcommon/LinkDiscovery.java b/providers/lldpcommon/src/main/java/org/onosproject/provider/lldpcommon/LinkDiscovery.java
index 33e5f4d..bea59ee 100644
--- a/providers/lldpcommon/src/main/java/org/onosproject/provider/lldpcommon/LinkDiscovery.java
+++ b/providers/lldpcommon/src/main/java/org/onosproject/provider/lldpcommon/LinkDiscovery.java
@@ -25,13 +25,18 @@
import org.onlab.packet.MacAddress;
import org.onlab.packet.ONOSLLDP;
import org.onlab.util.Timer;
+import org.onlab.util.Tools;
+import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultPort;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link.Type;
import org.onosproject.net.LinkKey;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
import org.onosproject.net.link.DefaultLinkDescription;
import org.onosproject.net.link.LinkDescription;
import org.onosproject.net.link.ProbedLinkProvider;
@@ -42,6 +47,10 @@
import java.nio.ByteBuffer;
import java.util.Map;
+import java.util.Optional;
+import java.util.function.Supplier;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -59,6 +68,9 @@
*/
public class LinkDiscovery implements TimerTask {
+ private static final String SCHEME_NAME = "linkdiscovery";
+ private static final String ETHERNET = "ETHERNET";
+
private final Logger log = getLogger(getClass());
private final Device device;
@@ -166,6 +178,27 @@
return false;
}
+ if (processOnosLldp(packetContext, eth)) {
+ return true;
+ }
+
+ if (processLldp(packetContext, eth)) {
+ return true;
+ }
+
+ ONOSLLDP lldp = ONOSLLDP.parseLLDP(eth);
+
+ if (lldp == null) {
+ log.debug("Cannot parse the packet. It seems that it is not the lldp or bsn packet.");
+ } else {
+ log.debug("LLDP packet is dropped due to there are no handlers that properly handle this packet: {}",
+ lldp.toString());
+ }
+
+ return false;
+ }
+
+ private boolean processOnosLldp(PacketContext packetContext, Ethernet eth) {
ONOSLLDP onoslldp = ONOSLLDP.parseONOSLLDP(eth);
if (onoslldp != null) {
Type lt;
@@ -198,6 +231,7 @@
context.providerService().linkDetected(ld);
context.touchLink(LinkKey.linkKey(src, dst));
} catch (IllegalStateException e) {
+ log.debug("There is a exception during link creation: {}", e);
return true;
}
return true;
@@ -206,6 +240,114 @@
return false;
}
+ private boolean processLldp(PacketContext packetContext, Ethernet eth) {
+ ONOSLLDP onoslldp = ONOSLLDP.parseLLDP(eth);
+ if (onoslldp != null) {
+ Type lt = eth.getEtherType() == Ethernet.TYPE_LLDP ?
+ Type.DIRECT : Type.INDIRECT;
+
+ DeviceService deviceService = context.deviceService();
+ MacAddress srcChassisId = onoslldp.getChassisIdByMac();
+ String srcPortName = onoslldp.getPortNameString();
+ String srcPortDesc = onoslldp.getPortDescString();
+
+ log.debug("srcChassisId:{}, srcPortName:{}, srcPortDesc:{}", srcChassisId, srcPortName, srcPortDesc);
+
+ if (srcChassisId == null && srcPortDesc == null) {
+ log.warn("there are no valid port id");
+ return false;
+ }
+
+ Optional<Device> srcDevice = findSourceDeviceByChassisId(deviceService, srcChassisId);
+
+ if (!srcDevice.isPresent()) {
+ log.warn("source device not found. srcChassisId value: {}", srcChassisId);
+ return false;
+ }
+ Optional<Port> sourcePort = findSourcePortByName(
+ srcPortName == null ? srcPortDesc : srcPortName,
+ deviceService,
+ srcDevice.get());
+
+ if (!sourcePort.isPresent()) {
+ log.warn("source port not found. sourcePort value: {}", sourcePort);
+ return false;
+ }
+
+ PortNumber srcPort = sourcePort.get().number();
+ PortNumber dstPort = packetContext.inPacket().receivedFrom().port();
+
+ DeviceId srcDeviceId = srcDevice.get().id();
+ DeviceId dstDeviceId = packetContext.inPacket().receivedFrom().deviceId();
+
+ ConnectPoint src = new ConnectPoint(srcDeviceId, srcPort);
+ ConnectPoint dst = new ConnectPoint(dstDeviceId, dstPort);
+
+ DefaultAnnotations annotations = DefaultAnnotations.builder()
+ .set(AnnotationKeys.PROTOCOL, SCHEME_NAME.toUpperCase())
+ .set(AnnotationKeys.LAYER, ETHERNET)
+ .build();
+
+ LinkDescription ld = new DefaultLinkDescription(src, dst, lt, true, annotations);
+ try {
+ context.providerService().linkDetected(ld);
+ context.setTtl(LinkKey.linkKey(src, dst), onoslldp.getTtlBySeconds());
+ } catch (IllegalStateException e) {
+ log.debug("There is a exception during link creation: {}", e);
+ return true;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private Optional<Device> findSourceDeviceByChassisId(DeviceService deviceService, MacAddress srcChassisId) {
+ Supplier<Stream<Device>> deviceStream = () ->
+ StreamSupport.stream(deviceService.getAvailableDevices().spliterator(), false);
+ Optional<Device> remoteDeviceOptional = deviceStream.get()
+ .filter(device -> device.chassisId() != null
+ && MacAddress.valueOf(device.chassisId().value()).equals(srcChassisId))
+ .findAny();
+
+ if (remoteDeviceOptional.isPresent()) {
+ log.debug("sourceDevice found by chassis id: {}", srcChassisId);
+ return remoteDeviceOptional;
+ } else {
+ remoteDeviceOptional = deviceStream.get().filter(device ->
+ Tools.stream(deviceService.getPorts(device.id()))
+ .anyMatch(port -> port.annotations().keys().contains(AnnotationKeys.PORT_MAC)
+ && MacAddress.valueOf(port.annotations().value(AnnotationKeys.PORT_MAC))
+ .equals(srcChassisId)))
+ .findAny();
+ if (remoteDeviceOptional.isPresent()) {
+ log.debug("sourceDevice found by port mac: {}", srcChassisId);
+ return remoteDeviceOptional;
+ } else {
+ return Optional.empty();
+ }
+ }
+ }
+
+ private Optional<Port> findSourcePortByName(String remotePortName,
+ DeviceService deviceService,
+ Device remoteDevice) {
+ Optional<Port> remotePort = deviceService.getPorts(remoteDevice.id())
+ .stream().filter(port -> remotePortName.equals(port.annotations().value(AnnotationKeys.PORT_NAME)))
+ .findAny();
+
+ if (remotePort.isPresent()) {
+ return remotePort;
+ } else {
+ int portNumber = Integer.parseInt(remotePortName.replaceAll("\\D+", ""));
+ DefaultAnnotations.Builder annotations = DefaultAnnotations.builder()
+ .set(AnnotationKeys.PORT_NAME, remotePortName);
+
+ return Optional.of(new DefaultPort(remoteDevice, PortNumber.portNumber(portNumber),
+ true,
+ annotations.build()));
+ }
+ }
+
// true if *NOT* this cluster's own probe.
private boolean notMy(String mac) {
// if we are using DEFAULT_MAC, clustering hadn't initialized, so conservative 'yes'
diff --git a/providers/lldpcommon/src/main/java/org/onosproject/provider/lldpcommon/LinkDiscoveryContext.java b/providers/lldpcommon/src/main/java/org/onosproject/provider/lldpcommon/LinkDiscoveryContext.java
index a325b95..056e3e7 100644
--- a/providers/lldpcommon/src/main/java/org/onosproject/provider/lldpcommon/LinkDiscoveryContext.java
+++ b/providers/lldpcommon/src/main/java/org/onosproject/provider/lldpcommon/LinkDiscoveryContext.java
@@ -76,6 +76,14 @@
void touchLink(LinkKey key);
/**
+ * Set the TTL to the link identified by the given key to indicate that it's active.
+ *
+ * @param key link key
+ * @param ttl ttl value(seconds)
+ */
+ void setTtl(LinkKey key, short ttl);
+
+ /**
* Returns the cluster-wide unique identifier.
*
* @return the cluster identifier
diff --git a/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/NetworkConfigLinksProvider.java b/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/NetworkConfigLinksProvider.java
index ac00cf8..8bd4c41 100644
--- a/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/NetworkConfigLinksProvider.java
+++ b/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/NetworkConfigLinksProvider.java
@@ -264,6 +264,10 @@
}
@Override
+ public void setTtl(LinkKey key, short ttl) {
+ }
+
+ @Override
public String fingerprint() {
return buildSrcMac();
}
diff --git a/tools/build/bazel/modules.bzl b/tools/build/bazel/modules.bzl
index 26a5da4..dfa5cfe 100644
--- a/tools/build/bazel/modules.bzl
+++ b/tools/build/bazel/modules.bzl
@@ -77,7 +77,8 @@
"//web/api:onos-rest",
# "//web/gui2:onos-gui2",
"//web/gui:onos-gui",
- # "//incubator/protobuf/models:onos-incubator-protobuf-models",
+ "//incubator/protobuf/models/proto:onos-incubator-protobuf-models-proto",
+ "//incubator/protobuf/models:onos-incubator-protobuf-models",
# "//incubator/protobuf/services/nb:onos-incubator-protobuf-services-nb",
]
@@ -241,7 +242,7 @@
"//apps/powermanagement:onos-apps-powermanagement-oar",
"//apps/t3:onos-apps-t3-oar",
"//apps/simplefabric:onos-apps-simplefabric-oar",
- # "//apps/kafka-integration:onos-apps-kafka-integration-oar",
+ #"//apps/kafka-integration:onos-apps-kafka-integration-oar",
"//apps/rabbitmq:onos-apps-rabbitmq-oar",
"//apps/odtn/api:onos-apps-odtn-api-oar",
"//apps/odtn/service:onos-apps-odtn-service-oar",
@@ -297,8 +298,8 @@
"//apps/vtn/sfcmgr:onos-apps-vtn-sfcmgr",
"//apps/vtn/vtnmgr:onos-apps-vtn-vtnmgr",
"//apps/vtn/vtnweb:onos-apps-vtn-vtnweb",
- "//apps/kafka-integration/api:onos-apps-kafka-integration-api",
- # "//apps/kafka-integration/app:onos-apps-kafka-integration-app",
+ #"//apps/kafka-integration/api:onos-apps-kafka-integration-api",
+ #"//apps/kafka-integration/app:onos-apps-kafka-integration-app",
]
FEATURES = [
diff --git a/tools/dev/mininet/onos.py b/tools/dev/mininet/onos.py
index c656a05..15232ac 100755
--- a/tools/dev/mininet/onos.py
+++ b/tools/dev/mininet/onos.py
@@ -127,7 +127,7 @@
return env
-tarDefaultPath = 'buck-out/gen/tools/package/onos-package/onos.tar.gz'
+tarDefaultPath = "bazel-out/k8-fastbuild/bin/onos.tar.gz"
def unpackONOS( destDir='/tmp', run=quietRun ):
"Unpack ONOS and return its location"
@@ -280,7 +280,7 @@
self.cmd( 'export PATH=%s:%s:$PATH' % ( onosbin, karafbin ) )
self.cmd( 'cd', self.ONOS_HOME )
self.ucmd( 'mkdir -p config && '
- 'onos-gen-partitions config/cluster.json',
+ 'onos-gen-default-cluster config/cluster.json --nodes ',
' '.join( node.IP() for node in nodes ) )
def intfsDown( self ):
@@ -397,6 +397,11 @@
( self.IP(), self.IP(), CopycatPort )
if nodeStr in result:
break
+
+ # just break if state is active
+ if "state=ACTIVE" in result:
+ break
+
info( '.' )
self.sanityCheck()
time.sleep( 1 )
diff --git a/tools/test/bin/onos-gen-default-cluster b/tools/test/bin/onos-gen-default-cluster
new file mode 100755
index 0000000..e557eda
--- /dev/null
+++ b/tools/test/bin/onos-gen-default-cluster
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+"""
+usage: onos-gen-default-cluster [-h] [-s PARTITION_SIZE] [-n NUM_PARTITIONS]
+ [filename] [node_ip [node_ip ...]]
+
+Generate the partitions json file given a list of IPs or from the $OCC*
+environment variables.
+
+positional arguments:
+ filename File to write output to. If none is provided, output
+ is written to stdout.
+ node_ip IP Address(es) of the node(s) in the cluster. If no
+ IPs are given, will use the $OC* environment
+ variables. NOTE: these arguments are only processed
+ after the filename argument.
+
+optional arguments:
+ -h, --help show this help message and exit
+"""
+
+from os import environ
+import argparse
+import re
+import json
+
+convert = lambda text: int(text) if text.isdigit() else text.lower()
+alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)]
+
+
+def get_vars_by_type(type):
+ vars = []
+ for var in environ:
+ if re.match(r"{}[0-9]+".format(type), var):
+ vars.append(var)
+ return sorted(vars, key=alphanum_key)
+
+
+def get_vars():
+ vars = get_vars_by_type('OCC')
+ if len(vars) == 0:
+ vars = get_vars_by_type('OC')
+ return vars
+
+
+def get_nodes(ips=None, default_port=9876):
+ node = lambda id, ip, port: {'id': id, 'ip': ip, 'port': port}
+ result = []
+ if not ips:
+ ips = [environ[v] for v in get_vars()]
+ i = 1
+ for ip_string in ips:
+ address_tuple = ip_string.split(":")
+ if len(address_tuple) == 3:
+ id = address_tuple[0]
+ ip = address_tuple[1]
+ port = int(address_tuple[2])
+ else:
+ i += 1
+ ip = ip_string
+ id = ip
+ port = default_port
+ result.append(node(id, ip, port))
+ return result
+
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(
+ description="Generate the partitions json file given a list of IPs or from environment variables.")
+
+ parser.add_argument(
+ 'filename', metavar='filename', type=str, nargs='?',
+ help='File to write output to. If none is provided, output is written to stdout.')
+
+ parser.add_argument(
+ '--nodes', '-n', metavar='node_ip', type=str, nargs='+',
+ help='IP Address(es) of the storage nodes. If no IPs are given, ' +
+ 'will use the $OCC* or $OC* environment variables. NOTE: these arguments' +
+ ' are only processed after the filename argument.')
+
+ args = parser.parse_args()
+ filename = args.filename
+ nodes = get_nodes(args.nodes)
+
+ data = {
+ 'name': 'onos',
+ 'controller': nodes
+ }
+ output = json.dumps(data, indent=4)
+
+ if filename:
+ with open(filename, 'w') as f:
+ f.write(output)
+ else:
+ print output
diff --git a/utils/misc/src/main/java/org/onlab/packet/LLDP.java b/utils/misc/src/main/java/org/onlab/packet/LLDP.java
index 33b1f85..e555f1f 100644
--- a/utils/misc/src/main/java/org/onlab/packet/LLDP.java
+++ b/utils/misc/src/main/java/org/onlab/packet/LLDP.java
@@ -37,8 +37,16 @@
public static final byte PORT_TLV_TYPE = 2;
public static final short PORT_TLV_SIZE = 5;
+
+ /**
+ * @deprecated since 1.15. Use the PORT_TLV_COMPONENT_SUBTYPE instead of PORT_TLV_SUBTYPE.
+ */
+ @Deprecated
public static final byte PORT_TLV_SUBTYPE = 2;
+ public static final byte PORT_TLV_COMPONENT_SUBTYPE = PORT_TLV_SUBTYPE;
+ public static final byte PORT_TLV_INTERFACE_NAME_SUBTYPE = 5;
+
public static final byte TTL_TLV_TYPE = 3;
public static final short TTL_TLV_SIZE = 2;
diff --git a/utils/misc/src/main/java/org/onlab/packet/ONOSLLDP.java b/utils/misc/src/main/java/org/onlab/packet/ONOSLLDP.java
index f0b981c..7405bbf 100644
--- a/utils/misc/src/main/java/org/onlab/packet/ONOSLLDP.java
+++ b/utils/misc/src/main/java/org/onlab/packet/ONOSLLDP.java
@@ -18,6 +18,7 @@
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang.ArrayUtils;
+import org.slf4j.Logger;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
@@ -31,16 +32,18 @@
import static org.onlab.packet.LLDPOrganizationalTLV.OUI_LENGTH;
import static org.onlab.packet.LLDPOrganizationalTLV.SUBTYPE_LENGTH;
+import static org.slf4j.LoggerFactory.getLogger;
/**
* ONOS LLDP containing organizational TLV for ONOS device discovery.
*/
public class ONOSLLDP extends LLDP {
+ private static final Logger log = getLogger(ONOSLLDP.class);
+
public static final String DEFAULT_DEVICE = "INVALID";
public static final String DEFAULT_NAME = "ONOS Discovery";
-
protected static final byte NAME_SUBTYPE = 1;
protected static final byte DEVICE_SUBTYPE = 2;
protected static final byte DOMAIN_SUBTYPE = 3;
@@ -62,11 +65,7 @@
private static final byte CHASSIS_TLV_SIZE = 7;
private static final byte CHASSIS_TLV_SUBTYPE = 4;
- private static final byte PORT_TLV_TYPE = 2;
- private static final byte PORT_TLV_SUBTYPE = 2;
-
private static final byte TTL_TLV_TYPE = 3;
-
private static final byte PORT_DESC_TLV_TYPE = 4;
private final byte[] ttlValue = new byte[] {0, 0x78};
@@ -137,7 +136,7 @@
}
public void setPortId(final int portNumber) {
- byte[] port = ArrayUtils.addAll(new byte[] {PORT_TLV_SUBTYPE},
+ byte[] port = ArrayUtils.addAll(new byte[] {PORT_TLV_COMPONENT_SUBTYPE},
String.valueOf(portNumber).getBytes(StandardCharsets.UTF_8));
LLDPTLV portTLV = new LLDPTLV();
@@ -147,6 +146,17 @@
this.setPortId(portTLV);
}
+ public void setPortName(final String portName) {
+ byte[] port = ArrayUtils.addAll(new byte[] {PORT_TLV_INTERFACE_NAME_SUBTYPE},
+ portName.getBytes(StandardCharsets.UTF_8));
+
+ LLDPTLV portTLV = new LLDPTLV();
+ portTLV.setLength((short) port.length);
+ portTLV.setType(PORT_TLV_TYPE);
+ portTLV.setValue(port);
+ this.setPortId(portTLV);
+ }
+
public void setTimestamp(long timestamp) {
LLDPOrganizationalTLV tmtlv = opttlvs.get(TIMESTAMP_SUBTYPE);
if (tmtlv == null) {
@@ -235,6 +245,17 @@
return null;
}
+ public LLDPTLV getPortDescTLV() {
+ for (LLDPTLV tlv : this.getOptionalTLVList()) {
+ if (tlv.getType() == PORT_DESC_TLV_TYPE) {
+ return tlv;
+ }
+ }
+
+ log.error("Cannot find the port description tlv type.");
+ return null;
+ }
+
public String getNameString() {
LLDPOrganizationalTLV tlv = getNameTLV();
if (tlv != null) {
@@ -259,12 +280,57 @@
return null;
}
+ public String getPortDescString() {
+ LLDPTLV tlv = getPortDescTLV();
+ if (tlv != null) {
+ return new String(tlv.getValue(), StandardCharsets.UTF_8);
+ }
+ return null;
+ }
+
public Integer getPort() {
ByteBuffer portBB = ByteBuffer.wrap(this.getPortId().getValue());
- portBB.position(1);
+ byte type = portBB.get();
- return Integer.parseInt(new String(portBB.array(),
- portBB.position(), portBB.remaining(), StandardCharsets.UTF_8));
+ if (type == PORT_TLV_COMPONENT_SUBTYPE) {
+ return Integer.parseInt(new String(portBB.array(),
+ portBB.position(), portBB.remaining(), StandardCharsets.UTF_8));
+ } else {
+ return -1;
+ }
+ }
+
+ public String getPortNameString() {
+ ByteBuffer portBB = ByteBuffer.wrap(this.getPortId().getValue());
+ byte type = portBB.get();
+
+ if (type == PORT_TLV_INTERFACE_NAME_SUBTYPE) {
+ return new String(portBB.array(), portBB.position(), portBB.remaining(), StandardCharsets.UTF_8);
+ } else {
+ log.error("Cannot find the port name tlv type.");
+ return null;
+ }
+ }
+
+ public MacAddress getChassisIdByMac() {
+ ByteBuffer portBB = ByteBuffer.wrap(this.getChassisId().getValue());
+ byte type = portBB.get();
+
+ if (type == CHASSIS_TLV_SUBTYPE) {
+ byte[] bytes = new byte[portBB.remaining()];
+
+ System.arraycopy(portBB.array(), portBB.position(), bytes, 0, MacAddress.MAC_ADDRESS_LENGTH);
+
+ return new MacAddress(bytes);
+ } else {
+ return MacAddress.NONE;
+ }
+ }
+
+ public short getTtlBySeconds() {
+ ByteBuffer portBB = ByteBuffer.wrap(this.getTtl().getValue());
+
+ return portBB.getShort();
}
public long getTimestamp() {
@@ -303,6 +369,22 @@
}
/**
+ * Given an ethernet packet, returns the device the LLDP came from.
+ * @param eth an ethernet packet
+ * @return a the lldp packet or null
+ */
+ public static ONOSLLDP parseLLDP(Ethernet eth) {
+ if (eth.getEtherType() == Ethernet.TYPE_LLDP ||
+ eth.getEtherType() == Ethernet.TYPE_BSN) {
+
+ return new ONOSLLDP((LLDP) eth.getPayload());
+ }
+
+ log.error("Packet is not the LLDP or BSN.");
+ return null;
+ }
+
+ /**
* Creates a link probe for link discovery/verification.
* @deprecated since 1.15. Insecure, do not use.
*
diff --git a/utils/misc/src/test/java/org/onlab/packet/ONOSLLDPTest.java b/utils/misc/src/test/java/org/onlab/packet/ONOSLLDPTest.java
index b2494b5..2405998 100644
--- a/utils/misc/src/test/java/org/onlab/packet/ONOSLLDPTest.java
+++ b/utils/misc/src/test/java/org/onlab/packet/ONOSLLDPTest.java
@@ -30,6 +30,7 @@
private static final Integer PORT_NUMBER = 2;
private static final Integer PORT_NUMBER_2 = 98761234;
private static final String PORT_DESC = "Ethernet1";
+ private static final String PORT_NAME = "Ethernet2";
private static final String TEST_SECRET = "test";
private ONOSLLDP onoslldp = ONOSLLDP.onosSecureLLDP(DEVICE_ID, CHASSIS_ID, PORT_NUMBER, PORT_DESC, TEST_SECRET);
@@ -39,11 +40,21 @@
*/
@Test
public void testPortNumber() throws Exception {
- assertEquals("the value from constructor with getPort value is miss matched",
+ assertEquals("the value from constructor with getPort value is mismatched",
PORT_NUMBER, onoslldp.getPort());
onoslldp.setPortId(PORT_NUMBER_2);
- assertEquals("the value from setPortId with getPort value is miss matched",
+ assertEquals("the value from setPortId with getPort value is mismatched",
PORT_NUMBER_2, onoslldp.getPort());
}
+
+ /**
+ * Tests port name and getters.
+ */
+ @Test
+ public void testPortName() throws Exception {
+ onoslldp.setPortName(PORT_NAME);
+ assertEquals("the value from setPortName with getPortNameString value is mismatched",
+ PORT_NAME, onoslldp.getPortNameString());
+ }
}
\ No newline at end of file