Merge branch 'master' into merge
Change-Id: I163ecf699b554e33f4db938c66b73c9911e51135
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/DistributedSecurityGroupStore.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/DistributedSecurityGroupStore.java
index ec12967..f4fbf52 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/DistributedSecurityGroupStore.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/DistributedSecurityGroupStore.java
@@ -171,7 +171,7 @@
event.newValue().value()));
break;
case REMOVE:
- log.debug("OpenStack security group removed {}", event.newValue());
+ log.debug("OpenStack security group removed {}", event.oldValue());
eventExecutor.execute(() ->
notifyDelegate(new OpenstackSecurityGroupEvent(
OPENSTACK_SECURITY_GROUP_REMOVED,
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 a6f54bd..8c45d4c 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
@@ -45,15 +45,18 @@
import org.onosproject.net.packet.PacketService;
import org.onosproject.openstacknetworking.api.Constants;
import org.onosproject.openstacknetworking.api.InstancePort;
+import org.onosproject.openstacknetworking.api.InstancePortAdminService;
import org.onosproject.openstacknetworking.api.InstancePortEvent;
import org.onosproject.openstacknetworking.api.InstancePortListener;
-import org.onosproject.openstacknetworking.api.InstancePortService;
import org.onosproject.openstacknetworking.api.OpenstackFlowRuleService;
import org.onosproject.openstacknetworking.api.OpenstackNetworkAdminService;
+import org.onosproject.openstacknetworking.api.OpenstackNetworkEvent;
+import org.onosproject.openstacknetworking.api.OpenstackNetworkListener;
import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
import org.onosproject.openstacknetworking.api.OpenstackRouterEvent;
import org.onosproject.openstacknetworking.api.OpenstackRouterListener;
import org.onosproject.openstacknetworking.api.OpenstackRouterService;
+import org.onosproject.openstacknetworking.api.PreCommitPortService;
import org.onosproject.openstacknode.api.OpenstackNode;
import org.onosproject.openstacknode.api.OpenstackNodeEvent;
import org.onosproject.openstacknode.api.OpenstackNodeListener;
@@ -61,6 +64,7 @@
import org.openstack4j.model.network.ExternalGateway;
import org.openstack4j.model.network.IP;
import org.openstack4j.model.network.NetFloatingIP;
+import org.openstack4j.model.network.Port;
import org.openstack4j.model.network.Router;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
@@ -87,6 +91,7 @@
import static org.onosproject.openstacknetworking.api.Constants.OPENSTACK_NETWORKING_APP_ID;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ARP_CONTROL_RULE;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ARP_GATEWAY_RULE;
+import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_PORT_PRE_REMOVE;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.associatedFloatingIp;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getGwByComputeDevId;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getGwByInstancePort;
@@ -124,7 +129,7 @@
protected OpenstackNodeService osNodeService;
@Reference(cardinality = ReferenceCardinality.MANDATORY)
- protected InstancePortService instancePortService;
+ protected InstancePortAdminService instancePortService;
@Reference(cardinality = ReferenceCardinality.MANDATORY)
protected ClusterService clusterService;
@@ -141,6 +146,9 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY)
protected ComponentConfigService configService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected PreCommitPortService preCommitPortService;
+
//@Property(name = ARP_MODE, value = DEFAULT_ARP_MODE_STR,
// label = "ARP processing mode, broadcast | proxy (default)")
protected String arpMode = DEFAULT_ARP_MODE_STR;
@@ -150,6 +158,7 @@
private final OpenstackRouterListener osRouterListener = new InternalRouterEventListener();
private final OpenstackNodeListener osNodeListener = new InternalNodeEventListener();
private final InstancePortListener instPortListener = new InternalInstancePortListener();
+ private final OpenstackNetworkListener osNetworkListener = new InternalNetworkEventListener();
private ApplicationId appId;
private NodeId localNodeId;
@@ -166,6 +175,7 @@
localNodeId = clusterService.getLocalNode().id();
osRouterService.addListener(osRouterListener);
osNodeService.addListener(osNodeListener);
+ osNetworkService.addListener(osNetworkListener);
instancePortService.addListener(instPortListener);
leadershipService.runForLeadership(appId.name());
packetService.addProcessor(packetProcessor, PacketProcessor.director(1));
@@ -178,6 +188,7 @@
instancePortService.removeListener(instPortListener);
osRouterService.removeListener(osRouterListener);
osNodeService.removeListener(osNodeListener);
+ osNetworkService.removeListener(osNetworkListener);
instancePortService.removeListener(instPortListener);
leadershipService.withdraw(appId.name());
eventExecutor.shutdown();
@@ -433,9 +444,9 @@
return;
}
- if (portId == null || fip.getPortId() == null) {
+ if (portId == null || (install && fip.getPortId() == null)) {
log.trace("Unknown target ARP request for {}, ignore it",
- fip.getFloatingIpAddress());
+ fip.getFloatingIpAddress());
return;
}
@@ -448,6 +459,16 @@
return;
}
+ if (install) {
+ preCommitPortService.subscribePreCommit(instPort.portId(),
+ OPENSTACK_PORT_PRE_REMOVE, this.getClass().getName());
+ log.info("Subscribed the port {} on listening pre-remove event", instPort.portId());
+ } else {
+ preCommitPortService.unsubscribePreCommit(instPort.portId(),
+ OPENSTACK_PORT_PRE_REMOVE, instancePortService, this.getClass().getName());
+ log.info("Unsubscribed the port {} on listening pre-remove event", instPort.portId());
+ }
+
setArpRule(fip, targetMac, gw, install);
}
}
@@ -486,8 +507,8 @@
}
}
- private void setFakeGatewayArpRule(Router router, boolean install) {
- setFakeGatewayArpRule(router.getExternalGatewayInfo(), install);
+ private void setFakeGatewayArpRuleByRouter(Router router, boolean install) {
+ setFakeGatewayArpRuleByGateway(router.getExternalGatewayInfo(), install);
}
private Set<IP> getExternalGatewaySnatIps(ExternalGateway extGw) {
@@ -500,47 +521,89 @@
.collect(Collectors.toSet());
}
- private void setFakeGatewayArpRule(ExternalGateway extGw, boolean install) {
+ private void setFakeGatewayArpRuleByGateway(ExternalGateway extGw, boolean install) {
if (ARP_BROADCAST_MODE.equals(getArpMode())) {
if (extGw == null) {
return;
}
- Set<IP> ips = getExternalGatewaySnatIps(extGw);
+ setFakeGatewayArpRuleByIps(getExternalGatewaySnatIps(extGw), install);
+ }
+ }
- ips.forEach(ip -> {
- TrafficSelector selector = DefaultTrafficSelector.builder()
- .matchEthType(EthType.EtherType.ARP.ethType().toShort())
- .matchArpOp(ARP.OP_REQUEST)
- .matchArpTpa(Ip4Address.valueOf(ip.getIpAddress()))
- .build();
+ private void setFakeGatewayArpRuleByIps(Set<IP> ips, boolean install) {
+ ips.forEach(ip -> {
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchEthType(EthType.EtherType.ARP.ethType().toShort())
+ .matchArpOp(ARP.OP_REQUEST)
+ .matchArpTpa(Ip4Address.valueOf(ip.getIpAddress()))
+ .build();
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .setArpOp(ARP.OP_REPLY)
- .setArpSha(MacAddress.valueOf(gatewayMac))
- .setArpSpa(Ip4Address.valueOf(ip.getIpAddress()))
- .setOutput(PortNumber.IN_PORT)
- .build();
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .setArpOp(ARP.OP_REPLY)
+ .setArpSha(MacAddress.valueOf(gatewayMac))
+ .setArpSpa(Ip4Address.valueOf(ip.getIpAddress()))
+ .setOutput(PortNumber.IN_PORT)
+ .build();
- osNodeService.completeNodes(GATEWAY).forEach(n ->
- osFlowRuleService.setRule(
- appId,
- n.intgBridge(),
- selector,
- treatment,
- PRIORITY_ARP_GATEWAY_RULE,
- GW_COMMON_TABLE,
- install
- )
- );
+ osNodeService.completeNodes(GATEWAY).forEach(n ->
+ osFlowRuleService.setRule(
+ appId,
+ n.intgBridge(),
+ selector,
+ treatment,
+ PRIORITY_ARP_GATEWAY_RULE,
+ GW_COMMON_TABLE,
+ install
+ )
+ );
- if (install) {
- log.info("Install ARP Rule for Gateway Snat {}", ip.getIpAddress());
- } else {
- log.info("Uninstall ARP Rule for Gateway Snat {}", ip.getIpAddress());
- }
- });
+ if (install) {
+ log.info("Install ARP Rule for Gateway Snat {}", ip.getIpAddress());
+ } else {
+ log.info("Uninstall ARP Rule for Gateway Snat {}", ip.getIpAddress());
+ }
+ });
+ }
+
+ /**
+ * An internal network event listener, intended to uninstall ARP rules for
+ * routing the packets destined to external gateway.
+ */
+ private class InternalNetworkEventListener implements OpenstackNetworkListener {
+
+ @Override
+ public boolean isRelevant(OpenstackNetworkEvent event) {
+ Port osPort = event.port();
+ if (osPort == null || osPort.getFixedIps() == null) {
+ return false;
+ }
+
+ // do not allow to proceed without leadership
+ NodeId leader = leadershipService.getLeader(appId.name());
+ return Objects.equals(localNodeId, leader) &&
+ DEVICE_OWNER_ROUTER_GW.equals(osPort.getDeviceOwner());
+ }
+
+ @Override
+ public void event(OpenstackNetworkEvent event) {
+ switch (event.type()) {
+ case OPENSTACK_PORT_CREATED:
+ case OPENSTACK_PORT_UPDATED:
+ eventExecutor.execute(() ->
+ setFakeGatewayArpRuleByIps((Set<IP>) event.port().getFixedIps(), true)
+ );
+ break;
+ case OPENSTACK_PORT_REMOVED:
+ eventExecutor.execute(() ->
+ setFakeGatewayArpRuleByIps((Set<IP>) event.port().getFixedIps(), false)
+ );
+ break;
+ default:
+ // do nothing
+ break;
+ }
}
}
@@ -566,25 +629,25 @@
case OPENSTACK_ROUTER_CREATED:
eventExecutor.execute(() ->
// add a router with external gateway
- setFakeGatewayArpRule(event.subject(), true)
+ setFakeGatewayArpRuleByRouter(event.subject(), true)
);
break;
case OPENSTACK_ROUTER_REMOVED:
eventExecutor.execute(() ->
// remove a router with external gateway
- setFakeGatewayArpRule(event.subject(), false)
+ setFakeGatewayArpRuleByRouter(event.subject(), false)
);
break;
case OPENSTACK_ROUTER_GATEWAY_ADDED:
eventExecutor.execute(() ->
// add a gateway manually after adding a router
- setFakeGatewayArpRule(event.externalGateway(), true)
+ setFakeGatewayArpRuleByGateway(event.externalGateway(), true)
);
break;
case OPENSTACK_ROUTER_GATEWAY_REMOVED:
eventExecutor.execute(() ->
// remove a gateway from an existing router
- setFakeGatewayArpRule(event.externalGateway(), false)
+ setFakeGatewayArpRuleByGateway(event.externalGateway(), false)
);
break;
case OPENSTACK_FLOATING_IP_ASSOCIATED:
@@ -807,7 +870,7 @@
osRouterService.routers().stream()
.filter(router -> router.getExternalGatewayInfo() != null)
- .forEach(router -> setFakeGatewayArpRule(router, install));
+ .forEach(router -> setFakeGatewayArpRuleByRouter(router, install));
}
}
}
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 173b6bf..4423bd3 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
@@ -27,6 +27,7 @@
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
+import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.LeadershipService;
import org.onosproject.cluster.NodeId;
@@ -85,6 +86,7 @@
import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_PORT_PRE_REMOVE;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.associatedFloatingIp;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getGwByComputeDevId;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getPropertyValueAsBoolean;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.isAssociatedWithVM;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.swapStaleLocation;
import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.buildExtension;
@@ -101,6 +103,8 @@
private static final String ERR_FLOW = "Failed set flows for floating IP %s: ";
private static final String ERR_UNSUPPORTED_NET_TYPE = "Unsupported network type %s";
+ private static final String USE_SECURITY_GROUP = "useSecurityGroup";
+
@Reference(cardinality = ReferenceCardinality.MANDATORY)
protected CoreService coreService;
@@ -114,6 +118,9 @@
protected ClusterService clusterService;
@Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected ComponentConfigService componentConfigService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
protected OpenstackNodeService osNodeService;
@Reference(cardinality = ReferenceCardinality.MANDATORY)
@@ -879,14 +886,22 @@
NetFloatingIP fip =
associatedFloatingIp(instPort, osRouterAdminService.floatingIps());
+ boolean sgFlag = getPropertyValueAsBoolean(
+ componentConfigService.getProperties(
+ OpenstackSecurityGroupHandler.class.getName()),
+ USE_SECURITY_GROUP);
+
if (fip != null) {
-
- instancePortService.updateInstancePort(instPort.updateState(REMOVE_PENDING));
-
+ instancePortService.updateInstancePort(
+ instPort.updateState(REMOVE_PENDING));
eventExecutor.execute(() ->
updateFipStore(instancePortService.instancePort(event.port().getId())));
} else {
- instancePortService.removeInstancePort(instPort.portId());
+ // FIXME: we have dependency with security group, need to
+ // find a better way to remove this dependency
+ if (!sgFlag) {
+ instancePortService.removeInstancePort(instPort.portId());
+ }
}
break;
default:
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 114cc44..550fc37 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
@@ -41,9 +41,9 @@
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.criteria.ExtensionSelector;
import org.onosproject.openstacknetworking.api.InstancePort;
+import org.onosproject.openstacknetworking.api.InstancePortAdminService;
import org.onosproject.openstacknetworking.api.InstancePortEvent;
import org.onosproject.openstacknetworking.api.InstancePortListener;
-import org.onosproject.openstacknetworking.api.InstancePortService;
import org.onosproject.openstacknetworking.api.OpenstackFlowRuleService;
import org.onosproject.openstacknetworking.api.OpenstackNetworkEvent;
import org.onosproject.openstacknetworking.api.OpenstackNetworkListener;
@@ -51,6 +51,7 @@
import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupEvent;
import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupListener;
import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupService;
+import org.onosproject.openstacknetworking.api.PreCommitPortService;
import org.onosproject.openstacknetworking.util.RulePopulatorUtil;
import org.onosproject.openstacknode.api.OpenstackNode;
import org.onosproject.openstacknode.api.OpenstackNodeEvent;
@@ -88,6 +89,8 @@
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_CT_DROP_RULE;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_CT_HOOK_RULE;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_CT_RULE;
+import static org.onosproject.openstacknetworking.api.InstancePort.State.REMOVE_PENDING;
+import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_PORT_PRE_REMOVE;
import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.computeCtMaskFlag;
import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.computeCtStateFlag;
import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.niciraConnTrackTreatmentBuilder;
@@ -112,7 +115,7 @@
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY)
- protected InstancePortService instancePortService;
+ protected InstancePortAdminService instancePortService;
@Reference(cardinality = ReferenceCardinality.MANDATORY)
protected MastershipService mastershipService;
@@ -141,6 +144,9 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY)
protected ClusterService clusterService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected PreCommitPortService preCommitPortService;
+
private final InstancePortListener instancePortListener =
new InternalInstancePortListener();
private final OpenstackNetworkListener osNetworkListener =
@@ -255,6 +261,16 @@
final String action = install ? "Installed " : "Removed ";
log.debug(action + "security group rule ID : " + sgId);
});
+
+ if (install) {
+ preCommitPortService.subscribePreCommit(instPort.portId(),
+ OPENSTACK_PORT_PRE_REMOVE, this.getClass().getName());
+ log.info("Subscribed the port {} on listening pre-remove event", instPort.portId());
+ } else {
+ preCommitPortService.unsubscribePreCommit(instPort.portId(),
+ OPENSTACK_PORT_PRE_REMOVE, instancePortService, this.getClass().getName());
+ log.info("Unsubscribed the port {} on listening pre-remove event", instPort.portId());
+ }
}
private void updateSecurityGroupRule(InstancePort instPort, Port port,
@@ -715,9 +731,11 @@
switch (event.type()) {
case OPENSTACK_PORT_PRE_REMOVE:
- eventExecutor.execute(() -> {
- setSecurityGroupRules(instPort, osPort, false);
- });
+ instancePortService.updateInstancePort(
+ instPort.updateState(REMOVE_PENDING));
+ eventExecutor.execute(() ->
+ setSecurityGroupRules(instPort, osPort, false)
+ );
break;
default:
// do nothing for the other events
@@ -803,8 +821,8 @@
securityGroupRuleToRemove.getId());
});
break;
- case OPENSTACK_SECURITY_GROUP_CREATED:
case OPENSTACK_SECURITY_GROUP_REMOVED:
+ case OPENSTACK_SECURITY_GROUP_CREATED:
default:
// do nothing
break;
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 daad9d1..008f484 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
@@ -276,6 +276,21 @@
private void setFakeGatewayArpRule(Subnet osSubnet, boolean install, OpenstackNode osNode) {
if (ARP_BROADCAST_MODE.equals(getArpMode())) {
+
+ // do not remove fake gateway ARP rules, if there is another gateway
+ // which has the same subnet that to be removed
+ // this only occurs if we have duplicated subnets associated with
+ // different networks
+ if (!install) {
+ long numOfDupGws = osNetworkService.subnets().stream()
+ .filter(s -> !s.getId().equals(osSubnet.getId()))
+ .filter(s -> s.getGateway().equals(osSubnet.getGateway()))
+ .count();
+ if (numOfDupGws > 0) {
+ return;
+ }
+ }
+
String gateway = osSubnet.getGateway();
TrafficSelector selector = DefaultTrafficSelector.builder()
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 4f4e570..b755017 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
@@ -452,6 +452,20 @@
}
/**
+ * Obtains the boolean property value with specified property key name.
+ *
+ * @param properties a collection of properties
+ * @param name key name
+ * @return mapping value
+ */
+ public static boolean getPropertyValueAsBoolean(Set<ConfigProperty> properties, String name) {
+ Optional<ConfigProperty> property =
+ properties.stream().filter(p -> p.name().equals(name)).findFirst();
+
+ return property.map(ConfigProperty::asBoolean).orElse(false);
+ }
+
+ /**
* Prints out the JSON string in pretty format.
*
* @param mapper Object mapper