Add group rule service, purge flood rules, use group to handle ARP
Change-Id: If0db889d6ab28a4d36f433f16bf84241d2726045
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 a4e817f..8c6d1d9 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
@@ -15,6 +15,7 @@
*/
package org.onosproject.openstacknetworking.impl;
+import com.google.common.collect.Lists;
import org.onlab.packet.ARP;
import org.onlab.packet.EthType;
import org.onlab.packet.Ethernet;
@@ -30,6 +31,7 @@
import org.onosproject.cluster.NodeId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
+import org.onosproject.core.GroupId;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.Device;
import org.onosproject.net.PortNumber;
@@ -38,6 +40,7 @@
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.group.GroupBucket;
import org.onosproject.net.packet.DefaultOutboundPacket;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketProcessor;
@@ -47,6 +50,7 @@
import org.onosproject.openstacknetworking.api.InstancePortListener;
import org.onosproject.openstacknetworking.api.InstancePortService;
import org.onosproject.openstacknetworking.api.OpenstackFlowRuleService;
+import org.onosproject.openstacknetworking.api.OpenstackGroupRuleService;
import org.onosproject.openstacknetworking.api.OpenstackNetwork.Type;
import org.onosproject.openstacknetworking.api.OpenstackNetworkEvent;
import org.onosproject.openstacknetworking.api.OpenstackNetworkListener;
@@ -71,6 +75,7 @@
import java.nio.ByteBuffer;
import java.util.Dictionary;
+import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutorService;
@@ -79,13 +84,14 @@
import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.net.group.GroupDescription.Type.ALL;
import static org.onosproject.openstacknetworking.api.Constants.ARP_BROADCAST_MODE;
import static org.onosproject.openstacknetworking.api.Constants.ARP_PROXY_MODE;
import static org.onosproject.openstacknetworking.api.Constants.ARP_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_FLOOD_RULE;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ARP_GATEWAY_RULE;
+import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ARP_GROUP_RULE;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ARP_REPLY_RULE;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ARP_REQUEST_RULE;
import static org.onosproject.openstacknetworking.api.InstancePort.State.ACTIVE;
@@ -102,6 +108,7 @@
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.swapStaleLocation;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.tunnelPortNumByNetId;
import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.buildExtension;
+import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.buildGroupBucket;
import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.buildMoveArpShaToThaExtension;
import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.buildMoveArpSpaToTpaExtension;
import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.buildMoveEthSrcToDstExtension;
@@ -131,6 +138,9 @@
protected OpenstackFlowRuleService osFlowRuleService;
@Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected OpenstackGroupRuleService osGroupRuleService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
protected ComponentConfigService configService;
@Reference(cardinality = ReferenceCardinality.MANDATORY)
@@ -417,9 +427,11 @@
case GRE:
case GENEVE:
setRemoteArpRequestRuleForTunnel(port, install);
+ setLocalArpRequestRuleForVnet(port, install);
break;
case VLAN:
setArpRequestRuleForVlan(port, install);
+ setLocalArpRequestRuleForVnet(port, install);
break;
default:
break;
@@ -454,7 +466,7 @@
}
/**
- * Installs flow rules to match ARP request packets only for VxLAN.
+ * Installs flow rules at remote node to match ARP request packets for Tunnel.
*
* @param port instance port
* @param install installation flag
@@ -476,6 +488,22 @@
}
/**
+ * Installs flow rules at local node to matchA RP request packets for Tunnel.
+ *
+ * @param port instance port
+ * @param install installation flag
+ */
+ private void setLocalArpRequestRuleForVnet(InstancePort port, boolean install) {
+ TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
+ .setOutput(port.portNumber());
+
+ List<GroupBucket> bkts = Lists.newArrayList();
+ bkts.add(buildGroupBucket(tBuilder.build(), ALL, (short) -1));
+ osGroupRuleService.setBuckets(appId, port.deviceId(),
+ port.networkId().hashCode(), bkts, install);
+ }
+
+ /**
* Installs flow rules to match ARP request packets for VLAN.
*
* @param port instance port
@@ -761,6 +789,43 @@
}
}
+ // a helper method
+ private void setBaseVnetArpRuleForBroadcastMode(OpenstackNode osNode,
+ String segId, String netId,
+ boolean isTunnel,
+ boolean install) {
+
+ // add group rule
+ int groupId = netId.hashCode();
+ osGroupRuleService.setRule(appId, osNode.intgBridge(), groupId,
+ ALL, Lists.newArrayList(), install);
+
+ // add flow rule
+ TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
+ .matchEthType(EthType.EtherType.ARP.ethType().toShort())
+ .matchArpOp(ARP.OP_REQUEST);
+
+ if (isTunnel) {
+ sBuilder.matchTunnelId(Long.parseLong(segId));
+ } else {
+ sBuilder.matchVlanId(VlanId.vlanId(segId));
+ }
+
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .group(GroupId.valueOf(netId.hashCode()))
+ .build();
+
+ osFlowRuleService.setRule(
+ appId,
+ osNode.intgBridge(),
+ sBuilder.build(),
+ treatment,
+ PRIORITY_ARP_GROUP_RULE,
+ ARP_TABLE,
+ install
+ );
+ }
+
/**
* Extracts properties from the component configuration context.
*
@@ -795,35 +860,6 @@
}
}
- 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
@@ -915,14 +951,18 @@
&& netType != NetworkType.VLAN) {
String segId = osNetworkService.segmentId(netId);
osNodeService.completeNodes(COMPUTE)
- .forEach(node -> setBaseVnetArpRuleForBroadcastMode(
- node, segId, true, install));
+ .forEach(node -> {
+ setBaseVnetArpRuleForBroadcastMode(node, segId,
+ netId, true, install);
+ });
}
if (netType == NetworkType.VLAN) {
String segId = osNetworkService.segmentId(netId);
osNodeService.completeNodes(COMPUTE)
- .forEach(node -> setBaseVnetArpRuleForBroadcastMode(
- node, segId, false, install));
+ .forEach(node -> {
+ setBaseVnetArpRuleForBroadcastMode(
+ node, segId, netId, false, install);
+ });
}
}
}
@@ -1042,19 +1082,17 @@
osNetworkService.networkType(nid) == GENEVE)
.forEach(nid -> {
String segId = osNetworkService.segmentId(nid);
- setBaseVnetArpRuleForBroadcastMode(osNode, segId, true, install);
+ setBaseVnetArpRuleForBroadcastMode(osNode, segId, nid, true, install);
});
netIds.stream()
.filter(nid -> osNetworkService.networkType(nid) == VLAN)
.forEach(nid -> {
String segId = osNetworkService.segmentId(nid);
- setBaseVnetArpRuleForBroadcastMode(osNode, segId, false, install);
+ setBaseVnetArpRuleForBroadcastMode(osNode, segId, nid, false, install);
});
}
-
-
private void setAllArpRules(OpenstackNode osNode, boolean install) {
if (ARP_BROADCAST_MODE.equals(getArpMode())) {
instancePortService.instancePorts().stream()
@@ -1064,6 +1102,8 @@
setArpRequestRule(p, install);
setArpReplyRule(p, install);
});
+ } else {
+ // we do nothing for proxy mode
}
}
}