blob: e8b47755f6b586cfc3d1c63ebb9ecfe68df87c6f [file] [log] [blame]
Hyunsun Moon022272f2016-01-11 15:30:42 -08001/*
Brian O'Connor8e57fd52016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Hyunsun Moon022272f2016-01-11 15:30:42 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
alshabibb4d31712016-06-01 18:51:03 -070016package org.opencord.cordvtn.impl;
Hyunsun Moon022272f2016-01-11 15:30:42 -080017
Hyunsun Moonb5f92e52016-02-17 15:02:06 -080018import com.google.common.collect.Maps;
Hyunsun Moon5401aaa2016-06-12 17:40:34 -070019import org.apache.felix.scr.annotations.Activate;
20import org.apache.felix.scr.annotations.Component;
21import org.apache.felix.scr.annotations.Deactivate;
22import org.apache.felix.scr.annotations.Reference;
23import org.apache.felix.scr.annotations.ReferenceCardinality;
Hyunsun Moon022272f2016-01-11 15:30:42 -080024import org.onlab.packet.ARP;
25import org.onlab.packet.EthType;
26import org.onlab.packet.Ethernet;
27import org.onlab.packet.Ip4Address;
28import org.onlab.packet.IpAddress;
29import org.onlab.packet.MacAddress;
Hyunsun Moon4302c2b2017-01-19 14:20:34 +090030import org.onosproject.core.ApplicationId;
31import org.onosproject.core.CoreService;
Hyunsun Moonc031d9b2016-08-04 13:57:22 -070032import org.onosproject.net.DeviceId;
Hyunsun Moon187bf532017-01-19 10:57:40 +090033import org.onosproject.net.Host;
Hyunsun Moonc031d9b2016-08-04 13:57:22 -070034import org.onosproject.net.PortNumber;
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070035import org.onosproject.net.config.NetworkConfigEvent;
36import org.onosproject.net.config.NetworkConfigListener;
Hyunsun Moon187bf532017-01-19 10:57:40 +090037import org.onosproject.net.config.NetworkConfigService;
Hyunsun Moon022272f2016-01-11 15:30:42 -080038import org.onosproject.net.flow.DefaultTrafficSelector;
39import org.onosproject.net.flow.DefaultTrafficTreatment;
40import org.onosproject.net.flow.TrafficSelector;
41import org.onosproject.net.flow.TrafficTreatment;
Hyunsun Moon4302c2b2017-01-19 14:20:34 +090042import org.onosproject.net.host.HostService;
Hyunsun Moon022272f2016-01-11 15:30:42 -080043import org.onosproject.net.packet.DefaultOutboundPacket;
44import org.onosproject.net.packet.PacketContext;
45import org.onosproject.net.packet.PacketPriority;
Hyunsun Moon187bf532017-01-19 10:57:40 +090046import org.onosproject.net.packet.PacketProcessor;
Hyunsun Moon022272f2016-01-11 15:30:42 -080047import org.onosproject.net.packet.PacketService;
Hyunsun Moon4302c2b2017-01-19 14:20:34 +090048import org.opencord.cordvtn.api.Constants;
Hyunsun Moon187bf532017-01-19 10:57:40 +090049import org.opencord.cordvtn.api.CordVtnConfig;
50import org.opencord.cordvtn.api.core.Instance;
Hyunsun Moon4302c2b2017-01-19 14:20:34 +090051import org.opencord.cordvtn.api.core.ServiceNetworkEvent;
52import org.opencord.cordvtn.api.core.ServiceNetworkListener;
53import org.opencord.cordvtn.api.core.ServiceNetworkService;
Hyunsun Moon187bf532017-01-19 10:57:40 +090054import org.opencord.cordvtn.api.net.ServiceNetwork;
Hyunsun Moon022272f2016-01-11 15:30:42 -080055import org.slf4j.Logger;
56
57import java.nio.ByteBuffer;
Hyunsun Moonb5f92e52016-02-17 15:02:06 -080058import java.util.Map;
Hyunsun Moon022272f2016-01-11 15:30:42 -080059import java.util.Optional;
60import java.util.Set;
61
Hyunsun Moon4302c2b2017-01-19 14:20:34 +090062import static com.google.common.base.Preconditions.checkArgument;
Hyunsun Moon022272f2016-01-11 15:30:42 -080063import static com.google.common.base.Preconditions.checkNotNull;
Hyunsun Moon187bf532017-01-19 10:57:40 +090064import static org.opencord.cordvtn.api.net.ServiceNetwork.NetworkType.*;
Hyunsun Moon022272f2016-01-11 15:30:42 -080065import static org.slf4j.LoggerFactory.getLogger;
66
67/**
68 * Handles ARP requests for virtual network service IPs.
69 */
Hyunsun Moon5401aaa2016-06-12 17:40:34 -070070@Component(immediate = true)
Hyunsun Moon4302c2b2017-01-19 14:20:34 +090071public class CordVtnArpProxy {
Hyunsun Moon022272f2016-01-11 15:30:42 -080072 protected final Logger log = getLogger(getClass());
Hyunsun Moon022272f2016-01-11 15:30:42 -080073
Hyunsun Moon5401aaa2016-06-12 17:40:34 -070074 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
75 protected PacketService packetService;
Hyunsun Moon022272f2016-01-11 15:30:42 -080076
Hyunsun Moonc031d9b2016-08-04 13:57:22 -070077 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Hyunsun Moon4302c2b2017-01-19 14:20:34 +090078 protected CoreService coreService;
79
80 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
81 protected HostService hostService;
Hyunsun Moonc031d9b2016-08-04 13:57:22 -070082
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070083 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Hyunsun Moon187bf532017-01-19 10:57:40 +090084 protected NetworkConfigService configService;
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070085
Hyunsun Moon4302c2b2017-01-19 14:20:34 +090086 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
87 protected CordVtnNodeManager nodeManager;
88
89 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
90 protected ServiceNetworkService snetService;
91
Hyunsun Moon5401aaa2016-06-12 17:40:34 -070092 private final PacketProcessor packetProcessor = new InternalPacketProcessor();
Hyunsun Moon8e9bc932017-01-31 21:32:20 +090093 private final Map<IpAddress, MacAddress> gateways = Maps.newConcurrentMap();
Hyunsun Moon022272f2016-01-11 15:30:42 -080094
Hyunsun Moon5401aaa2016-06-12 17:40:34 -070095 private MacAddress privateGatewayMac = MacAddress.NONE;
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070096 private NetworkConfigListener configListener = new InternalConfigListener();
Hyunsun Moon4302c2b2017-01-19 14:20:34 +090097 private ServiceNetworkListener snetListener = new InternalServiceNetworkListener();
98 private ApplicationId appId;
Hyunsun Moon5401aaa2016-06-12 17:40:34 -070099
100 @Activate
101 protected void activate() {
Hyunsun Moon4302c2b2017-01-19 14:20:34 +0900102 appId = coreService.registerApplication(Constants.CORDVTN_APP_ID);
Hyunsun Moon187bf532017-01-19 10:57:40 +0900103 configService.addListener(configListener);
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700104 readConfiguration();
105
Hyunsun Moon5401aaa2016-06-12 17:40:34 -0700106 packetService.addProcessor(packetProcessor, PacketProcessor.director(0));
107 requestPacket();
Hyunsun Moon4302c2b2017-01-19 14:20:34 +0900108
109 snetService.addListener(snetListener);
Hyunsun Moon8e9bc932017-01-31 21:32:20 +0900110 snetService.serviceNetworks().stream()
111 .filter(net -> net.type() == PRIVATE || net.type() == VSG)
112 .filter(net -> net.serviceIp() != null)
113 .forEach(net -> addGateway(net.serviceIp(), privateGatewayMac));
Hyunsun Moon5401aaa2016-06-12 17:40:34 -0700114 }
115
116 @Deactivate
117 protected void deactivate() {
Hyunsun Moon4302c2b2017-01-19 14:20:34 +0900118 snetService.removeListener(snetListener);
Hyunsun Moon5401aaa2016-06-12 17:40:34 -0700119 packetService.removeProcessor(packetProcessor);
Hyunsun Moon187bf532017-01-19 10:57:40 +0900120 configService.removeListener(configListener);
Hyunsun Moon022272f2016-01-11 15:30:42 -0800121 }
122
123 /**
124 * Requests ARP packet.
125 */
Hyunsun Moon5401aaa2016-06-12 17:40:34 -0700126 private void requestPacket() {
Hyunsun Moon022272f2016-01-11 15:30:42 -0800127 TrafficSelector selector = DefaultTrafficSelector.builder()
128 .matchEthType(EthType.EtherType.ARP.ethType().toShort())
129 .build();
130
Hyunsun Moon4302c2b2017-01-19 14:20:34 +0900131 packetService.requestPackets(
132 selector,
133 PacketPriority.CONTROL,
134 appId,
135 Optional.empty());
Hyunsun Moon022272f2016-01-11 15:30:42 -0800136 }
137
138 /**
139 * Cancels ARP packet.
140 */
Hyunsun Moon5401aaa2016-06-12 17:40:34 -0700141 private void cancelPacket() {
Hyunsun Moon022272f2016-01-11 15:30:42 -0800142 TrafficSelector selector = DefaultTrafficSelector.builder()
143 .matchEthType(EthType.EtherType.ARP.ethType().toShort())
144 .build();
145
Hyunsun Moon4302c2b2017-01-19 14:20:34 +0900146 packetService.cancelPackets(
147 selector,
148 PacketPriority.CONTROL,
149 appId,
150 Optional.empty());
Hyunsun Moon022272f2016-01-11 15:30:42 -0800151 }
152
153 /**
Hyunsun Moonb5f92e52016-02-17 15:02:06 -0800154 * Adds a given gateway IP and MAC address to this ARP proxy.
Hyunsun Moon022272f2016-01-11 15:30:42 -0800155 *
Hyunsun Moonb5f92e52016-02-17 15:02:06 -0800156 * @param gatewayIp gateway ip address
157 * @param gatewayMac gateway mac address
Hyunsun Moon022272f2016-01-11 15:30:42 -0800158 */
Hyunsun Moon5401aaa2016-06-12 17:40:34 -0700159 private void addGateway(IpAddress gatewayIp, MacAddress gatewayMac) {
Hyunsun Moonb5f92e52016-02-17 15:02:06 -0800160 checkNotNull(gatewayIp);
Hyunsun Moon4302c2b2017-01-19 14:20:34 +0900161 checkArgument(gatewayMac != null && gatewayMac != MacAddress.NONE,
162 "privateGatewayMac is not configured");
Hyunsun Moon8e9bc932017-01-31 21:32:20 +0900163
164 MacAddress existing = gateways.get(gatewayIp);
165 if (existing != null && !existing.equals(privateGatewayMac) &&
166 gatewayMac.equals(privateGatewayMac)) {
167 // this is public gateway IP and MAC configured via netcfg
168 // don't update with private gateway MAC
169 return;
170 }
171 gateways.put(gatewayIp, gatewayMac);
172 log.debug("Added ARP proxy entry IP:{} MAC:{}", gatewayIp, gatewayMac);
Hyunsun Moon022272f2016-01-11 15:30:42 -0800173 }
174
175 /**
176 * Removes a given service IP address from this ARP proxy.
177 *
Hyunsun Moonb5f92e52016-02-17 15:02:06 -0800178 * @param gatewayIp gateway ip address
Hyunsun Moon022272f2016-01-11 15:30:42 -0800179 */
Hyunsun Moon5401aaa2016-06-12 17:40:34 -0700180 private void removeGateway(IpAddress gatewayIp) {
Hyunsun Moonb5f92e52016-02-17 15:02:06 -0800181 checkNotNull(gatewayIp);
Hyunsun Moon8e9bc932017-01-31 21:32:20 +0900182 MacAddress existing = gateways.get(gatewayIp);
183 if (existing == null) {
184 return;
185 }
186 if (!existing.equals(privateGatewayMac)) {
187 // this is public gateway IP and MAC configured via netcfg
188 // do nothing
189 return;
190 }
191 gateways.remove(gatewayIp);
192 log.debug("Removed ARP proxy entry for IP:{} MAC: {}", gatewayIp, existing);
Hyunsun Moon022272f2016-01-11 15:30:42 -0800193 }
194
195 /**
196 * Emits ARP reply with fake MAC address for a given ARP request.
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700197 * It only handles requests for the registered gateway IPs and host IPs.
Hyunsun Moon022272f2016-01-11 15:30:42 -0800198 *
199 * @param context packet context
200 * @param ethPacket ethernet packet
201 */
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700202 private void processArpRequest(PacketContext context, Ethernet ethPacket) {
Hyunsun Moon022272f2016-01-11 15:30:42 -0800203 ARP arpPacket = (ARP) ethPacket.getPayload();
Hyunsun Moonb6febbe2016-02-12 15:59:53 -0800204 Ip4Address targetIp = Ip4Address.valueOf(arpPacket.getTargetProtocolAddress());
Hyunsun Moonb6febbe2016-02-12 15:59:53 -0800205
Hyunsun Moonb5f92e52016-02-17 15:02:06 -0800206 MacAddress gatewayMac = gateways.get(targetIp);
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700207 MacAddress replyMac = gatewayMac != null ? gatewayMac :
208 getMacFromHostService(targetIp);
Hyunsun Moonb5f92e52016-02-17 15:02:06 -0800209
210 if (replyMac.equals(MacAddress.NONE)) {
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700211 log.trace("Failed to find MAC for {}", targetIp);
212 forwardManagementArpRequest(context, ethPacket);
Hyunsun Moon0d836e22016-02-01 23:30:58 -0800213 return;
214 }
215
Hyunsun Moon022272f2016-01-11 15:30:42 -0800216 Ethernet ethReply = ARP.buildArpReply(
217 targetIp,
Hyunsun Moonb5f92e52016-02-17 15:02:06 -0800218 replyMac,
Hyunsun Moon022272f2016-01-11 15:30:42 -0800219 ethPacket);
220
221 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
222 .setOutput(context.inPacket().receivedFrom().port())
223 .build();
224
225 packetService.emit(new DefaultOutboundPacket(
226 context.inPacket().receivedFrom().deviceId(),
227 treatment,
228 ByteBuffer.wrap(ethReply.serialize())));
229
230 context.block();
231 }
Hyunsun Moon3fc17f72016-01-24 21:47:06 -0800232
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700233 private void processArpReply(PacketContext context, Ethernet ethPacket) {
234 ARP arpPacket = (ARP) ethPacket.getPayload();
235 Ip4Address targetIp = Ip4Address.valueOf(arpPacket.getTargetProtocolAddress());
236
237 DeviceId deviceId = context.inPacket().receivedFrom().deviceId();
238 Host host = hostService.getHostsByIp(targetIp).stream()
239 .filter(h -> h.location().deviceId().equals(deviceId))
240 .findFirst()
241 .orElse(null);
242
243 if (host == null) {
244 // do nothing for the unknown ARP reply
245 log.trace("No host found for {} in {}", targetIp, deviceId);
246 context.block();
247 return;
248 }
249
250 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
251 .setOutput(host.location().port())
252 .build();
253
254 packetService.emit(new DefaultOutboundPacket(
255 deviceId,
256 treatment,
257 ByteBuffer.wrap(ethPacket.serialize())));
258
259 context.block();
260 }
261
262 private void forwardManagementArpRequest(PacketContext context, Ethernet ethPacket) {
263 DeviceId deviceId = context.inPacket().receivedFrom().deviceId();
264 PortNumber hostMgmtPort = nodeManager.hostManagementPort(deviceId);
265 Host host = hostService.getConnectedHosts(context.inPacket().receivedFrom())
266 .stream()
267 .findFirst().orElse(null);
268
269 if (host == null ||
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700270 !Instance.of(host).netType().name().contains("MANAGEMENT") ||
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700271 hostMgmtPort == null) {
272 context.block();
273 return;
274 }
275
276 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
277 .setOutput(hostMgmtPort)
278 .build();
279
280 packetService.emit(new DefaultOutboundPacket(
281 context.inPacket().receivedFrom().deviceId(),
282 treatment,
283 ByteBuffer.wrap(ethPacket.serialize())));
284
285 log.trace("Forward ARP request to management network");
286 context.block();
287 }
288
Hyunsun Moon3fc17f72016-01-24 21:47:06 -0800289 /**
290 * Emits gratuitous ARP when a gateway mac address has been changed.
291 *
Hyunsun Moonb5f92e52016-02-17 15:02:06 -0800292 * @param gatewayIp gateway ip address to update MAC
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700293 * @param instances set of instances to send gratuitous ARP packet
Hyunsun Moon3fc17f72016-01-24 21:47:06 -0800294 */
Hyunsun Moon5401aaa2016-06-12 17:40:34 -0700295 private void sendGratuitousArp(IpAddress gatewayIp, Set<Instance> instances) {
Hyunsun Moon8e9bc932017-01-31 21:32:20 +0900296 MacAddress gatewayMac = gateways.get(gatewayIp);
Hyunsun Moonb5f92e52016-02-17 15:02:06 -0800297 if (gatewayMac == null) {
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700298 log.debug("Gateway {} is not registered to ARP proxy", gatewayIp);
Hyunsun Moonb5f92e52016-02-17 15:02:06 -0800299 return;
300 }
Hyunsun Moon3fc17f72016-01-24 21:47:06 -0800301
Hyunsun Moonb5f92e52016-02-17 15:02:06 -0800302 Ethernet ethArp = buildGratuitousArp(gatewayIp.getIp4Address(), gatewayMac);
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700303 instances.stream().forEach(instance -> {
Hyunsun Moon3fc17f72016-01-24 21:47:06 -0800304 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700305 .setOutput(instance.portNumber())
Hyunsun Moon3fc17f72016-01-24 21:47:06 -0800306 .build();
307
308 packetService.emit(new DefaultOutboundPacket(
Hyunsun Moone7e4bb32016-05-16 04:32:45 -0700309 instance.deviceId(),
Hyunsun Moon3fc17f72016-01-24 21:47:06 -0800310 treatment,
311 ByteBuffer.wrap(ethArp.serialize())));
312 });
313 }
314
315 /**
316 * Builds gratuitous ARP packet with a given IP and MAC address.
317 *
318 * @param ip ip address for TPA and SPA
319 * @param mac new mac address
320 * @return ethernet packet
321 */
322 private Ethernet buildGratuitousArp(IpAddress ip, MacAddress mac) {
323 Ethernet eth = new Ethernet();
324
325 eth.setEtherType(Ethernet.TYPE_ARP);
326 eth.setSourceMACAddress(mac);
327 eth.setDestinationMACAddress(MacAddress.BROADCAST);
328
329 ARP arp = new ARP();
330 arp.setOpCode(ARP.OP_REQUEST);
331 arp.setHardwareType(ARP.HW_TYPE_ETHERNET);
332 arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH);
333 arp.setProtocolType(ARP.PROTO_TYPE_IP);
334 arp.setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH);
335
336 arp.setSenderHardwareAddress(mac.toBytes());
337 arp.setTargetHardwareAddress(MacAddress.BROADCAST.toBytes());
338 arp.setSenderProtocolAddress(ip.getIp4Address().toOctets());
339 arp.setTargetProtocolAddress(ip.getIp4Address().toOctets());
340
341 eth.setPayload(arp);
342 return eth;
343 }
Hyunsun Moonb6febbe2016-02-12 15:59:53 -0800344
345 /**
346 * Returns MAC address of a host with a given target IP address by asking to
347 * host service. It does not support overlapping IP.
348 *
349 * @param targetIp target ip
350 * @return mac address, or NONE mac address if it fails to find the mac
351 */
352 private MacAddress getMacFromHostService(IpAddress targetIp) {
353 checkNotNull(targetIp);
354
355 Host host = hostService.getHostsByIp(targetIp)
356 .stream()
357 .findFirst()
358 .orElse(null);
359
360 if (host != null) {
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700361 log.trace("Found MAC from host service for {}", targetIp);
Hyunsun Moonb6febbe2016-02-12 15:59:53 -0800362 return host.mac();
363 } else {
364 return MacAddress.NONE;
365 }
366 }
Hyunsun Moon5401aaa2016-06-12 17:40:34 -0700367
368 private class InternalPacketProcessor implements PacketProcessor {
369
370 @Override
371 public void process(PacketContext context) {
372 if (context.isHandled()) {
373 return;
374 }
375 Ethernet ethPacket = context.inPacket().parsed();
376 if (ethPacket == null || ethPacket.getEtherType() != Ethernet.TYPE_ARP) {
377 return;
378 }
Hyunsun Moonc031d9b2016-08-04 13:57:22 -0700379
380 ARP arpPacket = (ARP) ethPacket.getPayload();
381 switch (arpPacket.getOpCode()) {
382 case ARP.OP_REQUEST:
383 processArpRequest(context, ethPacket);
384 break;
385 case ARP.OP_REPLY:
386 processArpReply(context, ethPacket);
387 break;
388 default:
389 break;
390 }
Hyunsun Moon5401aaa2016-06-12 17:40:34 -0700391 }
392 }
393
Hyunsun Moon4302c2b2017-01-19 14:20:34 +0900394 private class InternalServiceNetworkListener implements ServiceNetworkListener {
395
396 @Override
397 public boolean isRelevant(ServiceNetworkEvent event) {
398 ServiceNetwork snet = event.subject();
Hyunsun Moon8e9bc932017-01-31 21:32:20 +0900399 return snet.serviceIp() != null;
Hyunsun Moon1e88fef2016-08-04 14:00:35 -0700400 }
401
Hyunsun Moon4302c2b2017-01-19 14:20:34 +0900402 @Override
403 public void event(ServiceNetworkEvent event) {
404 ServiceNetwork snet = event.subject();
405 switch (event.type()) {
406 case SERVICE_NETWORK_CREATED:
407 case SERVICE_NETWORK_UPDATED:
Hyunsun Moon8e9bc932017-01-31 21:32:20 +0900408 addGateway(snet.serviceIp(), privateGatewayMac);
Hyunsun Moon4302c2b2017-01-19 14:20:34 +0900409 break;
410 case SERVICE_NETWORK_REMOVED:
411 removeGateway(snet.serviceIp());
412 break;
413 case SERVICE_PORT_CREATED:
414 case SERVICE_PORT_UPDATED:
415 case SERVICE_PORT_REMOVED:
416 default:
417 // do nothing for the other events
418 break;
419 }
Hyunsun Moon5401aaa2016-06-12 17:40:34 -0700420 }
421 }
422
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700423 private void readConfiguration() {
Hyunsun Moon187bf532017-01-19 10:57:40 +0900424 CordVtnConfig config = configService.getConfig(appId, CordVtnConfig.class);
Hyunsun Moon5401aaa2016-06-12 17:40:34 -0700425 if (config == null) {
426 log.debug("No configuration found");
427 return;
428 }
Hyunsun Moon8e9bc932017-01-31 21:32:20 +0900429 // TODO handle the case that private gateway MAC is changed
Hyunsun Moon5401aaa2016-06-12 17:40:34 -0700430 privateGatewayMac = config.privateGatewayMac();
Hyunsun Moon4302c2b2017-01-19 14:20:34 +0900431 log.debug("Set default service IP MAC address {}", privateGatewayMac);
Hyunsun Moon5401aaa2016-06-12 17:40:34 -0700432
433 config.publicGateways().entrySet().stream().forEach(entry -> {
434 addGateway(entry.getKey(), entry.getValue());
Hyunsun Moon5401aaa2016-06-12 17:40:34 -0700435 });
436 // TODO send gratuitous arp in case the MAC is changed
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700437 }
Hyunsun Moon5401aaa2016-06-12 17:40:34 -0700438
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700439 private class InternalConfigListener implements NetworkConfigListener {
440
441 @Override
Hyunsun Moon4302c2b2017-01-19 14:20:34 +0900442 public boolean isRelevant(NetworkConfigEvent event) {
443 return event.configClass().equals(CordVtnConfig.class);
444 }
445
446 @Override
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700447 public void event(NetworkConfigEvent event) {
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700448
449 switch (event.type()) {
450 case CONFIG_ADDED:
451 case CONFIG_UPDATED:
452 readConfiguration();
453 break;
454 default:
455 break;
456 }
457 }
Hyunsun Moon5401aaa2016-06-12 17:40:34 -0700458 }
Hyunsun Moon022272f2016-01-11 15:30:42 -0800459}