diff --git a/WORKSPACE b/WORKSPACE index 723f0ac1fa..1e83aaadff 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -68,6 +68,10 @@ load("//tools/build/bazel:p4lang_workspace.bzl", "generate_p4lang") generate_p4lang() +load("//tools/build/bazel:gnmi_workspace.bzl", "generate_gnmi") + +generate_gnmi() + git_repository( name = "build_bazel_rules_nodejs", remote = "https://github.com/bazelbuild/rules_nodejs.git", diff --git a/apps/odtn/service/src/test/resources/create-connectivity.json b/apps/odtn/service/src/test/resources/create-connectivity.json index 35798f4ec8..47fd6dc76b 100644 --- a/apps/odtn/service/src/test/resources/create-connectivity.json +++ b/apps/odtn/service/src/test/resources/create-connectivity.json @@ -26,8 +26,8 @@ "protection-role" : "WORK" } ], - "conn-constraint" : {}, - "topo-constraint" : {}, + "connectivity-constraint" : {}, + "topology-constraint" : {}, "resilience-constraint" : [ ] } } 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 51990d1629..2021aa86c0 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 @@ -69,6 +69,7 @@ import org.openstack4j.model.network.NetFloatingIP; import org.openstack4j.model.network.Network; import org.openstack4j.model.network.Port; import org.openstack4j.model.network.Router; +import org.openstack4j.model.network.RouterInterface; import org.osgi.service.component.ComponentContext; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; @@ -519,27 +520,33 @@ public class OpenstackRoutingArpHandler { } private void setFakeGatewayArpRuleByRouter(Router router, boolean install) { - setFakeGatewayArpRuleByGateway(router.getExternalGatewayInfo(), install); + setFakeGatewayArpRuleByGateway(router.getId(), router.getExternalGatewayInfo(), install); } - private Set getExternalGatewaySnatIps(ExternalGateway extGw) { - return osNetworkAdminService.ports().stream() - .filter(port -> - Objects.equals(port.getNetworkId(), extGw.getNetworkId())) - .filter(port -> - Objects.equals(port.getDeviceOwner(), DEVICE_OWNER_ROUTER_GW)) - .flatMap(port -> port.getFixedIps().stream()) + private Set getExternalGatewaySnatIps(String routerId, ExternalGateway extGw) { + if (routerId == null) { + return ImmutableSet.of(); + } + + Set portIds = osRouterAdminService.routerInterfaces(routerId).stream() + .map(RouterInterface::getPortId) + .collect(Collectors.toSet()); + + return portIds.stream() + .map(pid -> osNetworkAdminService.port(pid)) + .filter(p -> Objects.equals(p.getDeviceOwner(), DEVICE_OWNER_ROUTER_GW)) + .flatMap(p -> p.getFixedIps().stream()) .collect(Collectors.toSet()); } - private void setFakeGatewayArpRuleByGateway(ExternalGateway extGw, boolean install) { + private void setFakeGatewayArpRuleByGateway(String routerId, ExternalGateway extGw, boolean install) { if (ARP_BROADCAST_MODE.equals(getArpMode())) { if (extGw == null) { return; } - setFakeGatewayArpRuleByIps(getExternalGatewaySnatIps(extGw), install); + setFakeGatewayArpRuleByIps(getExternalGatewaySnatIps(routerId, extGw), install); } } @@ -653,13 +660,15 @@ public class OpenstackRoutingArpHandler { case OPENSTACK_ROUTER_GATEWAY_ADDED: eventExecutor.execute(() -> // add a gateway manually after adding a router - setFakeGatewayArpRuleByGateway(event.externalGateway(), true) + setFakeGatewayArpRuleByGateway(event.subject().getId(), + event.externalGateway(), true) ); break; case OPENSTACK_ROUTER_GATEWAY_REMOVED: eventExecutor.execute(() -> // remove a gateway from an existing router - setFakeGatewayArpRuleByGateway(event.externalGateway(), false) + setFakeGatewayArpRuleByGateway(event.subject().getId(), + event.externalGateway(), false) ); break; case OPENSTACK_FLOATING_IP_ASSOCIATED: @@ -875,6 +884,11 @@ public class OpenstackRoutingArpHandler { } private void setDefaultArpRule(OpenstackNode osNode, boolean install) { + + if (getArpMode() == null) { + return; + } + switch (getArpMode()) { case ARP_PROXY_MODE: setDefaultArpRuleForProxyMode(osNode, install); 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 1a9de18d8b..edcf6edfbb 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 @@ -482,15 +482,15 @@ public class OpenstackRoutingHandler { private void setInternalRoutes(Router osRouter, Subnet updatedSubnet, boolean install) { Network updatedNetwork = osNetworkAdminService.network(updatedSubnet.getNetworkId()); Set routableSubnets = routableSubnets(osRouter, updatedSubnet.getId()); - String updatedSegmendId = getSegmentId(updatedSubnet); + String updatedSegmentId = getSegmentId(updatedSubnet); // installs rule from/to my subnet intentionally to fix ICMP failure // to my subnet gateway if no external gateway added to the router osNodeService.completeNodes(COMPUTE).forEach(cNode -> { setInternalRouterRules( cNode.intgBridge(), - updatedSegmendId, - updatedSegmendId, + updatedSegmentId, + updatedSegmentId, IpPrefix.valueOf(updatedSubnet.getCidr()), IpPrefix.valueOf(updatedSubnet.getCidr()), updatedNetwork.getNetworkType(), @@ -500,7 +500,7 @@ public class OpenstackRoutingHandler { routableSubnets.forEach(subnet -> { setInternalRouterRules( cNode.intgBridge(), - updatedSegmendId, + updatedSegmentId, getSegmentId(subnet), IpPrefix.valueOf(updatedSubnet.getCidr()), IpPrefix.valueOf(subnet.getCidr()), @@ -510,7 +510,7 @@ public class OpenstackRoutingHandler { setInternalRouterRules( cNode.intgBridge(), getSegmentId(subnet), - updatedSegmendId, + updatedSegmentId, IpPrefix.valueOf(subnet.getCidr()), IpPrefix.valueOf(updatedSubnet.getCidr()), updatedNetwork.getNetworkType(), @@ -854,7 +854,6 @@ public class OpenstackRoutingHandler { .matchIPSrc(srcSubnet) .matchEthDst(Constants.DEFAULT_GATEWAY_MAC); - switch (networkType) { case VXLAN: sBuilder.matchTunnelId(Long.parseLong(segmentId)); @@ -886,7 +885,14 @@ public class OpenstackRoutingHandler { GW_COMMON_TABLE, install); + // TODO: we do not remove the IcmpReplyMatchRules with false installation flag + // need to find a better way to remove this rule + if (install) { + setIcmpReplyRules(deviceId, install); + } + } + private void setIcmpReplyRules(DeviceId deviceId, boolean install) { // Sends ICMP response to controller for SNATing ingress traffic TrafficSelector selector = DefaultTrafficSelector.builder() .matchEthType(Ethernet.TYPE_IPV4) diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java index 0fab57f571..1cc02b7525 100644 --- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java +++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java @@ -93,6 +93,9 @@ public class OpenstackRoutingIcmpHandler { private static final String ERR_REQ = "Failed to handle ICMP request: "; private static final String ERR_DUPLICATE = " already exists"; + private static final String VXLAN = "VXLAN"; + private static final String VLAN = "VLAN"; + @Reference(cardinality = ReferenceCardinality.MANDATORY) protected CoreService coreService; @@ -407,13 +410,26 @@ public class OpenstackRoutingIcmpHandler { } private void sendReply(Ethernet icmpReply, InstancePort instPort) { - TrafficTreatment treatment = DefaultTrafficTreatment.builder() - .setOutput(instPort.portNumber()) - .build(); + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder() + .setOutput(instPort.portNumber()); + + String netId = instPort.networkId(); + String segId = osNetworkService.segmentId(netId); + + switch (osNetworkService.networkType(netId)) { + case VXLAN: + tBuilder.setTunnelId(Long.valueOf(segId)); + break; + case VLAN: + tBuilder.setVlanId(VlanId.vlanId(segId)); + break; + default: + break; + } OutboundPacket packet = new DefaultOutboundPacket( instPort.deviceId(), - treatment, + tBuilder.build(), ByteBuffer.wrap(icmpReply.serialize())); packetService.emit(packet); @@ -435,7 +451,8 @@ public class OpenstackRoutingIcmpHandler { return; } - if (!gateways.isEmpty() && !gateways.contains(context.inPacket().receivedFrom().deviceId())) { + if (!gateways.isEmpty() && + !gateways.contains(context.inPacket().receivedFrom().deviceId())) { 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 863e40a23f..ba9ec96ef0 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 @@ -42,6 +42,7 @@ import org.onosproject.net.flow.DefaultTrafficTreatment; import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.flow.TrafficTreatment; import org.onosproject.net.flow.criteria.ExtensionSelector; +import org.onosproject.net.flow.instructions.ExtensionTreatment; import org.onosproject.openstacknetworking.api.InstancePort; import org.onosproject.openstacknetworking.api.InstancePortAdminService; import org.onosproject.openstacknetworking.api.InstancePortEvent; @@ -54,7 +55,6 @@ import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupEvent; import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupListener; import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupService; import org.onosproject.openstacknetworking.util.RulePopulatorUtil; -import org.onosproject.openstacknode.api.OpenstackNode; import org.onosproject.openstacknode.api.OpenstackNodeEvent; import org.onosproject.openstacknode.api.OpenstackNodeListener; import org.onosproject.openstacknode.api.OpenstackNodeService; @@ -176,13 +176,13 @@ public class OpenstackSecurityGroupHandler { .build(); private final InstancePortListener instancePortListener = - new InternalInstancePortListener(); + new InternalInstancePortListener(); private final OpenstackNetworkListener osNetworkListener = - new InternalOpenstackNetworkListener(); + new InternalOpenstackNetworkListener(); private final OpenstackNetworkListener osPortListener = - new InternalOpenstackPortListener(); + new InternalOpenstackPortListener(); private final OpenstackSecurityGroupListener securityGroupListener = - new InternalSecurityGroupListener(); + new InternalSecurityGroupListener(); private final OpenstackNodeListener osNodeListener = new InternalNodeListener(); private ConsistentMap removedOsPortStore; @@ -335,10 +335,10 @@ public class OpenstackSecurityGroupHandler { SecurityGroupRule rSgRule = new NeutronSecurityGroupRule .SecurityGroupRuleConcreteBuilder() - .from(sgRule) - .direction(sgRule.getDirection().toUpperCase() - .equals(EGRESS) ? INGRESS : EGRESS) - .build(); + .from(sgRule) + .direction(sgRule.getDirection().toUpperCase() + .equals(EGRESS) ? INGRESS : EGRESS) + .build(); populateSecurityGroupRule(rSgRule, instPort, port, rInstPort.ipAddress().toIpPrefix(), install); populateSecurityGroupRule(rSgRule, rInstPort, port, @@ -347,7 +347,7 @@ public class OpenstackSecurityGroupHandler { } else { populateSecurityGroupRule(sgRule, instPort, port, sgRule.getRemoteIpPrefix() == null ? IP_PREFIX_ANY : - IpPrefix.valueOf(sgRule.getRemoteIpPrefix()), install); + IpPrefix.valueOf(sgRule.getRemoteIpPrefix()), install); } } @@ -362,14 +362,25 @@ public class OpenstackSecurityGroupHandler { return; } + // XXX All egress traffic needs to go through connection tracking module, + // which might hurt its performance. + ExtensionTreatment ctTreatment = + niciraConnTrackTreatmentBuilder(driverService, instPort.deviceId()) + .commit(true) + .build(); + + TrafficTreatment treatment = DefaultTrafficTreatment.builder() + .extension(ctTreatment, instPort.deviceId()) + .transition(JUMP_TABLE) + .build(); + selectors.forEach(selector -> osFlowRuleService.setRule(appId, - instPort.deviceId(), - selector, - DefaultTrafficTreatment.builder().transition(JUMP_TABLE).build(), - PRIORITY_ACL_RULE, - ACL_TABLE, - install)); + instPort.deviceId(), + selector, treatment, + PRIORITY_ACL_RULE, + ACL_TABLE, + install)); } /** @@ -490,7 +501,7 @@ public class OpenstackSecurityGroupHandler { sgRule.getPortRangeMin() < sgRule.getPortRangeMax()) { Map portRangeMatchMap = buildPortRangeMatches(sgRule.getPortRangeMin(), - sgRule.getPortRangeMax()); + sgRule.getPortRangeMax()); portRangeMatchMap.forEach((key, value) -> { if (sgRule.getProtocol().toUpperCase().equals(PROTO_TCP)) { @@ -527,9 +538,6 @@ public class OpenstackSecurityGroupHandler { sgRule.getPortRangeMin() == null ? 0 : sgRule.getPortRangeMin(), sgRule.getPortRangeMax() == null ? 0 : sgRule.getPortRangeMax()); buildMatchRemoteIp(sBuilder, remoteIp, sgRule.getDirection()); - if (sgRule.getRemoteGroupId() != null && sgRule.getRemoteGroupId().isEmpty()) { - buildMatchRemoteIp(sBuilder, remoteIp, sgRule.getDirection()); - } } private void buildTunnelId(TrafficSelector.Builder sBuilder, Port port) { @@ -540,6 +548,8 @@ public class OpenstackSecurityGroupHandler { sBuilder.matchVlanId(VlanId.vlanId(segId)); } else if (VXLAN.equals(netType)) { sBuilder.matchTunnelId(Long.valueOf(segId)); + } else { + log.warn("Cannot tag the VID due to lack of support of virtual network type {}", netType); } } @@ -614,33 +624,31 @@ public class OpenstackSecurityGroupHandler { private void resetSecurityGroupRules() { if (useSecurityGroup) { - osNodeService.completeNodes(OpenstackNode.NodeType.COMPUTE) - .forEach(node -> osFlowRuleService - .setUpTableMissEntry(node.intgBridge(), ACL_TABLE)); + osNodeService.completeNodes(COMPUTE).forEach(node -> { + osFlowRuleService.setUpTableMissEntry(node.intgBridge(), ACL_TABLE); + initializeConnTrackTable(node.intgBridge(), true); + }); + securityGroupService.securityGroups().forEach(securityGroup -> securityGroup.getRules().forEach(this::securityGroupRuleAdded)); - osNodeService.nodes().stream() - .filter(node -> node.type().equals(OpenstackNode.NodeType.COMPUTE)) - .forEach(node -> initializeConnTrackTable(node .intgBridge(), true)); } else { - osNodeService.completeNodes(OpenstackNode.NodeType.COMPUTE) - .forEach(node -> osFlowRuleService - .connectTables(node.intgBridge(), ACL_TABLE, JUMP_TABLE)); + osNodeService.completeNodes(COMPUTE).forEach(node -> { + osFlowRuleService.connectTables(node.intgBridge(), ACL_TABLE, JUMP_TABLE); + initializeConnTrackTable(node.intgBridge(), false); + }); + securityGroupService.securityGroups().forEach(securityGroup -> securityGroup.getRules().forEach(this::securityGroupRuleRemoved)); - osNodeService.nodes().stream() - .filter(node -> node.type().equals(OpenstackNode.NodeType.COMPUTE)) - .forEach(node -> initializeConnTrackTable(node.intgBridge(), false)); } log.info("Reset security group info " + - (useSecurityGroup ? " with " : " without") + " Security Group"); + (useSecurityGroup ? " with " : " without") + " Security Group"); } private void securityGroupRuleAdded(SecurityGroupRule sgRule) { osNetService.ports().stream() .filter(port -> port.getSecurityGroups() - .contains(sgRule.getSecurityGroupId())) + .contains(sgRule.getSecurityGroupId())) .forEach(port -> { updateSecurityGroupRule( instancePortService.instancePort(port.getId()), @@ -655,7 +663,7 @@ public class OpenstackSecurityGroupHandler { Sets.union(osNetService.ports(), removedPorts).stream() .filter(port -> port.getSecurityGroups() - .contains(sgRule.getSecurityGroupId())) + .contains(sgRule.getSecurityGroupId())) .forEach(port -> { updateSecurityGroupRule( instancePortService.instancePort(port.getId()), @@ -825,7 +833,7 @@ public class OpenstackSecurityGroupHandler { } private class InternalOpenstackNetworkListener - implements OpenstackNetworkListener { + implements OpenstackNetworkListener { @Override public boolean isRelevant(OpenstackNetworkEvent event) { @@ -881,7 +889,7 @@ public class OpenstackSecurityGroupHandler { } private class InternalSecurityGroupListener - implements OpenstackSecurityGroupListener { + implements OpenstackSecurityGroupListener { @Override public boolean isRelevant(OpenstackSecurityGroupEvent event) { @@ -936,22 +944,9 @@ public class OpenstackSecurityGroupHandler { @Override public void event(OpenstackNodeEvent event) { - OpenstackNode osNode = event.subject(); - switch (event.type()) { case OPENSTACK_NODE_COMPLETE: - eventExecutor.execute(() -> { - try { - if (useSecurityGroup) { - initializeConnTrackTable(osNode.intgBridge(), true); - log.info("SG table initialization : {} is done", - osNode.intgBridge()); - } - } catch (IllegalArgumentException e) { - log.error("ACL table initialization error : {}", - e.getMessage()); - } - }); + resetSecurityGroupRules(); break; case OPENSTACK_NODE_CREATED: case OPENSTACK_NODE_REMOVED: 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 b348d4903f..f6977a3d3b 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 @@ -39,7 +39,6 @@ import org.onosproject.net.flow.DefaultTrafficSelector; import org.onosproject.net.flow.DefaultTrafficTreatment; import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.flow.TrafficTreatment; -import org.onosproject.net.flow.instructions.ExtensionTreatment; import org.onosproject.openstacknetworking.api.InstancePort; import org.onosproject.openstacknetworking.api.InstancePortEvent; import org.onosproject.openstacknetworking.api.InstancePortListener; @@ -49,7 +48,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.openstacknetworking.util.RulePopulatorUtil; import org.onosproject.openstacknode.api.OpenstackNode; import org.onosproject.openstacknode.api.OpenstackNodeService; import org.openstack4j.model.network.Network; @@ -501,25 +499,21 @@ public final class OpenstackSwitchingHandler { .matchInPort(instPort.portNumber()) .build(); - // XXX All egress traffic needs to go through connection tracking module, - // which might hurt its performance. - ExtensionTreatment ctTreatment = - RulePopulatorUtil.niciraConnTrackTreatmentBuilder(driverService, instPort.deviceId()) - .commit(true).build(); + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder() + .setTunnelId(getVni(instPort)); - TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder() - .setTunnelId(getVni(instPort)) - .transition(ARP_TABLE); - if (securityGroupService.isSecurityGroupEnabled() && ethType == Ethernet.TYPE_IPV4) { - tb.extension(ctTreatment, instPort.deviceId()); + if (ethType == Ethernet.TYPE_ARP) { + tBuilder.transition(ARP_TABLE); + } else if (ethType == Ethernet.TYPE_IPV4) { + tBuilder.transition(ACL_TABLE); } osFlowRuleService.setRule( appId, instPort.deviceId(), selector, - tb.build(), + tBuilder.build(), PRIORITY_TUNNEL_TAG_RULE, VTAG_TABLE, install); diff --git a/apps/route-service/app/src/main/java/org/onosproject/routeservice/cli/RouteRemoveCommand.java b/apps/route-service/app/src/main/java/org/onosproject/routeservice/cli/RouteRemoveCommand.java index eb6f01c4ca..8fb29ecbb7 100644 --- a/apps/route-service/app/src/main/java/org/onosproject/routeservice/cli/RouteRemoveCommand.java +++ b/apps/route-service/app/src/main/java/org/onosproject/routeservice/cli/RouteRemoveCommand.java @@ -43,6 +43,10 @@ public class RouteRemoveCommand extends AbstractShellCommand { required = true) String nextHopString = null; + @Argument(index = 2, name = "source", description = "Source type of the route", + required = false) + String source = null; + @Override protected void doExecute() { RouteAdminService service = AbstractShellCommand.get(RouteAdminService.class); @@ -50,7 +54,14 @@ public class RouteRemoveCommand extends AbstractShellCommand { IpPrefix prefix = IpPrefix.valueOf(prefixString); IpAddress nextHop = IpAddress.valueOf(nextHopString); - service.withdraw(Collections.singleton(new Route(Route.Source.STATIC, prefix, nextHop))); + // Routes through cli without mentioning source then it is created as STATIC, + // otherwise routes are created with corresponding source. + + Route route = source == null ? + new Route(Route.Source.STATIC, prefix, nextHop) : + new Route(Route.Source.valueOf(source), prefix, nextHop); + + service.withdraw(Collections.singleton(route)); } } diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java index ffc0e4dd45..ae35f7baf1 100644 --- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java +++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java @@ -448,18 +448,37 @@ public class HostHandler { * @param pairRemotePort pair remote port */ private void probe(Host host, ConnectPoint location, DeviceId pairDeviceId, PortNumber pairRemotePort) { + //Check if the host still exists in the host store + if (hostService.getHost(host.id()) == null) { + log.debug("Host entry for host {} no more present. Aborting hostprobe discover for this host", host.id()); + return; + } + VlanId vlanToProbe = host.vlan().equals(VlanId.NONE) ? srManager.getInternalVlanId(location) : host.vlan(); - srManager.interfaceService.getInterfaces().stream() - .filter(i -> i.vlanTagged().contains(vlanToProbe) || - i.vlanUntagged().equals(vlanToProbe) || - i.vlanNative().equals(vlanToProbe)) - .filter(i -> i.connectPoint().deviceId().equals(pairDeviceId)) - .filter(i -> !i.connectPoint().port().equals(pairRemotePort)) - .forEach(i -> { - log.debug("Probing host {} on pair device {}", host.id(), i.connectPoint()); - srManager.probingService.probeHost(host, i.connectPoint(), ProbeMode.DISCOVER); - }); + if (srManager.symmetricProbing) { + srManager.interfaceService.getInterfaces().stream() + .filter(i -> i.vlanTagged().contains(vlanToProbe) || + i.vlanUntagged().equals(vlanToProbe) || + i.vlanNative().equals(vlanToProbe)) + .filter(i -> i.connectPoint().deviceId().equals(pairDeviceId)) + .filter(i -> i.connectPoint().port().equals(location.port())) + .forEach(i -> { + log.debug("Probing host {} on pair device {}", host.id(), i.connectPoint()); + srManager.probingService.probeHost(host, i.connectPoint(), ProbeMode.DISCOVER); + }); + } else { + srManager.interfaceService.getInterfaces().stream() + .filter(i -> i.vlanTagged().contains(vlanToProbe) || + i.vlanUntagged().equals(vlanToProbe) || + i.vlanNative().equals(vlanToProbe)) + .filter(i -> i.connectPoint().deviceId().equals(pairDeviceId)) + .filter(i -> !i.connectPoint().port().equals(pairRemotePort)) + .forEach(i -> { + log.debug("Probing host {} on pair device {}", host.id(), i.connectPoint()); + srManager.probingService.probeHost(host, i.connectPoint(), ProbeMode.DISCOVER); + }); + } } /** diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/OsgiPropertyConstants.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/OsgiPropertyConstants.java index 399e95b72a..7b5a6fc2d4 100644 --- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/OsgiPropertyConstants.java +++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/OsgiPropertyConstants.java @@ -41,4 +41,7 @@ public final class OsgiPropertyConstants { public static final String PROP_PW_TRANSPORT_VLAN = "pwTransportVlan"; public static final int PW_TRANSPORT_VLAN_DEFAULT = 4090; + static final String PROP_SYMMETRIC_PROBING = "symmetricProbing"; + static final boolean SYMMETRIC_PROBING_DEFAULT = false; + } diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java index 17e733c22b..c75de3cc24 100644 --- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java +++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java @@ -165,10 +165,12 @@ import static org.onosproject.segmentrouting.OsgiPropertyConstants.PROP_PW_TRANS import static org.onosproject.segmentrouting.OsgiPropertyConstants.PROP_RESPOND_TO_UNKNOWN_HOSTS; import static org.onosproject.segmentrouting.OsgiPropertyConstants.PROP_ROUTE_DOUBLE_TAGGED_HOSTS; import static org.onosproject.segmentrouting.OsgiPropertyConstants.PROP_SINGLE_HOMED_DOWN; +import static org.onosproject.segmentrouting.OsgiPropertyConstants.PROP_SYMMETRIC_PROBING; import static org.onosproject.segmentrouting.OsgiPropertyConstants.PW_TRANSPORT_VLAN_DEFAULT; import static org.onosproject.segmentrouting.OsgiPropertyConstants.RESPOND_TO_UNKNOWN_HOSTS_DEFAULT; import static org.onosproject.segmentrouting.OsgiPropertyConstants.ROUTE_DOUBLE_TAGGED_HOSTS_DEFAULT; import static org.onosproject.segmentrouting.OsgiPropertyConstants.SINGLE_HOMED_DOWN_DEFAULT; +import static org.onosproject.segmentrouting.OsgiPropertyConstants.SYMMETRIC_PROBING_DEFAULT; /** * Segment routing manager. @@ -183,6 +185,7 @@ import static org.onosproject.segmentrouting.OsgiPropertyConstants.SINGLE_HOMED_ PROP_ROUTE_DOUBLE_TAGGED_HOSTS + ":Boolean=" + ROUTE_DOUBLE_TAGGED_HOSTS_DEFAULT, PROP_DEFAULT_INTERNAL_VLAN + ":Integer=" + DEFAULT_INTERNAL_VLAN_DEFAULT, PROP_PW_TRANSPORT_VLAN + ":Integer=" + PW_TRANSPORT_VLAN_DEFAULT, + PROP_SYMMETRIC_PROBING + ":Boolean=" + SYMMETRIC_PROBING_DEFAULT } ) public class SegmentRoutingManager implements SegmentRoutingService { @@ -256,6 +259,9 @@ public class SegmentRoutingManager implements SegmentRoutingService { /** Enable active probing to discover dual-homed hosts. */ boolean activeProbing = ACTIVE_PROBING_DEFAULT; + /** Enable only send probe on the same port number of the pair device. */ + boolean symmetricProbing = SYMMETRIC_PROBING_DEFAULT; + /** Enable administratively taking down single-homed hosts. */ boolean singleHomedDown = SINGLE_HOMED_DOWN_DEFAULT; @@ -625,6 +631,14 @@ public class SegmentRoutingManager implements SegmentRoutingService { log.info("{} active probing", activeProbing ? "Enabling" : "Disabling"); } + + String strSymmetricProbing = Tools.get(properties, PROP_SYMMETRIC_PROBING); + boolean expectSymmetricProbing = Boolean.parseBoolean(strSymmetricProbing); + if (expectSymmetricProbing != symmetricProbing) { + symmetricProbing = expectSymmetricProbing; + log.info("{} symmetric probing", symmetricProbing ? "Enabling" : "Disabling"); + } + String strSingleHomedDown = Tools.get(properties, PROP_SINGLE_HOMED_DOWN); boolean expectSingleHomedDown = Boolean.parseBoolean(strSingleHomedDown); if (expectSingleHomedDown != singleHomedDown) { diff --git a/core/api/src/main/java/org/onosproject/net/group/DefaultGroupDescription.java b/core/api/src/main/java/org/onosproject/net/group/DefaultGroupDescription.java index e047062831..4322482ac3 100644 --- a/core/api/src/main/java/org/onosproject/net/group/DefaultGroupDescription.java +++ b/core/api/src/main/java/org/onosproject/net/group/DefaultGroupDescription.java @@ -65,7 +65,8 @@ public class DefaultGroupDescription implements GroupDescription { if (this.type == GroupDescription.Type.INDIRECT) { checkArgument(buckets.buckets().size() == 1, "Indirect group " + "should have only one action bucket"); - } + } + checkArgument(buckets.buckets().stream().allMatch(b -> b.type() == type), "Inconsistent bucket type"); this.appCookie = appCookie; this.givenGroupId = groupId; this.appId = appId; diff --git a/core/api/src/test/java/org/onosproject/net/group/DefaultGroupDescriptionTest.java b/core/api/src/test/java/org/onosproject/net/group/DefaultGroupDescriptionTest.java index 0a0a093aa3..3d2d3687bc 100644 --- a/core/api/src/test/java/org/onosproject/net/group/DefaultGroupDescriptionTest.java +++ b/core/api/src/test/java/org/onosproject/net/group/DefaultGroupDescriptionTest.java @@ -16,6 +16,8 @@ package org.onosproject.net.group; import org.junit.Test; +import org.onosproject.core.GroupId; +import org.onosproject.net.PortNumber; import org.onosproject.net.flow.DefaultTrafficTreatment; import org.onosproject.net.flow.TrafficTreatment; @@ -32,28 +34,31 @@ import static org.onosproject.net.NetTestTools.did; * Default group description unit tests. */ public class DefaultGroupDescriptionTest { - byte[] keyData = "abcdefg".getBytes(); + private final byte[] keyData = "abcdefg".getBytes(); private final GroupKey key = new DefaultGroupKey(keyData); - private final TrafficTreatment treatment = - DefaultTrafficTreatment.emptyTreatment(); - private final GroupBucket bucket = - DefaultGroupBucket.createSelectGroupBucket(treatment); - private final GroupBuckets groupBuckets = - new GroupBuckets(ImmutableList.of(bucket)); + private final GroupId groupId1 = new GroupId(1); + private final TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment(); + + private final GroupBucket failoverGroupBucket = + DefaultGroupBucket.createFailoverGroupBucket(treatment, PortNumber.IN_PORT, groupId1); + private final GroupBuckets failoverGroupBuckets = new GroupBuckets(ImmutableList.of(failoverGroupBucket)); + private final GroupBucket indirectGroupBucket = + DefaultGroupBucket.createIndirectGroupBucket(treatment); + private final GroupBuckets indirectGroupBuckets = new GroupBuckets(ImmutableList.of(indirectGroupBucket)); + private final DefaultGroupDescription d1 = new DefaultGroupDescription(did("2"), GroupDescription.Type.FAILOVER, - groupBuckets); - private final DefaultGroupDescription sameAsD1 = - new DefaultGroupDescription(d1); + failoverGroupBuckets); + private final DefaultGroupDescription sameAsD1 = new DefaultGroupDescription(d1); private final DefaultGroupDescription d2 = new DefaultGroupDescription(did("2"), GroupDescription.Type.INDIRECT, - groupBuckets); + indirectGroupBuckets); private final DefaultGroupDescription d3 = new DefaultGroupDescription(did("3"), GroupDescription.Type.FAILOVER, - groupBuckets, + failoverGroupBuckets, key, 711, APP_ID); @@ -86,7 +91,7 @@ public class DefaultGroupDescriptionTest { public void testConstruction() { assertThat(d3.deviceId(), is(did("3"))); assertThat(d3.type(), is(GroupDescription.Type.FAILOVER)); - assertThat(d3.buckets(), is(groupBuckets)); + assertThat(d3.buckets(), is(failoverGroupBuckets)); assertThat(d3.appId(), is(APP_ID)); assertThat(d3.givenGroupId(), is(711)); assertThat(key.key(), is(keyData)); diff --git a/core/api/src/test/java/org/onosproject/net/group/DefaultGroupTest.java b/core/api/src/test/java/org/onosproject/net/group/DefaultGroupTest.java index e8fb7b3bf3..c84ac876f8 100644 --- a/core/api/src/test/java/org/onosproject/net/group/DefaultGroupTest.java +++ b/core/api/src/test/java/org/onosproject/net/group/DefaultGroupTest.java @@ -18,6 +18,7 @@ package org.onosproject.net.group; import org.junit.Test; import org.onosproject.core.GroupId; import org.onosproject.net.NetTestTools; +import org.onosproject.net.PortNumber; import org.onosproject.net.flow.DefaultTrafficTreatment; import com.google.common.collect.ImmutableList; @@ -35,24 +36,20 @@ public class DefaultGroupTest { private final GroupId id2 = new GroupId(7); private final GroupId id3 = new GroupId(1234); - private final GroupBucket bucket = - DefaultGroupBucket.createSelectGroupBucket( - DefaultTrafficTreatment.emptyTreatment()); - private final GroupBuckets groupBuckets = - new GroupBuckets(ImmutableList.of(bucket)); - private final GroupDescription groupDesc1 = - new DefaultGroupDescription(did("1"), - GroupDescription.Type.FAILOVER, - groupBuckets); - private final GroupDescription groupDesc2 = - new DefaultGroupDescription(did("2"), - GroupDescription.Type.FAILOVER, - groupBuckets); + private final GroupBucket failoverBucket = DefaultGroupBucket.createFailoverGroupBucket( + DefaultTrafficTreatment.emptyTreatment(), PortNumber.IN_PORT, id1); + private final GroupBuckets failoverGroupBuckets = new GroupBuckets(ImmutableList.of(failoverBucket)); - private final GroupDescription groupDesc3 = - new DefaultGroupDescription(did("3"), - GroupDescription.Type.INDIRECT, - groupBuckets); + private final GroupBucket indirectBucket = + DefaultGroupBucket.createIndirectGroupBucket(DefaultTrafficTreatment.emptyTreatment()); + private final GroupBuckets indirectGroupBuckets = new GroupBuckets(ImmutableList.of(indirectBucket)); + + private final GroupDescription groupDesc1 = + new DefaultGroupDescription(did("1"), GroupDescription.Type.FAILOVER, failoverGroupBuckets); + private final GroupDescription groupDesc2 = + new DefaultGroupDescription(did("2"), GroupDescription.Type.FAILOVER, failoverGroupBuckets); + private final GroupDescription groupDesc3 = + new DefaultGroupDescription(did("3"), GroupDescription.Type.INDIRECT, indirectGroupBuckets); DefaultGroup group1 = new DefaultGroup(id1, groupDesc1); DefaultGroup sameAsGroup1 = new DefaultGroup(id1, groupDesc1); @@ -83,7 +80,7 @@ public class DefaultGroupTest { assertThat(group1.life(), is(0L)); assertThat(group1.packets(), is(0L)); assertThat(group1.referenceCount(), is(0L)); - assertThat(group1.buckets(), is(groupBuckets)); + assertThat(group1.buckets(), is(failoverGroupBuckets)); assertThat(group1.state(), is(Group.GroupState.PENDING_ADD)); assertThat(group1.failedRetryCount(), is(0)); } @@ -94,14 +91,14 @@ public class DefaultGroupTest { @Test public void checkConstructionWithDid() { DefaultGroup group = new DefaultGroup(id2, NetTestTools.did("1"), - GroupDescription.Type.ALL, groupBuckets); + GroupDescription.Type.FAILOVER, failoverGroupBuckets); assertThat(group.id(), is(id2)); assertThat(group.bytes(), is(0L)); assertThat(group.life(), is(0L)); assertThat(group.packets(), is(0L)); assertThat(group.referenceCount(), is(0L)); assertThat(group.deviceId(), is(NetTestTools.did("1"))); - assertThat(group.buckets(), is(groupBuckets)); + assertThat(group.buckets(), is(failoverGroupBuckets)); assertThat(group.failedRetryCount(), is(0)); } diff --git a/core/common/src/test/java/org/onosproject/codec/impl/GroupCodecTest.java b/core/common/src/test/java/org/onosproject/codec/impl/GroupCodecTest.java index 0867213bdc..19c9671ed9 100644 --- a/core/common/src/test/java/org/onosproject/codec/impl/GroupCodecTest.java +++ b/core/common/src/test/java/org/onosproject/codec/impl/GroupCodecTest.java @@ -76,23 +76,22 @@ public class GroupCodecTest { @Test public void codecEncodeTest() { - GroupBucket bucket1 = DefaultGroupBucket - .createSelectGroupBucket(DefaultTrafficTreatment.emptyTreatment()); - GroupBucket bucket2 = DefaultGroupBucket - .createIndirectGroupBucket(DefaultTrafficTreatment.emptyTreatment()); - GroupBuckets buckets = new GroupBuckets(ImmutableList.of(bucket1, bucket2)); - GroupBuckets bucketsIndirect = new GroupBuckets(ImmutableList.of(bucket2)); + GroupBucket bucket1 = DefaultGroupBucket.createAllGroupBucket(DefaultTrafficTreatment.emptyTreatment()); + GroupBucket bucket2 = DefaultGroupBucket.createAllGroupBucket(DefaultTrafficTreatment.emptyTreatment()); + GroupBucket bucket3 = DefaultGroupBucket.createIndirectGroupBucket(DefaultTrafficTreatment.emptyTreatment()); + GroupBuckets allBuckets = new GroupBuckets(ImmutableList.of(bucket1, bucket2)); + GroupBuckets indirectBuckets = new GroupBuckets(ImmutableList.of(bucket3)); DefaultGroup group = new DefaultGroup( new GroupId(1), NetTestTools.did("d1"), ALL, - buckets); + allBuckets); DefaultGroup group1 = new DefaultGroup( new GroupId(2), NetTestTools.did("d2"), INDIRECT, - bucketsIndirect); + indirectBuckets); MockCodecContext context = new MockCodecContext(); GroupCodec codec = new GroupCodec(); diff --git a/core/common/src/test/java/org/onosproject/utils/ComparatorsTest.java b/core/common/src/test/java/org/onosproject/utils/ComparatorsTest.java index 6047719bb3..d616e71c36 100644 --- a/core/common/src/test/java/org/onosproject/utils/ComparatorsTest.java +++ b/core/common/src/test/java/org/onosproject/utils/ComparatorsTest.java @@ -129,8 +129,7 @@ public class ComparatorsTest { private final ConnectPoint cp = new ConnectPoint(DeviceId.deviceId("of:00001"), PortNumber.portNumber(100)); private final GroupBucket testBucket = - DefaultGroupBucket.createSelectGroupBucket( - DefaultTrafficTreatment.emptyTreatment()); + DefaultGroupBucket.createAllGroupBucket(DefaultTrafficTreatment.emptyTreatment()); private final GroupBuckets groupBuckets = new GroupBuckets(ImmutableList.of(testBucket)); private final GroupDescription groupDesc1 = diff --git a/core/store/dist/src/test/java/org/onosproject/store/group/impl/DistributedGroupStoreTest.java b/core/store/dist/src/test/java/org/onosproject/store/group/impl/DistributedGroupStoreTest.java index 0a44359184..087bd808ad 100644 --- a/core/store/dist/src/test/java/org/onosproject/store/group/impl/DistributedGroupStoreTest.java +++ b/core/store/dist/src/test/java/org/onosproject/store/group/impl/DistributedGroupStoreTest.java @@ -61,11 +61,11 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.onosproject.net.NetTestTools.APP_ID; import static org.onosproject.net.NetTestTools.did; import static org.onosproject.net.group.GroupDescription.Type.ALL; import static org.onosproject.net.group.GroupDescription.Type.INDIRECT; -import static org.onosproject.net.group.GroupDescription.Type.SELECT; import static org.onosproject.net.group.GroupStore.UpdateType.ADD; import static org.onosproject.net.group.GroupStore.UpdateType.SET; /** @@ -73,49 +73,49 @@ import static org.onosproject.net.group.GroupStore.UpdateType.SET; */ public class DistributedGroupStoreTest { - DeviceId deviceId1 = did("dev1"); - DeviceId deviceId2 = did("dev2"); - GroupId groupId1 = new GroupId(1); - GroupId groupId2 = new GroupId(2); - GroupId groupId3 = new GroupId(3); - GroupKey groupKey1 = new DefaultGroupKey("abc".getBytes()); - GroupKey groupKey2 = new DefaultGroupKey("def".getBytes()); - GroupKey groupKey3 = new DefaultGroupKey("ghi".getBytes()); + private final DeviceId deviceId1 = did("dev1"); + private final DeviceId deviceId2 = did("dev2"); + private final GroupId groupId1 = new GroupId(1); + private final GroupId groupId2 = new GroupId(2); + private final GroupId groupId3 = new GroupId(3); + private final GroupKey groupKey1 = new DefaultGroupKey("abc".getBytes()); + private final GroupKey groupKey2 = new DefaultGroupKey("def".getBytes()); + private final GroupKey groupKey3 = new DefaultGroupKey("ghi".getBytes()); - TrafficTreatment treatment = - DefaultTrafficTreatment.emptyTreatment(); - GroupBucket selectGroupBucket = - DefaultGroupBucket.createSelectGroupBucket(treatment); - GroupBucket failoverGroupBucket = - DefaultGroupBucket.createFailoverGroupBucket(treatment, - PortNumber.IN_PORT, groupId1); + private final TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment(); + private final TrafficTreatment treatment2 = DefaultTrafficTreatment.builder() + .setOutput(PortNumber.portNumber(2)).build(); + private final GroupBucket allGroupBucket = DefaultGroupBucket.createAllGroupBucket(treatment); + private final GroupBucket allGroupBucket2 = DefaultGroupBucket.createAllGroupBucket(treatment2); + private final GroupBuckets allGroupBuckets = new GroupBuckets(ImmutableList.of(allGroupBucket)); + private final GroupBucket indirectGroupBucket = DefaultGroupBucket.createIndirectGroupBucket(treatment); + private final GroupBuckets indirectGroupBuckets = new GroupBuckets(ImmutableList.of(indirectGroupBucket)); - GroupBuckets buckets = new GroupBuckets(ImmutableList.of(selectGroupBucket)); - GroupDescription groupDescription1 = new DefaultGroupDescription( + private final GroupDescription groupDescription1 = new DefaultGroupDescription( deviceId1, ALL, - buckets, + allGroupBuckets, groupKey1, groupId1.id(), APP_ID); - GroupDescription groupDescription2 = new DefaultGroupDescription( + private final GroupDescription groupDescription2 = new DefaultGroupDescription( deviceId2, INDIRECT, - buckets, + indirectGroupBuckets, groupKey2, groupId2.id(), APP_ID); - GroupDescription groupDescription3 = new DefaultGroupDescription( + private final GroupDescription groupDescription3 = new DefaultGroupDescription( deviceId2, INDIRECT, - buckets, + indirectGroupBuckets, groupKey3, groupId3.id(), APP_ID); - DistributedGroupStore groupStoreImpl; - GroupStore groupStore; - ConsistentMap auditPendingReqQueue; + private DistributedGroupStore groupStoreImpl; + private GroupStore groupStore; + private ConsistentMap auditPendingReqQueue; static class MasterOfAll extends MastershipServiceAdapter { @Override @@ -285,8 +285,8 @@ public class DistributedGroupStoreTest { GroupDescription groupDescription3 = new DefaultGroupDescription( deviceId1, - SELECT, - buckets, + ALL, + allGroupBuckets, new DefaultGroupKey("aaa".getBytes()), null, APP_ID); @@ -347,7 +347,7 @@ public class DistributedGroupStoreTest { GroupOperation opAdd = GroupOperation.createAddGroupOperation(groupId1, INDIRECT, - buckets); + indirectGroupBuckets); groupStore.groupOperationFailed(deviceId1, opAdd); List eventsAfterAddFailed = delegate.eventsSeen(); @@ -361,7 +361,7 @@ public class DistributedGroupStoreTest { GroupOperation opModify = GroupOperation.createModifyGroupOperation(groupId2, INDIRECT, - buckets); + indirectGroupBuckets); groupStore.groupOperationFailed(deviceId2, opModify); List eventsAfterModifyFailed = delegate.eventsSeen(); assertThat(eventsAfterModifyFailed, hasSize(1)); @@ -400,7 +400,7 @@ public class DistributedGroupStoreTest { // test group exists GroupOperation opAdd = GroupOperation - .createAddGroupOperation(groupId1, INDIRECT, buckets); + .createAddGroupOperation(groupId1, ALL, allGroupBuckets); GroupOperation addFailedExists = GroupOperation .createFailedGroupOperation(opAdd, GroupMsgErrorCode.GROUP_EXISTS); groupStore.groupOperationFailed(deviceId1, addFailedExists); @@ -420,7 +420,7 @@ public class DistributedGroupStoreTest { assertEquals(0, g2.failedRetryCount()); assertEquals(GroupState.PENDING_ADD, g2.state()); GroupOperation opAdd1 = GroupOperation - .createAddGroupOperation(groupId2, INDIRECT, buckets); + .createAddGroupOperation(groupId2, INDIRECT, indirectGroupBuckets); GroupOperation addFailedInvalid = GroupOperation .createFailedGroupOperation(opAdd1, GroupMsgErrorCode.INVALID_GROUP); @@ -487,9 +487,7 @@ public class DistributedGroupStoreTest { */ @Test public void testUpdateGroupDescription() { - - GroupBuckets buckets = - new GroupBuckets(ImmutableList.of(failoverGroupBucket, selectGroupBucket)); + GroupBuckets buckets = new GroupBuckets(ImmutableList.of(allGroupBucket2)); groupStore.deviceInitialAuditCompleted(deviceId1, true); groupStore.storeGroupDescription(groupDescription1); @@ -504,40 +502,31 @@ public class DistributedGroupStoreTest { assertThat(group1.appCookie(), is(newKey)); assertThat(group1.buckets().buckets(), hasSize(2)); - short weight = 5; - GroupBucket selectGroupBucketWithWeight = - DefaultGroupBucket.createSelectGroupBucket(treatment, weight); - buckets = new GroupBuckets(ImmutableList.of(failoverGroupBucket, - selectGroupBucketWithWeight)); - + buckets = new GroupBuckets(ImmutableList.of(allGroupBucket, allGroupBucket2)); groupStore.updateGroupDescription(deviceId1, newKey, ADD, buckets, newKey); - group1 = groupStore.getGroup(deviceId1, groupId1); assertThat(group1.appCookie(), is(newKey)); assertThat(group1.buckets().buckets(), hasSize(2)); for (GroupBucket bucket : group1.buckets().buckets()) { - if (bucket.type() == SELECT) { - assertEquals(weight, bucket.weight()); - } + assertTrue(bucket.treatment().equals(treatment) || + bucket.treatment().equals(treatment2)); } - buckets = new GroupBuckets(ImmutableList.of(selectGroupBucketWithWeight)); - + buckets = new GroupBuckets(ImmutableList.of(allGroupBucket2)); groupStore.updateGroupDescription(deviceId1, newKey, SET, buckets, newKey); - group1 = groupStore.getGroup(deviceId1, groupId1); assertThat(group1.appCookie(), is(newKey)); assertThat(group1.buckets().buckets(), hasSize(1)); GroupBucket onlyBucket = group1.buckets().buckets().iterator().next(); - assertEquals(weight, onlyBucket.weight()); + assertEquals(treatment2, onlyBucket.treatment()); } @Test diff --git a/drivers/gnmi/BUILD b/drivers/gnmi/BUILD index 50d8b5e739..63b11c6962 100644 --- a/drivers/gnmi/BUILD +++ b/drivers/gnmi/BUILD @@ -4,8 +4,7 @@ COMPILE_DEPS = CORE_DEPS + KRYO + [ "@io_grpc_grpc_java//netty", "@io_grpc_grpc_java//stub", "//core/store/serializers:onos-core-serializers", - "//protocols/gnmi/stub:gnmi_java_grpc", - "//protocols/gnmi/stub:gnmi_java_proto", + "//protocols/gnmi/stub:onos-protocols-gnmi-stub", "//protocols/grpc/api:onos-protocols-grpc-api", "//protocols/grpc/proto:onos-protocols-grpc-proto", ] diff --git a/modules.defs b/modules.defs new file mode 100644 index 0000000000..b4097c70da --- /dev/null +++ b/modules.defs @@ -0,0 +1,326 @@ +UTILS = [ + '//utils/osgi:onlab-osgi', + '//utils/junit:onlab-junit', + '//utils/misc:onlab-misc', + '//utils/rest:onlab-rest', + '//tools/build/conf:onos-build-conf', +] + +API = [ + '//core/api:onos-api', + '//incubator/api:onos-incubator-api', +] + +CORE = UTILS + API + [ + '//core/net:onos-core-net', + '//core/common:onos-core-common', + '//core/store/primitives:onos-core-primitives', + '//core/store/serializers:onos-core-serializers', + '//core/store/dist:onos-core-dist', + '//core/security:onos-security', + '//core/store/persistence:onos-core-persistence', + + '//incubator/net:onos-incubator-net', + '//incubator/store:onos-incubator-store', + '//incubator/rpc:onos-incubator-rpc', + + '//cli:onos-cli', + + '//protocols/rest/api:onos-protocols-rest-api', + '//protocols/rest/ctl:onos-protocols-rest-ctl', + '//protocols/bgp/bgpio:onos-protocols-bgp-bgpio', + '//protocols/bgp/api:onos-protocols-bgp-api', + '//protocols/bgp/ctl:onos-protocols-bgp-ctl', + # '//protocols/bmv2/thrift-api:onos-protocols-bmv2-thrift-api', + '//protocols/netconf/api:onos-protocols-netconf-api', + '//protocols/netconf/ctl:onos-protocols-netconf-ctl', + '//protocols/openflow/api:onos-protocols-openflow-api', + '//protocols/openflow/ctl:onos-protocols-openflow-ctl', + '//protocols/ospf/api:onos-protocols-ospf-api', + '//protocols/ospf/protocol:onos-protocols-ospf-protocol', + '//protocols/ospf/ctl:onos-protocols-ospf-ctl', + '//protocols/ovsdb/rfc:onos-protocols-ovsdb-rfc', + '//protocols/ovsdb/api:onos-protocols-ovsdb-api', + '//protocols/ovsdb/ctl:onos-protocols-ovsdb-ctl', + '//protocols/pcep/pcepio:onos-protocols-pcep-pcepio', + '//protocols/pcep/server/api:onos-protocols-pcep-server-api', + '//protocols/pcep/server/ctl:onos-protocols-pcep-server-ctl', + '//protocols/snmp/api:onos-protocols-snmp-api', + '//protocols/snmp/ctl:onos-protocols-snmp-ctl', + '//protocols/isis/api:onos-protocols-isis-api', + '//protocols/isis/ctl:onos-protocols-isis-ctl', + '//protocols/isis/isisio:onos-protocols-isis-isisio', + '//protocols/lisp/api:onos-protocols-lisp-api', + '//protocols/lisp/ctl:onos-protocols-lisp-ctl', + '//protocols/lisp/msg:onos-protocols-lisp-msg', + '//protocols/tl1/api:onos-protocols-tl1-api', + '//protocols/tl1/ctl:onos-protocols-tl1-ctl', + '//protocols/restconf/client/api:onos-protocols-restconf-client-api', + '//protocols/restconf/client/ctl:onos-protocols-restconf-client-ctl', + '//protocols/xmpp/core/api:onos-protocols-xmpp-core-api', + '//protocols/xmpp/core/ctl:onos-protocols-xmpp-core-ctl', + + '//drivers/utilities:onos-drivers-utilities', + + '//providers/netconf/device:onos-providers-netconf-device', + '//providers/openflow/device:onos-providers-openflow-device', + '//providers/openflow/packet:onos-providers-openflow-packet', + '//providers/openflow/flow:onos-providers-openflow-flow', + '//providers/openflow/group:onos-providers-openflow-group', + '//providers/openflow/meter:onos-providers-openflow-meter', + '//providers/ovsdb/device:onos-providers-ovsdb-device', + '//providers/ovsdb/tunnel:onos-providers-ovsdb-tunnel', + '//providers/rest/device:onos-providers-rest-device', + '//providers/snmp/device:onos-providers-snmp-device', + '//providers/isis/cfg:onos-providers-isis-cfg', + '//providers/isis/topology:onos-providers-isis-topology', + '//providers/lisp/device:onos-providers-lisp-device', + '//providers/tl1/device:onos-providers-tl1-device', + '//providers/general/device:onos-providers-general-device', + # '//providers/p4runtime/packet:onos-providers-p4runtime-packet', + + '//web/api:onos-rest', + # '//web/gui2:onos-gui2', + '//web/gui:onos-gui', + + '//incubator/protobuf/models:onos-incubator-protobuf-models', + '//incubator/protobuf/services/nb:onos-incubator-protobuf-services-nb', +] + +ONOS_DRIVERS = [ + # Drivers + '//drivers/default:onos-drivers-default-oar', + '//drivers/arista:onos-drivers-arista-oar', + '//drivers/ciena/waveserver:onos-drivers-ciena-waveserver-oar', + '//drivers/ciena/c5162:onos-drivers-ciena-c5162-oar', + '//drivers/ciena/c5170:onos-drivers-ciena-c5170-oar', + '//drivers/ciena/waveserverai:onos-drivers-ciena-waveserverai-oar', + '//drivers/cisco/netconf:onos-drivers-cisco-netconf-oar', + '//drivers/cisco/rest:onos-drivers-cisco-rest-oar', + '//drivers/corsa:onos-drivers-corsa-oar', + '//drivers/fujitsu:onos-drivers-fujitsu-oar', + '//drivers/lumentum:onos-drivers-lumentum-oar', + '//drivers/netconf:onos-drivers-netconf-oar', + '//drivers/server:onos-drivers-server-oar', + '//drivers/optical:onos-drivers-optical-oar', + '//drivers/ovsdb:onos-drivers-ovsdb-oar', + '//drivers/juniper:onos-drivers-juniper-oar', + '//drivers/lisp:onos-drivers-lisp-oar', + '//drivers/flowspec:onos-drivers-flowspec-oar', + '//drivers/huawei:onos-drivers-huawei-oar', + '//drivers/microsemi/ea1000:onos-drivers-microsemi-ea1000-oar', + '//drivers/oplink:onos-drivers-oplink-oar', + # '//drivers/bmv2:onos-drivers-bmv2-oar', + # '//drivers/barefoot:onos-drivers-barefoot-oar', + # '//drivers/mellanox:onos-drivers-mellanox-oar', + '//drivers/hp:onos-drivers-hp-oar', + # '//drivers/p4runtime:onos-drivers-p4runtime-oar', + # '//drivers/gnmi:onos-drivers-gnmi-oar', + '//drivers/polatis/netconf:onos-drivers-polatis-netconf-oar', + '//drivers/polatis/openflow:onos-drivers-polatis-openflow-oar', + '//drivers/polatis/snmp:onos-drivers-polatis-snmp-oar', + '//drivers/odtn-driver:onos-drivers-odtn-driver-oar', +] + +ONOS_PROVIDERS = [ + # Providers + '//providers/bgp:onos-providers-bgp-oar', + '//providers/bgpcep:onos-providers-bgpcep-oar', + '//providers/host:onos-providers-host-oar', + '//providers/hostprobing:onos-providers-hostprobing-oar', + '//providers/lldp:onos-providers-lldp-oar', + '//providers/netcfghost:onos-providers-netcfghost-oar', + '//providers/netcfglinks:onos-providers-netcfglinks-oar', + '//providers/netconf:onos-providers-netconf-oar', + '//providers/openflow/message:onos-providers-openflow-message-oar', + '//providers/ovsdb:onos-providers-ovsdb-oar', + '//providers/ovsdb/host:onos-providers-ovsdb-host-oar', + '//providers/ovsdb/base:onos-providers-ovsdb-base-oar', + '//providers/pcep:onos-providers-pcep-oar', + '//providers/null:onos-providers-null-oar', + '//providers/openflow/base:onos-providers-openflow-base-oar', + '//providers/openflow/app:onos-providers-openflow-app-oar', + '//providers/rest:onos-providers-rest-oar', + '//providers/isis:onos-providers-isis-oar', + '//providers/snmp:onos-providers-snmp-oar', + '//providers/link:onos-providers-link-oar', + '//providers/lisp:onos-providers-lisp-oar', + '//providers/tl1:onos-providers-tl1-oar', + '//providers/general:onos-providers-general-oar', + # '//providers/p4runtime:onos-providers-p4runtime-oar', +# '//providers/ietfte:onos-providers-ietfte-oar', + '//providers/xmpp/device:onos-providers-xmpp-device-oar', +] + +ONOS_APPS = [ + # Apps + '//apps/dhcp:onos-apps-dhcp-oar', + '//apps/dhcprelay:onos-apps-dhcprelay-oar', + '//apps/fwd:onos-apps-fwd-oar', + '//apps/packet-stats:onos-apps-packet-stats-oar', + '//apps/acl:onos-apps-acl-oar', + '//apps/bgprouter:onos-apps-bgprouter-oar', + '//apps/cip:onos-apps-cip-oar', + '//apps/drivermatrix:onos-apps-drivermatrix-oar', + '//apps/events:onos-apps-events-oar', + '//apps/proxyarp:onos-apps-proxyarp-oar', + '//apps/segmentrouting:onos-apps-segmentrouting-oar', + '//apps/gangliametrics:onos-apps-gangliametrics-oar', + '//apps/graphitemetrics:onos-apps-graphitemetrics-oar', + '//apps/flowanalyzer:onos-apps-flowanalyzer-oar', + '//apps/intentsync:onos-apps-intentsync-oar', + '//apps/influxdbmetrics:onos-apps-influxdbmetrics-oar', + '//apps/metrics:onos-apps-metrics-oar', + '//apps/mfwd:onos-apps-mfwd-oar', + '//apps/mlb:onos-apps-mlb-oar', + '//apps/openstacknetworking:onos-apps-openstacknetworking-oar', + '//apps/mobility:onos-apps-mobility-oar', + '//apps/newoptical:onos-apps-newoptical-oar', + '//apps/optical-model:onos-apps-optical-model-oar', + '//apps/optical-rest:onos-apps-optical-rest-oar', + '//apps/pathpainter:onos-apps-pathpainter-oar', + '//apps/pcep-api:onos-apps-pcep-api-oar', + '//apps/pim:onos-apps-pim-oar', + '//apps/linkprops:onos-apps-linkprops-oar', + '//apps/reactive-routing:onos-apps-reactive-routing-oar', + '//apps/roadm:onos-apps-roadm-oar', + '//apps/sdnip:onos-apps-sdnip-oar', + '//apps/test/cluster-ha:onos-apps-test-cluster-ha-oar', + '//apps/test/demo:onos-apps-test-demo-oar', + '//apps/test/distributed-primitives:onos-apps-test-distributed-primitives-oar', + '//apps/test/election:onos-apps-test-election-oar', + '//apps/test/flow-perf:onos-apps-test-flow-perf-oar', + '//apps/test/intent-perf:onos-apps-test-intent-perf-oar', + '//apps/test/route-scale:onos-apps-test-route-scale-oar', + '//apps/test/loadtest:onos-apps-test-loadtest-oar', + '//apps/test/netcfg-monitor:onos-apps-test-netcfg-monitor-oar', + '//apps/test/messaging-perf:onos-apps-test-messaging-perf-oar', + '//apps/test/primitive-perf:onos-apps-test-primitive-perf-oar', + '//apps/test/proxy:onos-apps-test-proxy-oar', + '//apps/test/transaction-perf:onos-apps-test-transaction-perf-oar', + '//apps/virtualbng:onos-apps-virtualbng-oar', + '//apps/vpls:onos-apps-vpls-oar', + '//apps/vrouter:onos-apps-vrouter-oar', + '//apps/routing/fibinstaller:onos-apps-routing-fibinstaller-oar', + '//apps/routing/cpr:onos-apps-routing-cpr-oar', + '//apps/routing/fpm:onos-apps-routing-fpm-oar', + '//apps/vtn:onos-apps-vtn-oar', + '//apps/faultmanagement:onos-apps-faultmanagement-oar', + '//apps/openstacknode:onos-apps-openstacknode-oar', + '//apps/cpman/app:onos-apps-cpman-app-oar', + '//apps/scalablegateway:onos-apps-scalablegateway-oar', + '//apps/castor:onos-apps-castor-oar', +# '//apps/yms:onos-apps-yms-oar', + '//apps/ofagent:onos-apps-ofagent-oar', + '//apps/mappingmanagement:onos-apps-mappingmanagement-oar', + '//apps/config:onos-apps-config-oar', + '//apps/configsync:onos-apps-configsync-oar', + '//apps/configsync-netconf:onos-apps-configsync-netconf-oar', + '//apps/netconf/client:onos-apps-netconf-client-oar', + '//apps/tetopology:onos-apps-tetopology-oar', + '//apps/tetunnel:onos-apps-tetunnel-oar', +# '//apps/tenbi/yangmodel:onos-apps-tenbi-yangmodel-feature', +# '//apps/tenbi:onos-apps-tenbi-oar', + '//protocols/restconf/server:onos-protocols-restconf-server-oar', + '//apps/restconf:onos-apps-restconf-oar', + '//apps/flowspec-api:onos-apps-flowspec-api-oar', + '//apps/yang:onos-apps-yang-oar', + '//apps/yang-gui:onos-apps-yang-gui-oar', + '//apps/cord-support:onos-apps-cord-support-oar', + '//apps/network-troubleshoot:onos-apps-network-troubleshoot-oar', + '//apps/l3vpn:onos-apps-l3vpn-oar', + '//apps/openroadm:onos-apps-openroadm-oar', + '//apps/artemis:onos-apps-artemis-oar', + '//apps/pi-demo/ecmp:onos-apps-pi-demo-ecmp-oar', + '//apps/gluon:onos-apps-gluon-oar', + '//apps/evpnopenflow:onos-apps-evpnopenflow-oar', + '//apps/route-service:onos-apps-route-service-oar', + '//apps/evpn-route-service:onos-apps-evpn-route-service-oar', + '//incubator/protobuf/registry:onos-incubator-protobuf-registry-oar', + '//incubator/protobuf/services/nb:onos-incubator-protobuf-services-nb-oar', + '//apps/openstacknetworkingui:onos-apps-openstacknetworkingui-oar', + '//apps/openstacktelemetry:onos-apps-openstacktelemetry-oar', + '//apps/openstacktroubleshoot:onos-apps-openstacktroubleshoot-oar', + '//apps/openstackvtap:onos-apps-openstackvtap-oar', + # '//apps/p4-tutorial/pipeconf:onos-apps-p4-tutorial-pipeconf-oar', + # '//apps/p4-tutorial/mytunnel:onos-apps-p4-tutorial-mytunnel-oar', + '//apps/cfm:onos-apps-cfm-oar', + '//apps/routeradvertisement:onos-apps-routeradvertisement-oar', + '//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/rabbitmq:onos-apps-rabbitmq-oar', + '//apps/odtn/api:onos-apps-odtn-api-oar', + '//apps/odtn/service:onos-apps-odtn-service-oar', + '//apps/mcast:onos-apps-mcast-oar', + '//apps/layout:onos-apps-layout-oar', + '//apps/imr:onos-apps-imr-oar', + '//apps/inbandtelemetry/app:onos-apps-inbandtelemetry-app-oar', + '//apps/workflow:onos-apps-workflow-oar', + # nodemetrics application + '//apps/nodemetrics:onos-apps-nodemetrics-oar', + #'//web/gui2:onos-web-gui2-oar', +] + +PROTOCOL_APPS = [ + # '//protocols/grpc:onos-protocols-grpc-oar', + # '//protocols/p4runtime:onos-protocols-p4runtime-oar', + #'//protocols/gnmi:onos-protocols-gnmi-oar', + '//protocols/xmpp/core:onos-protocols-xmpp-core-oar', + '//protocols/xmpp/pubsub:onos-protocols-xmpp-pubsub-oar', +] + +MODELS = [ + '//models/ietf:onos-models-ietf-oar', + '//models/common:onos-models-common-oar', + '//models/huawei:onos-models-huawei-oar', + '//models/openconfig:onos-models-openconfig-oar', + '//models/openconfig-infinera:onos-models-openconfig-infinera-oar', + '//models/openroadm:onos-models-openroadm-oar', + '//models/tapi:onos-models-tapi-oar', + '//models/l3vpn:onos-models-l3vpn-oar', + '//models/microsemi:onos-models-microsemi-oar', + '//models/polatis:onos-models-polatis-oar', + '//models/ciena/waveserverai:onos-models-ciena-waveserverai-oar', +] + +PIPELINES = [ + # '//pipelines/basic:onos-pipelines-basic-oar', + # '//pipelines/fabric:onos-pipelines-fabric-oar', +] + +APP_JARS = [ + '//apps/cpman/api:onos-apps-cpman-api', + '//apps/routing-api:onos-apps-routing-api', + '//apps/dhcp/api:onos-apps-dhcp-api', + '//apps/dhcp/app:onos-apps-dhcp-app', + '//apps/imr/api:onos-apps-imr-api', + '//apps/imr/app:onos-apps-imr-app', + '//apps/dhcprelay:onos-apps-dhcprelay', + '//apps/fwd:onos-apps-fwd', + '//apps/iptopology-api:onos-apps-iptopology-api', + '//apps/routing/common:onos-apps-routing-common', + '//apps/vtn/vtnrsc:onos-apps-vtn-vtnrsc', + '//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', +] + +FEATURES = [ + '//tools/package/features:onos-thirdparty-base', + '//tools/package/features:onos-thirdparty-web', + '//tools/package/features:onos-api', + '//tools/package/features:onos-core', + '//tools/package/features:onos-incubator', + '//tools/package/features:onos-rest', + '//tools/package/features:onos-gui', + #'//tools/package/features:onos-gui2', + '//tools/package/features:onos-cli', + '//tools/package/features:onos-security', +] + +APPS = ONOS_DRIVERS + ONOS_PROVIDERS + ONOS_APPS + MODELS + PIPELINES \ + + PROTOCOL_APPS diff --git a/protocols/gnmi/BUILD b/protocols/gnmi/BUILD index 30599ae05f..8a3510d054 100644 --- a/protocols/gnmi/BUILD +++ b/protocols/gnmi/BUILD @@ -1,6 +1,5 @@ BUNDLES = [ - "//protocols/gnmi/stub:gnmi_java_grpc", - "//protocols/gnmi/stub:gnmi_java_proto", + "//protocols/gnmi/stub:onos-protocols-gnmi-stub", ] onos_app( diff --git a/protocols/gnmi/stub/BUILD b/protocols/gnmi/stub/BUILD index 3b1a2dc0c1..cf7926594b 100644 --- a/protocols/gnmi/stub/BUILD +++ b/protocols/gnmi/stub/BUILD @@ -1,43 +1,14 @@ -load("//tools/build/bazel:osgi_java_library.bzl", "wrapped_osgi_jar") -load("@io_grpc_grpc_java//:java_grpc_library.bzl", "java_grpc_library") +load("//tools/build/bazel:osgi_java_library.bzl", "osgi_proto_jar") -wrapped_osgi_jar( - name = "gnmi_java_grpc", - jar = ":gnmi_java_grpc_native", - visibility = ["//visibility:public"], +PROTOS = [ + "@com_github_openconfig_gnmi//:gnmi_proto", + "@com_github_openconfig_gnmi//:gnmi_ext_proto", +] + +osgi_proto_jar( + grpc_proto_lib = "@com_github_openconfig_gnmi//:gnmi_proto", + proto_libs = PROTOS, deps = [ - "@io_grpc_grpc_java//core", - "@io_grpc_grpc_java//protobuf", - "@io_grpc_grpc_java//stub", - ], -) - -wrapped_osgi_jar( - name = "gnmi_java_proto", - jar = ":gnmi_java_proto_native", - visibility = ["//visibility:public"], - deps = [ - "@com_google_protobuf//:protobuf_java", - ], -) - -java_proto_library( - name = "gnmi_java_proto_native", - visibility = ["//visibility:public"], - deps = [":gnmi_proto"], -) - -java_grpc_library( - name = "gnmi_java_grpc_native", - srcs = [":gnmi_proto"], - deps = [":gnmi_java_proto_native"], -) - -proto_library( - name = "gnmi_proto", - srcs = ["src/main/proto/gnmi.proto"], - deps = [ - "@com_google_protobuf//:any_proto", - "@com_google_protobuf//:descriptor_proto", + "@com_google_api_grpc_proto_google_common_protos//jar", ], ) diff --git a/protocols/gnmi/stub/src/main/proto/COMMIT_ID b/protocols/gnmi/stub/src/main/proto/COMMIT_ID deleted file mode 100644 index acf773de9c..0000000000 --- a/protocols/gnmi/stub/src/main/proto/COMMIT_ID +++ /dev/null @@ -1,2 +0,0 @@ -https://github.com/openconfig/gnmi/blob/master/proto/gnmi/gnmi.proto -9c8d9e965b3e854107ea02c12ab11b70717456f2 diff --git a/protocols/gnmi/stub/src/main/proto/gnmi.proto b/protocols/gnmi/stub/src/main/proto/gnmi.proto deleted file mode 100644 index 1f3bb7cd05..0000000000 --- a/protocols/gnmi/stub/src/main/proto/gnmi.proto +++ /dev/null @@ -1,423 +0,0 @@ -// -// Copyright 2016 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -syntax = "proto3"; - -import "google/protobuf/any.proto"; -import "google/protobuf/descriptor.proto"; - -// Package gNMI defines a service specification for the gRPC Network Management -// Interface. This interface is defined to be a standard interface via which -// a network management system ("client") can subscribe to state values, -// retrieve snapshots of state information, and manipulate the state of a data -// tree supported by a device ("target"). -// -// This document references the gNMI Specification which can be found at -// http://github.com/openconfig/reference/blob/master/rpc/gnmi -package gnmi; - -// Define a protobuf FileOption that defines the gNMI service version. -extend google.protobuf.FileOptions { - // The gNMI service semantic version. - string gnmi_service = 1001; -} - -// gNMI_service is the current version of the gNMI service, returned through -// the Capabilities RPC. -option (gnmi_service) = "0.5.0"; - -service gNMI { - // Capabilities allows the client to retrieve the set of capabilities that - // is supported by the target. This allows the target to validate the - // service version that is implemented and retrieve the set of models that - // the target supports. The models can then be specified in subsequent RPCs - // to restrict the set of data that is utilized. - // Reference: gNMI Specification Section 3.2 - rpc Capabilities(CapabilityRequest) returns (CapabilityResponse); - // Retrieve a snapshot of data from the target. A Get RPC requests that the - // target snapshots a subset of the data tree as specified by the paths - // included in the message and serializes this to be returned to the - // client using the specified encoding. - // Reference: gNMI Specification Section 3.3 - rpc Get(GetRequest) returns (GetResponse); - // Set allows the client to modify the state of data on the target. The - // paths to modified along with the new values that the client wishes - // to set the value to. - // Reference: gNMI Specification Section 3.4 - rpc Set(SetRequest) returns (SetResponse); - // Subscribe allows a client to request the target to send it values - // of particular paths within the data tree. These values may be streamed - // at a particular cadence (STREAM), sent one off on a long-lived channel - // (POLL), or sent as a one-off retrieval (ONCE). - // Reference: gNMI Specification Section 3.5 - rpc Subscribe(stream SubscribeRequest) returns (stream SubscribeResponse); -} - -// Notification is a re-usable message that is used to encode data from the -// target to the client. A Notification carries two types of changes to the data -// tree: -// - Deleted values (delete) - a set of paths that have been removed from the -// data tree. -// - Updated values (update) - a set of path-value pairs indicating the path -// whose value has changed in the data tree. -// Reference: gNMI Specification Section 2.1 -message Notification { - int64 timestamp = 1; // Timestamp in nanoseconds since Epoch. - Path prefix = 2; // Prefix used for paths in the message. - // An alias for the path specified in the prefix field. - // Reference: gNMI Specification Section 2.4.2 - string alias = 3; - repeated Update update = 4; // Data elements that have changed values. - repeated Path delete = 5; // Data elements that have been deleted. -} - -// Update is a re-usable message that is used to store a particular Path, -// Value pair. -// Reference: gNMI Specification Section 2.1 -message Update { - Path path = 1; // The path (key) for the update. - Value value = 2 [deprecated=true]; // The value (value) for the update. - TypedValue val = 3; // The explicitly typed update value. - uint32 duplicates = 4; // Number of coalesced duplicates. -} - -// TypedValue is used to encode a value being sent between the client and -// target (originated by either entity). -message TypedValue { - // One of the fields within the val oneof is populated with the value - // of the update. The type of the value being included in the Update - // determines which field should be populated. In the case that the - // encoding is a particular form of the base protobuf type, a specific - // field is used to store the value (e.g., json_val). - oneof value { - string string_val = 1; // String value. - int64 int_val = 2; // Integer value. - uint64 uint_val = 3; // Unsigned integer value. - bool bool_val = 4; // Bool value. - bytes bytes_val = 5; // Arbitrary byte sequence value. - float float_val = 6; // Floating point value. - Decimal64 decimal_val = 7; // Decimal64 encoded value. - ScalarArray leaflist_val = 8; // Mixed type scalar array value. - google.protobuf.Any any_val = 9; // protobuf.Any encoded bytes. - bytes json_val = 10; // JSON-encoded text. - bytes json_ietf_val = 11; // JSON-encoded text per RFC7951. - string ascii_val = 12; // Arbitrary ASCII text. - } -} - -// Path encodes a data tree path as a series of repeated strings, with -// each element of the path representing a data tree node name and the -// associated attributes. -// Reference: gNMI Specification Section 2.2.2. -message Path { - // Elements of the path are no longer encoded as a string, but rather within - // the elem field as a PathElem message. - repeated string element = 1 [deprecated=true]; - string origin = 2; // Label to disambiguate path. - repeated PathElem elem = 3; // Elements of the path. - string target = 4; // The name of the target - // (Sec. 2.2.2.1) -} - -// PathElem encodes an element of a gNMI path, along ith any attributes (keys) -// that may be associated with it. -// Reference: gNMI Specification Section 2.2.2. -message PathElem { - string name = 1; // The name of the element in the path. - map key = 2; // Map of key (attribute) name to value. -} - -// Value encodes a data tree node's value - along with the way in which -// the value is encoded. This message is deprecated by gNMI 0.3.0. -// Reference: gNMI Specification Section 2.2.3. -message Value { - option deprecated = true; - bytes value = 1; // Value of the variable being transmitted. - Encoding type = 2; // Encoding used for the value field. -} - -// Encoding defines the value encoding formats that are supported by the gNMI -// protocol. These encodings are used by both the client (when sending Set -// messages to modify the state of the target) and the target when serializing -// data to be returned to the client (in both Subscribe and Get RPCs). -// Reference: gNMI Specification Section 2.3 -enum Encoding { - JSON = 0; // JSON encoded text. - BYTES = 1; // Arbitrarily encoded bytes. - PROTO = 2; // Encoded according to out-of-band agreed Protobuf. - ASCII = 3; // ASCII text of an out-of-band agreed format. - JSON_IETF = 4; // JSON encoded text as per RFC7951. -} - -// Error message previously utilised to return errors to the client. Deprecated -// in favour of using the google.golang.org/genproto/googleapis/rpc/status -// message in the RPC response. -// Reference: gNMI Specification Section 2.5 -message Error { - option deprecated = true; - uint32 code = 1; // Canonical gRPC error code. - string message = 2; // Human readable error. - google.protobuf.Any data = 3; // Optional additional information. -} - -// Decimal64 is used to encode a fixed precision decimal number. The value -// is expressed as a set of digits with the precision specifying the -// number of digits following the decimal point in the digit set. -message Decimal64 { - int64 digits = 1; // Set of digits. - uint32 precision = 2; // Number of digits following the decimal point. -} - -// ScalarArray is used to encode a mixed-type array of values. -message ScalarArray { - // The set of elements within the array. Each TypedValue message should - // specify only elements that have a field identifier of 1-7 (i.e., the - // values are scalar values). - repeated TypedValue element = 1; -} - -// SubscribeRequest is the message sent by the client to the target when -// initiating a subscription to a set of paths within the data tree. The -// request field must be populated and the initial message must specify a -// SubscriptionList to initiate a subscription. The message is subsequently -// used to define aliases or trigger polled data to be sent by the target. -// Reference: gNMI Specification Section 3.5.1.1 -message SubscribeRequest { - oneof request { - SubscriptionList subscribe = 1; // Specify the paths within a subscription. - Poll poll = 3; // Trigger a polled update. - AliasList aliases = 4; // Aliases to be created. - } -} - -// Poll is sent within a SubscribeRequest to trigger the device to -// send telemetry updates for the paths that are associated with the -// subscription. -// Reference: gNMI Specification Section Section 3.5.1.4 -message Poll { -} - -// SubscribeResponse is the message used by the target within a Subscribe RPC. -// The target includes a Notification message which is used to transmit values -// of the path(s) that are associated with the subscription. The same message -// is to indicate that the target has sent all data values once (is -// synchronized). -// Reference: gNMI Specification Section 3.5.1.4 -message SubscribeResponse { - oneof response { - Notification update = 1; // Changed or sampled value for a path. - // Indicate target has sent all values associated with the subscription - // at least once. - bool sync_response = 3; - // Deprecated in favour of google.golang.org/genproto/googleapis/rpc/status - Error error = 4 [deprecated=true]; - } -} - -// SubscriptionList is used within a Subscribe message to specify the list of -// paths that the client wishes to subscribe to. The message consists of a -// list of (possibly prefixed) paths, and options that relate to the -// subscription. -// Reference: gNMI Specification Section 3.5.1.2 -message SubscriptionList { - Path prefix = 1; // Prefix used for paths. - repeated Subscription subscription = 2; // Set of subscriptions to create. - // Whether target defined aliases are allowed within the subscription. - bool use_aliases = 3; - QOSMarking qos = 4; // DSCP marking to be used. - // Mode of the subscription. - enum Mode { - STREAM = 0; // Values streamed by the target (Sec. 3.5.1.5.2). - ONCE = 1; // Values sent once-off by the target (Sec. 3.5.1.5.1). - POLL = 2; // Values sent in response to a poll request (Sec. 3.5.1.5.3). - } - Mode mode = 5; - // Whether elements of the schema that are marked as eligible for aggregation - // should be aggregated or not. - bool allow_aggregation = 6; - // The set of schemas that define the elements of the data tree that should - // be sent by the target. - repeated ModelData use_models = 7; - // The encoding that the target should use within the Notifications generated - // corresponding to the SubscriptionList. - Encoding encoding = 8; - // An optional field to specify that only updates to current state should be - // sent to a client. If set, the initial state is not sent to the client but - // rather only the sync message followed by any subsequent updates to the - // current state. For ONCE and POLL modes, this causes the server to send only - // the sync message (Sec. 3.5.2.3). - bool updates_only = 9; -} - -// Subscription is a single request within a SubscriptionList. The path -// specified is interpreted (along with the prefix) as the elements of the data -// tree that the client is subscribing to. The mode determines how the target -// should trigger updates to be sent. -// Reference: gNMI Specification Section 3.5.1.3 -message Subscription { - Path path = 1; // The data tree path. - SubscriptionMode mode = 2; // Subscription mode to be used. - uint64 sample_interval = 3; // ns between samples in SAMPLE mode. - // Indicates whether values that not changed should be sent in a SAMPLE - // subscription. - bool suppress_redundant = 4; - // Specifies the maximum allowable silent period in nanoseconds when - // suppress_redundant is in use. The target should send a value at least once - // in the period specified. - uint64 heartbeat_interval = 5; -} - -// SubscriptionMode is the mode of the subscription, specifying how the -// target must return values in a subscription. -// Reference: gNMI Specification Section 3.5.1.3 -enum SubscriptionMode { - TARGET_DEFINED = 0; // The target selects the relevant mode for each element. - ON_CHANGE = 1; // The target sends an update on element value change. - SAMPLE = 2; // The target samples values according to the interval. -} - -// QOSMarking specifies the DSCP value to be set on transmitted telemetry -// updates from the target. -// Reference: gNMI Specification Section 3.5.1.2 -message QOSMarking { - uint32 marking = 1; -} - -// Alias specifies a data tree path, and an associated string which defines an -// alias which is to be used for this path in the context of the RPC. The alias -// is specified as a string which is prefixed with "#" to disambiguate it from -// data tree element paths. -// Reference: gNMI Specification Section 2.4.2 -message Alias { - Path path = 1; // The path to be aliased. - string alias = 2; // The alias value, a string prefixed by "#". -} - -// AliasList specifies a list of aliases. It is used in a SubscribeRequest for -// a client to create a set of aliases that the target is to utilize. -// Reference: gNMI Specification Section 3.5.1.6 -message AliasList { - repeated Alias alias = 1; // The set of aliases to be created. -} - -// SetRequest is sent from a client to the target to update values in the data -// tree. Paths are either deleted by the client, or modified by means of being -// updated, or replaced. Where a replace is used, unspecified values are -// considered to be replaced, whereas when update is used the changes are -// considered to be incremental. The set of changes that are specified within -// a single SetRequest are considered to be a transaction. -// Reference: gNMI Specification Section 3.4.1 -message SetRequest { - Path prefix = 1; // Prefix used for paths in the message. - repeated Path delete = 2; // Paths to be deleted from the data tree. - repeated Update replace = 3; // Updates specifying elements to be replaced. - repeated Update update = 4; // Updates specifying elements to updated. -} - -// SetResponse is the response to a SetRequest, sent from the target to the -// client. It reports the result of the modifications to the data tree that were -// specified by the client. Errors for this RPC should be reported using the -// https://github.com/googleapis/googleapis/blob/master/google/rpc/status.proto -// message in the RPC return. The gnmi.Error message can be used to add additional -// details where required. -// Reference: gNMI Specification Section 3.4.2 -message SetResponse { - Path prefix = 1; // Prefix used for paths. - // A set of responses specifying the result of the operations specified in - // the SetRequest. - repeated UpdateResult response = 2; - Error message = 3 [deprecated=true]; // The overall status of the transaction. - int64 timestamp = 4; // Timestamp of transaction (ns since epoch). -} - -// UpdateResult is used within the SetResponse message to communicate the -// result of an operation specified within a SetRequest message. -// Reference: gNMI Specification Section 3.4.2 -message UpdateResult { - // The operation that was associated with the Path specified. - enum Operation { - INVALID = 0; - DELETE = 1; // The result relates to a delete of Path. - REPLACE = 2; // The result relates to a replace of Path. - UPDATE = 3; // The result relates to an update of Path. - } - // Deprecated timestamp for the UpdateResult, this field has been - // replaced by the timestamp within the SetResponse message, since - // all mutations effected by a set should be applied as a single - // transaction. - int64 timestamp = 1 [deprecated=true]; - Path path = 2; // Path associated with the update. - Error message = 3 [deprecated=true]; // Status of the update operation. - Operation op = 4; // Update operation type. -} - -// GetRequest is sent when a client initiates a Get RPC. It is used to specify -// the set of data elements for which the target should return a snapshot of -// data. The use_models field specifies the set of schema modules that are to -// be used by the target - where use_models is not specified then the target -// must use all schema models that it has. -// Reference: gNMI Specification Section 3.3.1 -message GetRequest { - Path prefix = 1; // Prefix used for paths. - repeated Path path = 2; // Paths requested by the client. - // Type of elements within the data tree. - enum DataType { - ALL = 0; // All data elements. - CONFIG = 1; // Config (rw) only elements. - STATE = 2; // State (ro) only elements. - // Data elements marked in the schema as operational. This refers to data - // elements whose value relates to the state of processes or interactions - // running on the device. - OPERATIONAL = 3; - } - DataType type = 3; // The type of data being requested. - Encoding encoding = 5; // Encoding to be used. - repeated ModelData use_models = 6; // The schema models to be used. -} - -// GetResponse is used by the target to respond to a GetRequest from a client. -// The set of Notifications corresponds to the data values that are requested -// by the client in the GetRequest. -// Reference: gNMI Specification Section 3.3.2 -message GetResponse { - repeated Notification notification = 1; // Data values. - Error error = 2 [deprecated=true]; // Errors that occurred in the Get. -} - -// CapabilityRequest is sent by the client in the Capabilities RPC to request -// that the target reports its capabilities. -// Reference: gNMI Specification Section 3.2.1 -message CapabilityRequest { -} - -// CapabilityResponse is used by the target to report its capabilities to the -// client within the Capabilities RPC. -// Reference: gNMI Specification Section 3.2.2 -message CapabilityResponse { - repeated ModelData supported_models = 1; // Supported schema models. - repeated Encoding supported_encodings = 2; // Supported encodings. - string gNMI_version = 3; // Supported gNMI version. -} - -// ModelData is used to describe a set of schema modules. It can be used in a -// CapabilityResponse where a target reports the set of modules that it -// supports, and within the SubscribeRequest and GetRequest messages to specify -// the set of models from which data tree elements should be reported. -// Reference: gNMI Specification Section 3.2.3 -message ModelData { - string name = 1; // Name of the model. - string organization = 2; // Organization publishing the model. - string version = 3; // Semantic version of the model. -} diff --git a/tools/build/bazel/gnmi_BUILD b/tools/build/bazel/gnmi_BUILD new file mode 100644 index 0000000000..43cb693cba --- /dev/null +++ b/tools/build/bazel/gnmi_BUILD @@ -0,0 +1,17 @@ +proto_library( + name = "gnmi_proto", + srcs = ["gnmi/gnmi.proto"], + deps = [ + ":gnmi_ext_proto", + "@com_google_protobuf//:descriptor_proto", + "@com_google_protobuf//:any_proto", + ], + visibility = ["//visibility:public"], +) + + +proto_library( + name = "gnmi_ext_proto", + srcs = ["gnmi_ext/gnmi_ext.proto"], + visibility = ["//visibility:public"], +) diff --git a/tools/build/bazel/gnmi_workspace.bzl b/tools/build/bazel/gnmi_workspace.bzl new file mode 100644 index 0000000000..6b0d4db9ec --- /dev/null +++ b/tools/build/bazel/gnmi_workspace.bzl @@ -0,0 +1,16 @@ +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +# FIXME: Currently gNMI proto file uses incorrect path to import "gnmi_ext.proto" +# Temporary use patch from ONF before gNMI team fix it. + +GNMI_COMMIT = "onos" +GNMI_SHA = "0c4d5f168cb142f8135171204dac3ff8840a147f51fa361079f42fa585bec2ce" + +def generate_gnmi(): + http_archive( + name = "com_github_openconfig_gnmi", + urls = ["https://github.com/opennetworkinglab/gnmi/archive/%s.zip" % GNMI_COMMIT], + sha256 = GNMI_SHA, + strip_prefix = "gnmi-%s/proto" % GNMI_COMMIT, + build_file = "//tools/build/bazel:gnmi_BUILD", + )