Daniel Park

[ONOS-5114] Fix to send icmp packet from vm to gateway when floating is assigned

Change-Id: Ia8ba62cfa38ee56a0f8d40545f728e47a902082c
...@@ -59,6 +59,8 @@ public final class Constants { ...@@ -59,6 +59,8 @@ public final class Constants {
59 public static final int TUNNELTAG_RULE_PRIORITY = 30000; 59 public static final int TUNNELTAG_RULE_PRIORITY = 30000;
60 public static final int ACL_RULE_PRIORITY = 30000; 60 public static final int ACL_RULE_PRIORITY = 30000;
61 public static final int EW_ROUTING_RULE_PRIORITY = 28000; 61 public static final int EW_ROUTING_RULE_PRIORITY = 28000;
62 +
63 + public static final int GATEWAY_ICMP_PRIORITY = 43000;
62 public static final int ROUTING_RULE_PRIORITY = 25000; 64 public static final int ROUTING_RULE_PRIORITY = 25000;
63 public static final int FLOATING_RULE_PRIORITY = 42000; 65 public static final int FLOATING_RULE_PRIORITY = 42000;
64 public static final int PNAT_RULE_PRIORITY = 26000; 66 public static final int PNAT_RULE_PRIORITY = 26000;
......
...@@ -23,6 +23,7 @@ import org.apache.felix.scr.annotations.Reference; ...@@ -23,6 +23,7 @@ import org.apache.felix.scr.annotations.Reference;
23 import org.apache.felix.scr.annotations.ReferenceCardinality; 23 import org.apache.felix.scr.annotations.ReferenceCardinality;
24 import org.apache.felix.scr.annotations.Service; 24 import org.apache.felix.scr.annotations.Service;
25 import org.onlab.packet.Ethernet; 25 import org.onlab.packet.Ethernet;
26 +import org.onlab.packet.IPv4;
26 import org.onlab.packet.Ip4Address; 27 import org.onlab.packet.Ip4Address;
27 import org.onlab.packet.IpPrefix; 28 import org.onlab.packet.IpPrefix;
28 import org.onlab.packet.MacAddress; 29 import org.onlab.packet.MacAddress;
...@@ -157,6 +158,8 @@ public class OpenstackRoutingManager extends AbstractVmHandler implements Openst ...@@ -157,6 +158,8 @@ public class OpenstackRoutingManager extends AbstractVmHandler implements Openst
157 return; 158 return;
158 } 159 }
159 160
161 + setGatewayIcmp(Ip4Address.valueOf(openstackService.subnet(routerIface.subnetId()).gatewayIp()));
162 +
160 setRoutes(osRouter, Optional.empty()); 163 setRoutes(osRouter, Optional.empty());
161 if (osRouter.gatewayExternalInfo().externalFixedIps().size() > 0) { 164 if (osRouter.gatewayExternalInfo().externalFixedIps().size() > 0) {
162 String subnetId = osPort.fixedIps().keySet().stream().findFirst().get(); 165 String subnetId = osPort.fixedIps().keySet().stream().findFirst().get();
...@@ -176,13 +179,66 @@ public class OpenstackRoutingManager extends AbstractVmHandler implements Openst ...@@ -176,13 +179,66 @@ public class OpenstackRoutingManager extends AbstractVmHandler implements Openst
176 OpenstackSubnet osSubnet = openstackService.subnet(routerIface.subnetId()); 179 OpenstackSubnet osSubnet = openstackService.subnet(routerIface.subnetId());
177 OpenstackNetwork osNet = openstackService.network(osSubnet.networkId()); 180 OpenstackNetwork osNet = openstackService.network(osSubnet.networkId());
178 181
182 + unsetGatewayIcmp(Ip4Address.valueOf(openstackService.subnet(routerIface.subnetId()).gatewayIp()));
183 +
179 unsetRoutes(osRouter, osSubnet); 184 unsetRoutes(osRouter, osSubnet);
185 +
180 if (osRouter.gatewayExternalInfo().externalFixedIps().size() > 0) { 186 if (osRouter.gatewayExternalInfo().externalFixedIps().size() > 0) {
181 unsetExternalConnection(osRouter, osNet.id()); 187 unsetExternalConnection(osRouter, osNet.id());
182 } 188 }
183 log.info("Disconnected {} from router {}", osSubnet.cidr(), osRouter.name()); 189 log.info("Disconnected {} from router {}", osSubnet.cidr(), osRouter.name());
184 } 190 }
185 191
192 + private void setGatewayIcmp(Ip4Address gatewayIp) {
193 + if (gatewayIp == null) {
194 + return;
195 + }
196 + gatewayService.getGatewayDeviceIds().stream().forEach(deviceId -> {
197 + populateGatewayIcmpRule(gatewayIp, deviceId);
198 + });
199 + }
200 +
201 + private void populateGatewayIcmpRule(Ip4Address gatewayIp, DeviceId deviceId) {
202 + TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
203 + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
204 +
205 + sBuilder.matchEthType(Ethernet.TYPE_IPV4)
206 + .matchIPProtocol(IPv4.PROTOCOL_ICMP)
207 + .matchIPDst(gatewayIp.toIpPrefix());
208 +
209 + tBuilder.setOutput(PortNumber.CONTROLLER);
210 +
211 + ForwardingObjective fo = DefaultForwardingObjective.builder()
212 + .withSelector(sBuilder.build())
213 + .withTreatment(tBuilder.build())
214 + .withPriority(GATEWAY_ICMP_PRIORITY)
215 + .withFlag(ForwardingObjective.Flag.VERSATILE)
216 + .fromApp(appId)
217 + .add();
218 +
219 + flowObjectiveService.forward(deviceId, fo);
220 + }
221 +
222 + private void unsetGatewayIcmp(Ip4Address gatewayIp) {
223 + if (gatewayIp == null) {
224 + return;
225 + }
226 + gatewayService.getGatewayDeviceIds().forEach(deviceId -> {
227 + removeGatewayIcmpRule(gatewayIp, deviceId);
228 + });
229 + }
230 +
231 + private void removeGatewayIcmpRule(Ip4Address gatewayIp, DeviceId deviceId) {
232 + TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
233 +
234 + sBuilder.matchEthType(Ethernet.TYPE_IPV4)
235 + .matchIPProtocol(IPv4.PROTOCOL_ICMP)
236 + .matchIPDst(gatewayIp.toIpPrefix());
237 +
238 + RulePopulatorUtil.removeRule(flowObjectiveService, appId, deviceId, sBuilder.build(),
239 + ForwardingObjective.Flag.VERSATILE, GATEWAY_ICMP_PRIORITY);
240 +
241 + }
186 private void setExternalConnection(OpenstackRouter osRouter, String osSubNetId) { 242 private void setExternalConnection(OpenstackRouter osRouter, String osSubNetId) {
187 if (!osRouter.gatewayExternalInfo().isEnablePnat()) { 243 if (!osRouter.gatewayExternalInfo().isEnablePnat()) {
188 log.debug("Source NAT is disabled"); 244 log.debug("Source NAT is disabled");
...@@ -462,6 +518,10 @@ public class OpenstackRoutingManager extends AbstractVmHandler implements Openst ...@@ -462,6 +518,10 @@ public class OpenstackRoutingManager extends AbstractVmHandler implements Openst
462 .filter(osPort -> osPort.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE)) 518 .filter(osPort -> osPort.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE))
463 .forEach(osPort -> { 519 .forEach(osPort -> {
464 OpenstackRouter osRouter = openstackRouter(osPort.deviceId()); 520 OpenstackRouter osRouter = openstackRouter(osPort.deviceId());
521 +
522 + setGatewayIcmp(Ip4Address.valueOf(openstackService
523 + .subnet(osPort.fixedIps().keySet().stream().findAny().get()).gatewayIp()));
524 +
465 setRoutes(osRouter, Optional.empty()); 525 setRoutes(osRouter, Optional.empty());
466 if (osRouter.gatewayExternalInfo().externalFixedIps().size() > 0) { 526 if (osRouter.gatewayExternalInfo().externalFixedIps().size() > 0) {
467 String subnetId = osPort.fixedIps().keySet().stream().findFirst().get(); 527 String subnetId = osPort.fixedIps().keySet().stream().findFirst().get();
......