Fix: process ICMP packets in controller
Change-Id: I03ccd687cc524fa442ad322c8d8c5ba202ffede4
diff --git a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/Constants.java b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/Constants.java
index 18bad9b..b59307e 100644
--- a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/Constants.java
+++ b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/Constants.java
@@ -66,6 +66,7 @@
public static final int PRIORITY_FLOATING_EXTERNAL = 41000;
public static final int PRIORITY_STATEFUL_SNAT_RULE = 40500;
public static final int PRIORITY_ICMP_RULE = 43000;
+ public static final int PRIORITY_ICMP_REQUEST_RULE = 40800;
public static final int PRIORITY_INTERNAL_ROUTING_RULE = 28000;
public static final int PRIORITY_EXTERNAL_ROUTING_RULE = 25000;
public static final int PRIORITY_EXTERNAL_FLOATING_ROUTING_RULE = 27000;
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
index 0e2b46b..222ce3e 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
@@ -18,6 +18,7 @@
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
import org.onlab.packet.Ethernet;
+import org.onlab.packet.ICMP;
import org.onlab.packet.IPv4;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
@@ -70,6 +71,7 @@
import static org.onosproject.openstacknetworking.api.Constants.ARP_BROADCAST_MODE;
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_ICMP_REQUEST_RULE;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ICMP_RULE;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_INTERNAL_ROUTING_RULE;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_SWITCHING_RULE;
@@ -251,14 +253,12 @@
netType,
install));
- if (!getStatefulSnatFlag()) {
- // install rules to punt ICMP packets to controller at gateway node
- // this rule is only valid for stateless ICMP SNAT case
- osNodeService.completeNodes(GATEWAY).forEach(gNode ->
- setReactiveGatewayIcmpRule(
- IpAddress.valueOf(osSubnet.getGateway()),
- gNode.intgBridge(), install));
- }
+ // install rules to punt ICMP packets to controller at gateway node
+ // this rule is only valid for stateless ICMP SNAT case
+ osNodeService.completeNodes(GATEWAY).forEach(gNode ->
+ setReactiveGatewayIcmpRule(
+ IpAddress.valueOf(osSubnet.getGateway()),
+ gNode.intgBridge(), install));
final String updateStr = install ? MSG_ENABLED : MSG_DISABLED;
log.debug(updateStr + "IP to {}", osSubnet.getGateway());
@@ -336,11 +336,21 @@
}
private void setReactiveGatewayIcmpRule(IpAddress gatewayIp, DeviceId deviceId, boolean install) {
- TrafficSelector selector = DefaultTrafficSelector.builder()
- .matchEthType(Ethernet.TYPE_IPV4)
- .matchIPProtocol(IPv4.PROTOCOL_ICMP)
- .matchIPDst(gatewayIp.getIp4Address().toIpPrefix())
- .build();
+
+ TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+ int icmpRulePriority;
+
+ if (getStatefulSnatFlag()) {
+ sBuilder.matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPProtocol(IPv4.PROTOCOL_ICMP)
+ .matchIcmpType(ICMP.TYPE_ECHO_REQUEST);
+ icmpRulePriority = PRIORITY_ICMP_REQUEST_RULE;
+ } else {
+ sBuilder.matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPProtocol(IPv4.PROTOCOL_ICMP)
+ .matchIPDst(gatewayIp.getIp4Address().toIpPrefix());
+ icmpRulePriority = PRIORITY_ICMP_RULE;
+ }
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
.punt()
@@ -349,9 +359,9 @@
osFlowRuleService.setRule(
appId,
deviceId,
- selector,
+ sBuilder.build(),
treatment,
- PRIORITY_ICMP_RULE,
+ icmpRulePriority,
Constants.GW_COMMON_TABLE,
install);
}
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
index 55b1a41..d74e276 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
@@ -17,6 +17,7 @@
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.onlab.packet.Ethernet;
@@ -111,6 +112,7 @@
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_SNAT_RULE;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_STATEFUL_SNAT_RULE;
import static org.onosproject.openstacknetworking.api.Constants.ROUTING_TABLE;
+import static org.onosproject.openstacknetworking.api.InstancePort.State.ACTIVE;
import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.FLAT;
import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.VLAN;
import static org.onosproject.openstacknetworking.impl.OsgiPropertyConstants.USE_STATEFUL_SNAT;
@@ -831,10 +833,17 @@
return;
}
+ String netId = osNetworkAdminService.subnet(routerIface.getSubnetId()).getNetworkId();
+
Map<OpenstackNode, PortRange> gwPortRangeMap = getAssignedPortsForGateway(
ImmutableList.copyOf(osNodeService.nodes(GATEWAY)));
osNodeService.completeNodes(GATEWAY).forEach(gwNode -> {
+ instancePortService.instancePorts(netId)
+ .stream()
+ .filter(port -> port.state() == ACTIVE)
+ .forEach(port -> setGatewayToInstanceDownstreamRule(
+ gwNode, port, install));
if (install) {
PortRange gwPortRange = gwPortRangeMap.get(gwNode);
@@ -1005,10 +1014,18 @@
IpPrefix gatewayIp,
boolean install) {
- TrafficSelector selector = DefaultTrafficSelector.builder()
- .matchEthType(Ethernet.TYPE_IPV4)
- .matchIPDst(gatewayIp)
- .build();
+ Set<TrafficSelector> selectors = Sets.newConcurrentHashSet();
+
+ ImmutableSet<Byte> ipv4Proto = ImmutableSet.of(IPv4.PROTOCOL_TCP, IPv4.PROTOCOL_UDP);
+
+ ipv4Proto.forEach(proto -> {
+ TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+ sBuilder.matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPDst(gatewayIp)
+ .matchIPProtocol(proto);
+ selectors.add(sBuilder.build());
+ });
+
ExtensionTreatment natTreatment = RulePopulatorUtil
.niciraConnTrackTreatmentBuilder(driverService, deviceId)
@@ -1021,14 +1038,16 @@
.extension(natTreatment, deviceId)
.build();
- osFlowRuleService.setRule(
- appId,
- deviceId,
- selector,
- treatment,
- PRIORITY_STATEFUL_SNAT_RULE,
- GW_COMMON_TABLE,
- install);
+ selectors.forEach(s -> {
+ osFlowRuleService.setRule(
+ appId,
+ deviceId,
+ s,
+ treatment,
+ PRIORITY_STATEFUL_SNAT_RULE,
+ GW_COMMON_TABLE,
+ install);
+ });
}
private void setStatefulSnatUpstreamRule(OpenstackNode gwNode,
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatIcmpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatIcmpHandler.java
index 1e4d002..117312a 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatIcmpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatIcmpHandler.java
@@ -190,7 +190,7 @@
private class InternalNodeEventListener implements OpenstackNodeListener {
@Override
public boolean isRelevant(OpenstackNodeEvent event) {
- return event.subject().type() == GATEWAY && !getStatefulSnatFlag();
+ return event.subject().type() == GATEWAY;
}
private boolean isRelevantHelper() {
@@ -265,10 +265,6 @@
return;
}
- if (getStatefulSnatFlag()) {
- return;
- }
-
InboundPacket pkt = context.inPacket();
Ethernet ethernet = pkt.parsed();
if (ethernet == null || ethernet.getEtherType() != Ethernet.TYPE_IPV4) {