hyungseo Ryu
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
...@@ -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();
......