Only flood the ARP traffic to virtual network to avoid network loop
1. Purge unnecessary phyIntfPort method from openstacknode.
2. Update setUpstreamRulesForFlat method to reflect multi-br change
Change-Id: I6d70702d2aac2a067577635fada06c8eb21b56ae
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 3b805e8..a4e817f 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
@@ -55,7 +55,9 @@
import org.onosproject.openstacknode.api.OpenstackNodeEvent;
import org.onosproject.openstacknode.api.OpenstackNodeListener;
import org.onosproject.openstacknode.api.OpenstackNodeService;
+import org.openstack4j.model.common.IdEntity;
import org.openstack4j.model.network.Network;
+import org.openstack4j.model.network.NetworkType;
import org.openstack4j.model.network.Subnet;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
@@ -72,6 +74,7 @@
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutorService;
+import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
@@ -792,6 +795,35 @@
}
}
+ private void setBaseVnetArpRuleForBroadcastMode(OpenstackNode osNode,
+ String segId,
+ boolean isTunnel,
+ boolean install) {
+ TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
+ .matchEthType(EthType.EtherType.ARP.ethType().toShort())
+ .matchArpOp(ARP.OP_REQUEST);
+
+ if (isTunnel) {
+ sBuilder.matchTunnelId(Long.valueOf(segId));
+ } else {
+ sBuilder.matchVlanId(VlanId.vlanId(segId));
+ }
+
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .setOutput(PortNumber.FLOOD)
+ .build();
+
+ osFlowRuleService.setRule(
+ appId,
+ osNode.intgBridge(),
+ sBuilder.build(),
+ treatment,
+ PRIORITY_ARP_FLOOD_RULE,
+ ARP_TABLE,
+ install
+ );
+ }
+
/**
* An internal network listener which listens to openstack network event,
* manages the gateway collection and installs flow rule that handles
@@ -827,7 +859,11 @@
break;
case OPENSTACK_NETWORK_CREATED:
case OPENSTACK_NETWORK_UPDATED:
+ eventExecutor.execute(() -> processNetworkCreation(event));
+ break;
case OPENSTACK_NETWORK_REMOVED:
+ eventExecutor.execute(() -> processNetworkRemoval(event));
+ break;
case OPENSTACK_PORT_CREATED:
case OPENSTACK_PORT_UPDATED:
case OPENSTACK_PORT_REMOVED:
@@ -854,6 +890,41 @@
setFakeGatewayArpRule(event.subnet(), event.subject(),
false, null);
}
+
+ private void processNetworkCreation(OpenstackNetworkEvent event) {
+ if (!isRelevantHelper()) {
+ return;
+ }
+
+ setVnetArpRule(event.subject(), true);
+ }
+
+ private void processNetworkRemoval(OpenstackNetworkEvent event) {
+ if (!isRelevantHelper()) {
+ return;
+ }
+
+ setVnetArpRule(event.subject(), false);
+ }
+
+ private void setVnetArpRule(Network network, boolean install) {
+ String netId = network.getId();
+ NetworkType netType = network.getNetworkType();
+
+ if (netType != NetworkType.LOCAL && netType != NetworkType.FLAT
+ && netType != NetworkType.VLAN) {
+ String segId = osNetworkService.segmentId(netId);
+ osNodeService.completeNodes(COMPUTE)
+ .forEach(node -> setBaseVnetArpRuleForBroadcastMode(
+ node, segId, true, install));
+ }
+ if (netType == NetworkType.VLAN) {
+ String segId = osNetworkService.segmentId(netId);
+ osNodeService.completeNodes(COMPUTE)
+ .forEach(node -> setBaseVnetArpRuleForBroadcastMode(
+ node, segId, false, install));
+ }
+ }
}
/**
@@ -926,7 +997,7 @@
private void processDefaultArpRuleForBroadcastMode(OpenstackNode osNode,
boolean install) {
- setDefaultArpRuleForBroadcastMode(osNode, install);
+ setVnetArpRuleForBroadcastMode(osNode, install);
// we do not add fake gateway ARP rules for FLAT network
// ARP packets generated by FLAT typed VM should not be
@@ -961,27 +1032,29 @@
);
}
- private void setDefaultArpRuleForBroadcastMode(OpenstackNode osNode, boolean install) {
- TrafficSelector selector = DefaultTrafficSelector.builder()
- .matchEthType(EthType.EtherType.ARP.ethType().toShort())
- .matchArpOp(ARP.OP_REQUEST)
- .build();
+ private void setVnetArpRuleForBroadcastMode(OpenstackNode osNode, boolean install) {
+ Set<String> netIds = osNetworkService.networks().stream()
+ .map(IdEntity::getId).collect(Collectors.toSet());
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .setOutput(PortNumber.FLOOD)
- .build();
+ netIds.stream()
+ .filter(nid -> osNetworkService.networkType(nid) == VXLAN ||
+ osNetworkService.networkType(nid) == GRE ||
+ osNetworkService.networkType(nid) == GENEVE)
+ .forEach(nid -> {
+ String segId = osNetworkService.segmentId(nid);
+ setBaseVnetArpRuleForBroadcastMode(osNode, segId, true, install);
+ });
- osFlowRuleService.setRule(
- appId,
- osNode.intgBridge(),
- selector,
- treatment,
- PRIORITY_ARP_FLOOD_RULE,
- ARP_TABLE,
- install
- );
+ netIds.stream()
+ .filter(nid -> osNetworkService.networkType(nid) == VLAN)
+ .forEach(nid -> {
+ String segId = osNetworkService.segmentId(nid);
+ setBaseVnetArpRuleForBroadcastMode(osNode, segId, false, install);
+ });
}
+
+
private void setAllArpRules(OpenstackNode osNode, boolean install) {
if (ARP_BROADCAST_MODE.equals(getArpMode())) {
instancePortService.instancePorts().stream()