Committed by
Gerrit Code Review
[ONOS-4702] Fixed Openstack ARP/ICMP in OpenstackNetworkingService.
-Fixes ICMP/ARP handler to deals with floatingIP. -Fixed some bugs in ARP/ICMP handler. Change-Id: Ie06fdcce25f8a58e2f14e9050bfb7e430ddfd3af
Showing
5 changed files
with
71 additions
and
13 deletions
| ... | @@ -347,7 +347,7 @@ public final class OpenstackSecurityGroupRule { | ... | @@ -347,7 +347,7 @@ public final class OpenstackSecurityGroupRule { |
| 347 | public OpenstackSecurityGroupRule build() { | 347 | public OpenstackSecurityGroupRule build() { |
| 348 | 348 | ||
| 349 | int portRangeMinInt = (portRangeMin == null || portRangeMin.equals("null")) ? | 349 | int portRangeMinInt = (portRangeMin == null || portRangeMin.equals("null")) ? |
| 350 | - -1 : Integer.parseInt(portRangeMax); | 350 | + -1 : Integer.parseInt(portRangeMin); |
| 351 | int portRangeMaxInt = (portRangeMax == null || portRangeMax.equals("null")) ? | 351 | int portRangeMaxInt = (portRangeMax == null || portRangeMax.equals("null")) ? |
| 352 | -1 : Integer.parseInt(portRangeMax); | 352 | -1 : Integer.parseInt(portRangeMax); |
| 353 | IpPrefix ipPrefix = (remoteIpPrefix == null || remoteIpPrefix.equals("null")) ? | 353 | IpPrefix ipPrefix = (remoteIpPrefix == null || remoteIpPrefix.equals("null")) ? | ... | ... |
| ... | @@ -66,14 +66,16 @@ public class OpenstackIcmpHandler { | ... | @@ -66,14 +66,16 @@ public class OpenstackIcmpHandler { |
| 66 | private static final MacAddress GATEWAY_MAC = MacAddress.valueOf("1f:1f:1f:1f:1f:1f"); | 66 | private static final MacAddress GATEWAY_MAC = MacAddress.valueOf("1f:1f:1f:1f:1f:1f"); |
| 67 | private static final String NETWORK_ROUTER_INTERFACE = "network:router_interface"; | 67 | private static final String NETWORK_ROUTER_INTERFACE = "network:router_interface"; |
| 68 | private static final String PORTNAME = "portName"; | 68 | private static final String PORTNAME = "portName"; |
| 69 | + private static final String NETWORK_ROUTER_GATEWAY = "network:router_gateway"; | ||
| 70 | + private static final String NETWORK_FLOATING_IP = "network:floatingip"; | ||
| 69 | 71 | ||
| 70 | /** | 72 | /** |
| 71 | * Default constructor. | 73 | * Default constructor. |
| 72 | * | 74 | * |
| 73 | - * @param packetService packet service | 75 | + * @param packetService packet service |
| 74 | - * @param deviceService device service | 76 | + * @param deviceService device service |
| 75 | - * @param openstackService openstackInterface service | 77 | + * @param openstackService openstackInterface service |
| 76 | - * @param config openstackRoutingConfig | 78 | + * @param config openstackRoutingConfig |
| 77 | * @param openstackSwitchingService openstackSwitching service | 79 | * @param openstackSwitchingService openstackSwitching service |
| 78 | */ | 80 | */ |
| 79 | OpenstackIcmpHandler(PacketService packetService, DeviceService deviceService, | 81 | OpenstackIcmpHandler(PacketService packetService, DeviceService deviceService, |
| ... | @@ -106,7 +108,7 @@ public class OpenstackIcmpHandler { | ... | @@ -106,7 +108,7 @@ public class OpenstackIcmpHandler { |
| 106 | /** | 108 | /** |
| 107 | * Handles ICMP packet. | 109 | * Handles ICMP packet. |
| 108 | * | 110 | * |
| 109 | - * @param context packet context | 111 | + * @param context packet context |
| 110 | * @param ethernet ethernet | 112 | * @param ethernet ethernet |
| 111 | */ | 113 | */ |
| 112 | public void processIcmpPacket(PacketContext context, Ethernet ethernet) { | 114 | public void processIcmpPacket(PacketContext context, Ethernet ethernet) { |
| ... | @@ -122,13 +124,30 @@ public class OpenstackIcmpHandler { | ... | @@ -122,13 +124,30 @@ public class OpenstackIcmpHandler { |
| 122 | short icmpId = getIcmpId(icmp); | 124 | short icmpId = getIcmpId(icmp); |
| 123 | 125 | ||
| 124 | DeviceId deviceId = context.inPacket().receivedFrom().deviceId(); | 126 | DeviceId deviceId = context.inPacket().receivedFrom().deviceId(); |
| 127 | + PortNumber portNumber = context.inPacket().receivedFrom().port(); | ||
| 125 | if (icmp.getIcmpType() == ICMP.TYPE_ECHO_REQUEST) { | 128 | if (icmp.getIcmpType() == ICMP.TYPE_ECHO_REQUEST) { |
| 126 | //TODO: Considers icmp between internal subnets which are belonged to the same router. | 129 | //TODO: Considers icmp between internal subnets which are belonged to the same router. |
| 127 | 130 | ||
| 128 | OpenstackPortInfo openstackPortInfo = | 131 | OpenstackPortInfo openstackPortInfo = |
| 129 | getOpenstackPortInfo(Ip4Address.valueOf(ipPacket.getSourceAddress()), ethernet.getSourceMAC()); | 132 | getOpenstackPortInfo(Ip4Address.valueOf(ipPacket.getSourceAddress()), ethernet.getSourceMAC()); |
| 130 | 133 | ||
| 131 | - checkNotNull(openstackPortInfo, "openstackPortInfo can not be null"); | 134 | + //checkNotNull(openstackPortInfo, "openstackPortInfo can not be null"); |
| 135 | + if (requestToOpenstackRoutingNetwork(ipPacket.getDestinationAddress())) { | ||
| 136 | + if (openstackPortInfo == null) { | ||
| 137 | + if (config.gatewayBridgeId().equals(context.inPacket().receivedFrom().deviceId().toString())) { | ||
| 138 | + if (portNumber.equals(getPortForAnnotationPortName(deviceId, | ||
| 139 | + config.gatewayExternalInterfaceName()))) { | ||
| 140 | + processIcmpPacketSentToExtenal(ipPacket, icmp, ipPacket.getSourceAddress(), | ||
| 141 | + ethernet.getSourceMAC(), deviceId, portNumber); | ||
| 142 | + return; | ||
| 143 | + } | ||
| 144 | + } | ||
| 145 | + return; | ||
| 146 | + } else { | ||
| 147 | + processIcmpPacketSentToGateway(ipPacket, icmp, openstackPortInfo); | ||
| 148 | + return; | ||
| 149 | + } | ||
| 150 | + } | ||
| 132 | 151 | ||
| 133 | if (ipPacket.getDestinationAddress() == openstackPortInfo.gatewayIP().toInt()) { | 152 | if (ipPacket.getDestinationAddress() == openstackPortInfo.gatewayIP().toInt()) { |
| 134 | processIcmpPacketSentToGateway(ipPacket, icmp, openstackPortInfo); | 153 | processIcmpPacketSentToGateway(ipPacket, icmp, openstackPortInfo); |
| ... | @@ -154,8 +173,27 @@ public class OpenstackIcmpHandler { | ... | @@ -154,8 +173,27 @@ public class OpenstackIcmpHandler { |
| 154 | } | 173 | } |
| 155 | } | 174 | } |
| 156 | 175 | ||
| 176 | + private void processIcmpPacketSentToExtenal(IPv4 icmpRequestIpv4, ICMP icmpRequest, | ||
| 177 | + int destAddr, MacAddress destMac, | ||
| 178 | + DeviceId deviceId, PortNumber portNumber) { | ||
| 179 | + icmpRequest.setChecksum((short) 0); | ||
| 180 | + icmpRequest.setIcmpType(ICMP.TYPE_ECHO_REPLY).resetChecksum(); | ||
| 181 | + icmpRequestIpv4.setSourceAddress(icmpRequestIpv4.getDestinationAddress()) | ||
| 182 | + .setDestinationAddress(destAddr).resetChecksum(); | ||
| 183 | + icmpRequestIpv4.setPayload(icmpRequest); | ||
| 184 | + Ethernet icmpResponseEth = new Ethernet(); | ||
| 185 | + icmpResponseEth.setEtherType(Ethernet.TYPE_IPV4) | ||
| 186 | + .setSourceMACAddress(config.gatewayExternalInterfaceMac()) | ||
| 187 | + .setDestinationMACAddress(destMac).setPayload(icmpRequestIpv4); | ||
| 188 | + TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(portNumber).build(); | ||
| 189 | + OutboundPacket packet = new DefaultOutboundPacket(deviceId, | ||
| 190 | + treatment, ByteBuffer.wrap(icmpResponseEth.serialize())); | ||
| 191 | + packetService.emit(packet); | ||
| 192 | + } | ||
| 193 | + | ||
| 157 | private void processIcmpPacketSentToGateway(IPv4 icmpRequestIpv4, ICMP icmpRequest, | 194 | private void processIcmpPacketSentToGateway(IPv4 icmpRequestIpv4, ICMP icmpRequest, |
| 158 | OpenstackPortInfo openstackPortInfo) { | 195 | OpenstackPortInfo openstackPortInfo) { |
| 196 | + icmpRequest.setChecksum((short) 0); | ||
| 159 | icmpRequest.setIcmpType(ICMP.TYPE_ECHO_REPLY) | 197 | icmpRequest.setIcmpType(ICMP.TYPE_ECHO_REPLY) |
| 160 | .resetChecksum(); | 198 | .resetChecksum(); |
| 161 | 199 | ||
| ... | @@ -272,4 +310,17 @@ public class OpenstackIcmpHandler { | ... | @@ -272,4 +310,17 @@ public class OpenstackIcmpHandler { |
| 272 | 310 | ||
| 273 | return port.number(); | 311 | return port.number(); |
| 274 | } | 312 | } |
| 275 | -} | 313 | + |
| 314 | + private boolean requestToOpenstackRoutingNetwork(int destAddr) { | ||
| 315 | + OpenstackPort port = openstackService.ports().stream() | ||
| 316 | + .filter(p -> p.deviceOwner().equals(NETWORK_ROUTER_GATEWAY) || | ||
| 317 | + p.deviceOwner().equals(NETWORK_FLOATING_IP)) | ||
| 318 | + .filter(p -> p.fixedIps().containsValue( | ||
| 319 | + Ip4Address.valueOf(destAddr))) | ||
| 320 | + .findAny().orElse(null); | ||
| 321 | + if (port == null) { | ||
| 322 | + return false; | ||
| 323 | + } | ||
| 324 | + return true; | ||
| 325 | + } | ||
| 326 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -52,6 +52,7 @@ public class OpenstackRoutingArpHandler { | ... | @@ -52,6 +52,7 @@ public class OpenstackRoutingArpHandler { |
| 52 | private final OpenstackInterfaceService openstackService; | 52 | private final OpenstackInterfaceService openstackService; |
| 53 | private final OpenstackNetworkingConfig config; | 53 | private final OpenstackNetworkingConfig config; |
| 54 | private static final String NETWORK_ROUTER_GATEWAY = "network:router_gateway"; | 54 | private static final String NETWORK_ROUTER_GATEWAY = "network:router_gateway"; |
| 55 | + private static final String NETWORK_FLOATING_IP = "network:floatingip"; | ||
| 55 | 56 | ||
| 56 | /** | 57 | /** |
| 57 | * Default constructor. | 58 | * Default constructor. |
| ... | @@ -106,11 +107,11 @@ public class OpenstackRoutingArpHandler { | ... | @@ -106,11 +107,11 @@ public class OpenstackRoutingArpHandler { |
| 106 | } | 107 | } |
| 107 | 108 | ||
| 108 | IpAddress targetIp = Ip4Address.valueOf(arp.getTargetProtocolAddress()); | 109 | IpAddress targetIp = Ip4Address.valueOf(arp.getTargetProtocolAddress()); |
| 109 | - MacAddress targetMac = getTargetMacForTargetIp(targetIp.getIp4Address()); | ||
| 110 | 110 | ||
| 111 | - if (targetMac == MacAddress.NONE) { | 111 | + if (getTargetMacForTargetIp(targetIp.getIp4Address()) == MacAddress.NONE) { |
| 112 | - return; | 112 | + return; |
| 113 | } | 113 | } |
| 114 | + MacAddress targetMac = MacAddress.valueOf(config.gatewayExternalInterfaceMac()); | ||
| 114 | 115 | ||
| 115 | Ethernet ethReply = ARP.buildArpReply(targetIp.getIp4Address(), | 116 | Ethernet ethReply = ARP.buildArpReply(targetIp.getIp4Address(), |
| 116 | targetMac, ethernet); | 117 | targetMac, ethernet); |
| ... | @@ -127,7 +128,8 @@ public class OpenstackRoutingArpHandler { | ... | @@ -127,7 +128,8 @@ public class OpenstackRoutingArpHandler { |
| 127 | 128 | ||
| 128 | private MacAddress getTargetMacForTargetIp(Ip4Address targetIp) { | 129 | private MacAddress getTargetMacForTargetIp(Ip4Address targetIp) { |
| 129 | OpenstackPort port = openstackService.ports().stream() | 130 | OpenstackPort port = openstackService.ports().stream() |
| 130 | - .filter(p -> p.deviceOwner().equals(NETWORK_ROUTER_GATEWAY)) | 131 | + .filter(p -> p.deviceOwner().equals(NETWORK_ROUTER_GATEWAY) || |
| 132 | + p.deviceOwner().equals(NETWORK_FLOATING_IP)) | ||
| 131 | .filter(p -> p.fixedIps().containsValue(targetIp.getIp4Address())) | 133 | .filter(p -> p.fixedIps().containsValue(targetIp.getIp4Address())) |
| 132 | .findAny().orElse(null); | 134 | .findAny().orElse(null); |
| 133 | 135 | ... | ... |
| ... | @@ -451,7 +451,7 @@ public class OpenstackRoutingRulePopulator { | ... | @@ -451,7 +451,7 @@ public class OpenstackRoutingRulePopulator { |
| 451 | sBuilder.matchEthType(Ethernet.TYPE_IPV4) | 451 | sBuilder.matchEthType(Ethernet.TYPE_IPV4) |
| 452 | .matchIPDst(IpPrefix.valueOf(floatingIP.floatingIpAddress(), PREFIX_LENGTH)); | 452 | .matchIPDst(IpPrefix.valueOf(floatingIP.floatingIpAddress(), PREFIX_LENGTH)); |
| 453 | 453 | ||
| 454 | - tBuilder.setEthSrc(MacAddress.valueOf(config.gatewayExternalInterfaceMac())) | 454 | + tBuilder.setEthSrc(GATEWAYMAC) |
| 455 | .setEthDst(port.macAddress()) | 455 | .setEthDst(port.macAddress()) |
| 456 | .setIpDst(floatingIP.fixedIpAddress()) | 456 | .setIpDst(floatingIP.fixedIpAddress()) |
| 457 | .setTunnelId(getVni(port.networkId())) | 457 | .setTunnelId(getVni(port.networkId())) | ... | ... |
| ... | @@ -126,6 +126,7 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { | ... | @@ -126,6 +126,7 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { |
| 126 | public static final Ip4Address DNS_SERVER_IP = Ip4Address.valueOf("8.8.8.8"); | 126 | public static final Ip4Address DNS_SERVER_IP = Ip4Address.valueOf("8.8.8.8"); |
| 127 | private static final String FORWARD_SLASH = "/"; | 127 | private static final String FORWARD_SLASH = "/"; |
| 128 | private static final int DHCP_INFINITE_LEASE = -1; | 128 | private static final int DHCP_INFINITE_LEASE = -1; |
| 129 | + public static final String SONA_DRIVER_NAME = "sona"; | ||
| 129 | 130 | ||
| 130 | 131 | ||
| 131 | private ApplicationId appId; | 132 | private ApplicationId appId; |
| ... | @@ -418,8 +419,12 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { | ... | @@ -418,8 +419,12 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { |
| 418 | 419 | ||
| 419 | @Override | 420 | @Override |
| 420 | public void process(PacketContext context) { | 421 | public void process(PacketContext context) { |
| 422 | + // FIXME: use GatewayNode list to check if the ARP packet is from GatewayNode's | ||
| 421 | if (context.isHandled()) { | 423 | if (context.isHandled()) { |
| 422 | return; | 424 | return; |
| 425 | + } else if (!SONA_DRIVER_NAME.equals(driverService | ||
| 426 | + .getDriver(context.inPacket().receivedFrom().deviceId()).name())) { | ||
| 427 | + return; | ||
| 423 | } | 428 | } |
| 424 | 429 | ||
| 425 | InboundPacket pkt = context.inPacket(); | 430 | InboundPacket pkt = context.inPacket(); | ... | ... |
-
Please register or login to post a comment