[ONOS-5114] Fix to send icmp packet from vm to gateway when floating is assigned
Change-Id: Ia8ba62cfa38ee56a0f8d40545f728e47a902082c
Showing
2 changed files
with
62 additions
and
0 deletions
... | @@ -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(); | ... | ... |
-
Please register or login to post a comment