[ONOS-6038] [ONOS-6036]Support Neutron network/port admin state up/down configuration
Change-Id: I4b4251131b38d719ee1980741bbf30750f403407
diff --git a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/api/Constants.java b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/api/Constants.java
index f2fe3f1..8b58cf6 100644
--- a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/api/Constants.java
+++ b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/api/Constants.java
@@ -41,6 +41,7 @@
public static final int PRIORITY_SNAT_RULE = 26000;
public static final int PRIORITY_SWITCHING_RULE = 30000;
public static final int PRIORITY_ACL_RULE = 30000;
+ public static final int PRIORITY_ADMIN_RULE = 31000;
public static final int SRC_VNI_TABLE = 0;
public static final int ACL_TABLE = 1;
diff --git a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
index 8370250..4bb42a0 100644
--- a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
+++ b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
@@ -23,6 +23,7 @@
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.packet.Ethernet;
+import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
@@ -37,22 +38,34 @@
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;
import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
import org.onosproject.openstacknode.api.OpenstackNode;
import org.onosproject.openstacknode.api.OpenstackNodeService;
import org.openstack4j.model.network.Network;
+import org.openstack4j.model.network.NetworkType;
+import org.openstack4j.model.network.Port;
import org.slf4j.Logger;
import java.util.concurrent.ExecutorService;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
import static org.onlab.util.Tools.groupedThreads;
+
import static org.onosproject.openstacknetworking.api.Constants.ACL_TABLE;
import static org.onosproject.openstacknetworking.api.Constants.FORWARDING_TABLE;
import static org.onosproject.openstacknetworking.api.Constants.OPENSTACK_NETWORKING_APP_ID;
+import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ADMIN_RULE;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_SWITCHING_RULE;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_TUNNEL_TAG_RULE;
import static org.onosproject.openstacknetworking.api.Constants.SRC_VNI_TABLE;
+import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_NETWORK_CREATED;
+import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_NETWORK_REMOVED;
+import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_NETWORK_UPDATED;
+import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_PORT_CREATED;
+import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_PORT_REMOVED;
+import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_PORT_UPDATED;
import static org.onosproject.openstacknetworking.impl.RulePopulatorUtil.buildExtension;
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
import static org.slf4j.LoggerFactory.getLogger;
@@ -93,12 +106,15 @@
private final ExecutorService eventExecutor = newSingleThreadExecutor(
groupedThreads(this.getClass().getSimpleName(), "event-handler"));
private final InstancePortListener instancePortListener = new InternalInstancePortListener();
+ private final InternalOpenstackNetworkListener osNetworkListener =
+ new InternalOpenstackNetworkListener();
private ApplicationId appId;
@Activate
protected void activate() {
appId = coreService.registerApplication(OPENSTACK_NETWORKING_APP_ID);
instancePortService.addListener(instancePortListener);
+ osNetworkService.addListener(osNetworkListener);
log.info("Started");
}
@@ -106,6 +122,7 @@
@Deactivate
protected void deactivate() {
instancePortService.removeListener(instancePortListener);
+ osNetworkService.removeListener(osNetworkListener);
eventExecutor.shutdown();
log.info("Stopped");
@@ -265,6 +282,57 @@
}
+ private void setNetworkAdminRules(Network network, boolean install) {
+ TrafficSelector selector;
+ if (network.getNetworkType() == NetworkType.VXLAN) {
+
+ selector = DefaultTrafficSelector.builder()
+ .matchTunnelId(Long.valueOf(network.getProviderSegID()))
+ .build();
+ } else {
+ selector = DefaultTrafficSelector.builder()
+ .matchVlanId(VlanId.vlanId(network.getProviderSegID()))
+ .build();
+ }
+
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .drop()
+ .build();
+
+ osNodeService.completeNodes().stream()
+ .filter(osNode -> osNode.type() == COMPUTE)
+ .forEach(osNode -> {
+ osFlowRuleService.setRule(
+ appId,
+ osNode.intgBridge(),
+ selector,
+ treatment,
+ PRIORITY_ADMIN_RULE,
+ ACL_TABLE,
+ install);
+ });
+ }
+
+ private void setPortAdminRules(Port port, boolean install) {
+ InstancePort instancePort = instancePortService.instancePort(MacAddress.valueOf(port.getMacAddress()));
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchInPort(instancePort.portNumber())
+ .build();
+
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .drop()
+ .build();
+
+ osFlowRuleService.setRule(
+ appId,
+ instancePort.deviceId(),
+ selector,
+ treatment,
+ PRIORITY_ADMIN_RULE,
+ SRC_VNI_TABLE,
+ install);
+ }
+
private VlanId getVlanId(InstancePort instPort) {
Network osNet = osNetworkService.network(instPort.networkId());
@@ -334,4 +402,32 @@
// TODO add something else if needed
}
}
+
+ private class InternalOpenstackNetworkListener implements OpenstackNetworkListener {
+
+ @Override
+ public boolean isRelevant(OpenstackNetworkEvent event) {
+ return !(event.subject() == null && event.port() == null);
+ }
+
+ @Override
+ public void event(OpenstackNetworkEvent event) {
+
+ if ((event.type() == OPENSTACK_NETWORK_CREATED ||
+ event.type() == OPENSTACK_NETWORK_UPDATED) && !event.subject().isAdminStateUp()) {
+ setNetworkAdminRules(event.subject(), true);
+ } else if ((event.type() == OPENSTACK_NETWORK_UPDATED && event.subject().isAdminStateUp()) ||
+ (event.type() == OPENSTACK_NETWORK_REMOVED && !event.subject().isAdminStateUp())) {
+ setNetworkAdminRules(event.subject(), false);
+ }
+
+ if ((event.type() == OPENSTACK_PORT_CREATED ||
+ event.type() == OPENSTACK_PORT_UPDATED) && !event.port().isAdminStateUp()) {
+ setPortAdminRules(event.port(), true);
+ } else if ((event.type() == OPENSTACK_PORT_UPDATED && event.port().isAdminStateUp()) ||
+ (event.type() == OPENSTACK_PORT_REMOVED && !event.port().isAdminStateUp())) {
+ setPortAdminRules(event.port(), false);
+ }
+ }
+ }
}