Refactor: split the flow rule setup logic for compute and ctrl nodes
Change-Id: I30d5b2a63615fad3f5fd8281edbf46574809cb13
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 c016447..42c1c77 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
@@ -60,6 +60,8 @@
import org.onosproject.openstacknetworking.api.OpenstackRouterListener;
import org.onosproject.openstacknetworking.api.OpenstackRouterService;
import org.onosproject.openstacknode.api.OpenstackNode;
+import org.onosproject.openstacknode.api.OpenstackNodeEvent;
+import org.onosproject.openstacknode.api.OpenstackNodeListener;
import org.onosproject.openstacknode.api.OpenstackNodeService;
import org.openstack4j.model.network.ExternalGateway;
import org.openstack4j.model.network.NetFloatingIP;
@@ -84,8 +86,10 @@
import static org.onosproject.openstacknetworking.api.Constants.ARP_PROXY_MODE;
import static org.onosproject.openstacknetworking.api.Constants.DEFAULT_ARP_MODE_STR;
import static org.onosproject.openstacknetworking.api.Constants.DEFAULT_GATEWAY_MAC_STR;
+import static org.onosproject.openstacknetworking.api.Constants.DHCP_ARP_TABLE;
import static org.onosproject.openstacknetworking.api.Constants.GW_COMMON_TABLE;
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.impl.HostBasedInstancePort.ANNOTATION_NETWORK_ID;
import static org.onosproject.openstacknetworking.impl.HostBasedInstancePort.ANNOTATION_PORT_ID;
@@ -144,6 +148,7 @@
private final OpenstackRouterListener osRouterListener = new InternalRouterEventListener();
private final HostListener hostListener = new InternalHostListener();
+ private final OpenstackNodeListener osNodeListener = new InternalNodeEventListener();
private ApplicationId appId;
private NodeId localNodeId;
@@ -161,6 +166,7 @@
localNodeId = clusterService.getLocalNode().id();
osRouterService.addListener(osRouterListener);
hostService.addListener(hostListener);
+ osNodeService.addListener(osNodeListener);
leadershipService.runForLeadership(appId.name());
packetService.addProcessor(packetProcessor, PacketProcessor.director(1));
log.info("Started");
@@ -171,6 +177,7 @@
packetService.removeProcessor(packetProcessor);
hostService.removeListener(hostListener);
osRouterService.removeListener(osRouterListener);
+ osNodeService.removeListener(osNodeListener);
leadershipService.withdraw(appId.name());
eventExecutor.shutdown();
configService.unregisterProperties(getClass(), false);
@@ -565,4 +572,92 @@
host.annotations().value(ANNOTATION_PORT_ID) != null;
}
}
+
+ private class InternalNodeEventListener implements OpenstackNodeListener {
+
+ @Override
+ public boolean isRelevant(OpenstackNodeEvent event) {
+ // do not allow to proceed without leadership
+ NodeId leader = leadershipService.getLeader(appId.name());
+ return Objects.equals(localNodeId, leader);
+ }
+
+ @Override
+ public void event(OpenstackNodeEvent event) {
+ OpenstackNode osNode = event.subject();
+ switch (event.type()) {
+ case OPENSTACK_NODE_COMPLETE:
+ if (osNode.type().equals(GATEWAY)) {
+ setDefaultArpRule(osNode, true);
+ }
+ break;
+ case OPENSTACK_NODE_INCOMPLETE:
+ if (osNode.type().equals(GATEWAY)) {
+ setDefaultArpRule(osNode, false);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void setDefaultArpRule(OpenstackNode osNode, boolean install) {
+ switch (arpMode) {
+ case ARP_PROXY_MODE:
+ setDefaultArpRuleForProxyMode(osNode, install);
+ break;
+ case ARP_BROADCAST_MODE:
+ setDefaultArpRuleForBroadcastMode(osNode, install);
+ break;
+ default:
+ log.warn("Invalid ARP mode {}. Please use either " +
+ "broadcast or proxy mode.", arpMode);
+ break;
+ }
+ }
+
+ private void setDefaultArpRuleForProxyMode(OpenstackNode osNode, boolean install) {
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchEthType(EthType.EtherType.ARP.ethType().toShort())
+ .build();
+
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .punt()
+ .build();
+
+ osFlowRuleService.setRule(
+ appId,
+ osNode.intgBridge(),
+ selector,
+ treatment,
+ PRIORITY_ARP_CONTROL_RULE,
+ DHCP_ARP_TABLE,
+ install
+ );
+ }
+
+ private void setDefaultArpRuleForBroadcastMode(OpenstackNode osNode, boolean install) {
+ // we only match ARP_REPLY in gateway node, because controller
+ // somehow need to process ARP_REPLY which is issued from
+ // external router...
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchEthType(EthType.EtherType.ARP.ethType().toShort())
+ .matchArpOp(ARP.OP_REPLY)
+ .build();
+
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .punt()
+ .build();
+
+ osFlowRuleService.setRule(
+ appId,
+ osNode.intgBridge(),
+ selector,
+ treatment,
+ PRIORITY_ARP_CONTROL_RULE,
+ DHCP_ARP_TABLE,
+ install
+ );
+ }
+ }
}
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 c354f19..f2c2eda 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
@@ -86,7 +86,6 @@
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ARP_SUBNET_RULE;
import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.buildExtension;
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
-import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
/**
* Handles ARP packet from VMs.
@@ -433,73 +432,75 @@
OpenstackNode osNode = event.subject();
switch (event.type()) {
case OPENSTACK_NODE_COMPLETE:
- setDefaultArpRule(osNode, true);
+ if (osNode.type().equals(COMPUTE)) {
+ setDefaultArpRule(osNode, true);
+ }
break;
case OPENSTACK_NODE_INCOMPLETE:
- setDefaultArpRule(osNode, false);
+ if (osNode.type().equals(COMPUTE)) {
+ setDefaultArpRule(osNode, false);
+ }
break;
- case OPENSTACK_NODE_CREATED:
- case OPENSTACK_NODE_UPDATED:
- case OPENSTACK_NODE_REMOVED:
default:
break;
}
}
- private void setDefaultArpRule(OpenstackNode openstackNode, boolean install) {
- if (arpMode.equals(ARP_PROXY_MODE)) {
-
- TrafficSelector selector = DefaultTrafficSelector.builder()
- .matchEthType(EthType.EtherType.ARP.ethType().toShort())
- .build();
-
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .punt()
- .build();
-
- osFlowRuleService.setRule(
- appId,
- openstackNode.intgBridge(),
- selector,
- treatment,
- PRIORITY_ARP_CONTROL_RULE,
- DHCP_ARP_TABLE,
- install
- );
- } else if (arpMode.equals(ARP_BROADCAST_MODE)) {
-
- TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder()
- .matchEthType(EthType.EtherType.ARP.ethType().toShort());
-
- TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
-
- // we only match ARP_REPLY in gateway node, because controller
- // somehow need to process ARP_REPLY which is issued from
- // external router...
- // TODO: following code needs to be moved to OpenstackRoutingArpHandler sooner or later
- if (openstackNode.type().equals(GATEWAY)) {
- selectorBuilder.matchArpOp(ARP.OP_REPLY);
- treatmentBuilder.punt();
- }
-
- if (openstackNode.type().equals(COMPUTE)) {
- selectorBuilder.matchArpOp(ARP.OP_REQUEST);
- treatmentBuilder.setOutput(PortNumber.FLOOD);
- }
-
- osFlowRuleService.setRule(
- appId,
- openstackNode.intgBridge(),
- selectorBuilder.build(),
- treatmentBuilder.build(),
- PRIORITY_ARP_SUBNET_RULE,
- DHCP_ARP_TABLE,
- install
- );
- } else {
- log.warn("Invalid ARP mode {}. Please use either broadcast or proxy mode.", arpMode);
+ private void setDefaultArpRule(OpenstackNode osNode, boolean install) {
+ switch (arpMode) {
+ case ARP_PROXY_MODE:
+ setDefaultArpRuleForProxyMode(osNode, install);
+ break;
+ case ARP_BROADCAST_MODE:
+ setDefaultArpRuleForBroadcastMode(osNode, install);
+ break;
+ default:
+ log.warn("Invalid ARP mode {}. Please use either " +
+ "broadcast or proxy mode.", arpMode);
+ break;
}
}
+
+ private void setDefaultArpRuleForProxyMode(OpenstackNode osNode, boolean install) {
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchEthType(EthType.EtherType.ARP.ethType().toShort())
+ .build();
+
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .punt()
+ .build();
+
+ osFlowRuleService.setRule(
+ appId,
+ osNode.intgBridge(),
+ selector,
+ treatment,
+ PRIORITY_ARP_CONTROL_RULE,
+ DHCP_ARP_TABLE,
+ install
+ );
+ }
+
+ private void setDefaultArpRuleForBroadcastMode(OpenstackNode osNode, boolean install) {
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchEthType(EthType.EtherType.ARP.ethType().toShort())
+ .matchArpOp(ARP.OP_REQUEST)
+ .build();
+
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .setOutput(PortNumber.FLOOD)
+ .build();
+
+ osFlowRuleService.setRule(
+ appId,
+ osNode.intgBridge(),
+ selector,
+ treatment,
+ PRIORITY_ARP_SUBNET_RULE,
+ DHCP_ARP_TABLE,
+ install
+ );
+ }
}
/**