blob: cfcdc4b54e9bc081ece7ebb1ad4d1fa5f1e4b9db [file] [log] [blame]
Hyunsun Moond0e932a2015-09-15 22:39:16 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Hyunsun Moond0e932a2015-09-15 22:39:16 -07003 *
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 */
Hyunsun Moon7f4ed9d2016-04-14 16:13:42 -070016package org.onosproject.cordvtn.impl;
Hyunsun Moond0e932a2015-09-15 22:39:16 -070017
Hyunsun Moone0f3e282016-05-13 18:58:35 -070018import com.google.common.base.Strings;
Hyunsun Moon1d3eac92016-02-03 00:11:11 -080019import com.google.common.collect.Lists;
Hyunsun Moonae39ae82016-02-17 15:02:06 -080020import com.google.common.collect.Maps;
Hyunsun Moon1f145552015-10-08 22:25:30 -070021import com.google.common.collect.Sets;
Hyunsun Moond0e932a2015-09-15 22:39:16 -070022import org.apache.felix.scr.annotations.Activate;
23import org.apache.felix.scr.annotations.Component;
24import org.apache.felix.scr.annotations.Deactivate;
25import org.apache.felix.scr.annotations.Reference;
26import org.apache.felix.scr.annotations.ReferenceCardinality;
27import org.apache.felix.scr.annotations.Service;
Hyunsun Moon42c7b4e2016-01-11 15:30:42 -080028import org.onlab.packet.Ethernet;
Hyunsun Moon1d3eac92016-02-03 00:11:11 -080029import org.onlab.packet.Ip4Address;
Hyunsun Moon9f0814b2015-11-04 17:34:35 -080030import org.onlab.packet.IpAddress;
Hyunsun Moonb77b60f2016-01-15 20:03:18 -080031import org.onlab.packet.MacAddress;
32import org.onlab.packet.VlanId;
Hyunsun Moon7f4ed9d2016-04-14 16:13:42 -070033import org.onosproject.cordvtn.api.CordVtnConfig;
34import org.onosproject.cordvtn.api.CordVtnNode;
35import org.onosproject.cordvtn.api.CordVtnService;
Hyunsun Moon1f145552015-10-08 22:25:30 -070036import org.onosproject.core.ApplicationId;
Hyunsun Moond0e932a2015-09-15 22:39:16 -070037import org.onosproject.core.CoreService;
Hyunsun Moon1d3eac92016-02-03 00:11:11 -080038import org.onosproject.dhcp.DhcpService;
Hyunsun Moonc71231d2015-12-16 20:53:23 -080039import org.onosproject.mastership.MastershipService;
Hyunsun Moonb77b60f2016-01-15 20:03:18 -080040import org.onosproject.net.ConnectPoint;
Hyunsun Moond772f342015-10-28 20:28:16 -070041import org.onosproject.net.DefaultAnnotations;
Hyunsun Moond0e932a2015-09-15 22:39:16 -070042import org.onosproject.net.Host;
Hyunsun Moon9f0814b2015-11-04 17:34:35 -080043import org.onosproject.net.HostId;
Hyunsun Moonb77b60f2016-01-15 20:03:18 -080044import org.onosproject.net.HostLocation;
Hyunsun Moon8539b042015-11-07 22:08:43 -080045import org.onosproject.net.Port;
Hyunsun Moon746956f2016-01-24 21:47:06 -080046import org.onosproject.net.config.ConfigFactory;
47import org.onosproject.net.config.NetworkConfigEvent;
48import org.onosproject.net.config.NetworkConfigListener;
49import org.onosproject.net.config.NetworkConfigRegistry;
Hyunsun Moon746956f2016-01-24 21:47:06 -080050import org.onosproject.net.config.basics.SubjectFactories;
Hyunsun Moond0e932a2015-09-15 22:39:16 -070051import org.onosproject.net.device.DeviceService;
Hyunsun Moonc71231d2015-12-16 20:53:23 -080052import org.onosproject.net.flow.FlowRuleService;
53import org.onosproject.net.group.GroupService;
Hyunsun Moonb77b60f2016-01-15 20:03:18 -080054import org.onosproject.net.host.DefaultHostDescription;
55import org.onosproject.net.host.HostDescription;
Hyunsun Moond0e932a2015-09-15 22:39:16 -070056import org.onosproject.net.host.HostEvent;
57import org.onosproject.net.host.HostListener;
Hyunsun Moonb77b60f2016-01-15 20:03:18 -080058import org.onosproject.net.host.HostProvider;
59import org.onosproject.net.host.HostProviderRegistry;
60import org.onosproject.net.host.HostProviderService;
Hyunsun Moond0e932a2015-09-15 22:39:16 -070061import org.onosproject.net.host.HostService;
Hyunsun Moon42c7b4e2016-01-11 15:30:42 -080062import org.onosproject.net.packet.PacketContext;
63import org.onosproject.net.packet.PacketProcessor;
64import org.onosproject.net.packet.PacketService;
Hyunsun Moonb77b60f2016-01-15 20:03:18 -080065import org.onosproject.net.provider.AbstractProvider;
66import org.onosproject.net.provider.ProviderId;
Hyunsun Moone0f3e282016-05-13 18:58:35 -070067import org.onosproject.xosclient.api.OpenStackAccess;
68import org.onosproject.xosclient.api.VtnPort;
69import org.onosproject.xosclient.api.VtnPortApi;
70import org.onosproject.xosclient.api.VtnPortId;
71import org.onosproject.xosclient.api.VtnService;
Hyunsun Moon4c396632016-05-13 04:17:53 -070072import org.onosproject.xosclient.api.VtnServiceApi;
73import org.onosproject.xosclient.api.VtnServiceId;
Hyunsun Moondd91be22016-04-24 17:43:32 -070074import org.onosproject.xosclient.api.XosAccess;
75import org.onosproject.xosclient.api.XosClientService;
Hyunsun Moond0e932a2015-09-15 22:39:16 -070076import org.slf4j.Logger;
77
Hyunsun Moon1d3eac92016-02-03 00:11:11 -080078import java.util.List;
Hyunsun Moon1f145552015-10-08 22:25:30 -070079import java.util.Map;
Hyunsun Moon32f3b8e2016-03-02 19:27:26 -080080import java.util.Objects;
Hyunsun Moon9f0814b2015-11-04 17:34:35 -080081import java.util.Set;
Hyunsun Moond0e932a2015-09-15 22:39:16 -070082import java.util.concurrent.ExecutorService;
Hyunsun Moon9f0814b2015-11-04 17:34:35 -080083import java.util.stream.Collectors;
Hyunsun Moon32f3b8e2016-03-02 19:27:26 -080084import java.util.stream.StreamSupport;
Hyunsun Moond0e932a2015-09-15 22:39:16 -070085
Hyunsun Moon1f145552015-10-08 22:25:30 -070086import static com.google.common.base.Preconditions.checkNotNull;
Hyunsun Moon746956f2016-01-24 21:47:06 -080087import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
Hyunsun Moond0e932a2015-09-15 22:39:16 -070088import static org.onlab.util.Tools.groupedThreads;
Hyunsun Moond0e932a2015-09-15 22:39:16 -070089import static org.slf4j.LoggerFactory.getLogger;
90
91/**
Hyunsun Moon9f0814b2015-11-04 17:34:35 -080092 * Provisions virtual tenant networks with service chaining capability
93 * in OpenStack environment.
Hyunsun Moond0e932a2015-09-15 22:39:16 -070094 */
95@Component(immediate = true)
96@Service
Hyunsun Moonb77b60f2016-01-15 20:03:18 -080097public class CordVtn extends AbstractProvider implements CordVtnService, HostProvider {
Hyunsun Moond0e932a2015-09-15 22:39:16 -070098
99 protected final Logger log = getLogger(getClass());
100
101 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
102 protected CoreService coreService;
103
104 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Hyunsun Moon746956f2016-01-24 21:47:06 -0800105 protected NetworkConfigRegistry configRegistry;
106
107 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800108 protected HostProviderRegistry hostProviderRegistry;
Hyunsun Moond0e932a2015-09-15 22:39:16 -0700109
110 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Hyunsun Moond0e932a2015-09-15 22:39:16 -0700111 protected DeviceService deviceService;
112
113 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
114 protected HostService hostService;
115
Hyunsun Moon1f145552015-10-08 22:25:30 -0700116 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Hyunsun Moonc71231d2015-12-16 20:53:23 -0800117 protected FlowRuleService flowRuleService;
Hyunsun Moon9f0814b2015-11-04 17:34:35 -0800118
119 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Hyunsun Moon42c7b4e2016-01-11 15:30:42 -0800120 protected PacketService packetService;
121
122 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Hyunsun Moonc71231d2015-12-16 20:53:23 -0800123 protected MastershipService mastershipService;
124
125 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
126 protected GroupService groupService;
127
128 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Hyunsun Moon1d3eac92016-02-03 00:11:11 -0800129 protected DhcpService dhcpService;
130
Hyunsun Moondd91be22016-04-24 17:43:32 -0700131 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
132 protected XosClientService xosClient;
133
Hyunsun Moon746956f2016-01-24 21:47:06 -0800134 private final ConfigFactory configFactory =
135 new ConfigFactory(SubjectFactories.APP_SUBJECT_FACTORY, CordVtnConfig.class, "cordvtn") {
136 @Override
137 public CordVtnConfig createConfig() {
138 return new CordVtnConfig();
139 }
140 };
141
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700142 private static final String XOS_ACCESS_ERROR = "XOS access is not configured";
143 private static final String OPENSTACK_ACCESS_ERROR = "OpenStack access is not configured";
144
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800145 private static final String DEFAULT_TUNNEL = "vxlan";
146 private static final String SERVICE_ID = "serviceId";
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700147 private static final String PORT_ID = "vtnPortId";
Hyunsun Moon6d247342016-02-12 12:48:47 -0800148 private static final String DATA_PLANE_IP = "dataPlaneIp";
149 private static final String DATA_PLANE_INTF = "dataPlaneIntf";
150 private static final String S_TAG = "stag";
Hyunsun Moon98025542016-03-08 04:36:02 -0800151 private static final String VSG_HOST_ID = "vsgHostId";
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700152 private static final String CREATE_TIME = "createTime";
Hyunsun Moon6d247342016-02-12 12:48:47 -0800153
154 private static final Ip4Address DEFAULT_DNS = Ip4Address.valueOf("8.8.8.8");
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800155
Hyunsun Moon746956f2016-01-24 21:47:06 -0800156 private final ExecutorService eventExecutor =
157 newSingleThreadScheduledExecutor(groupedThreads("onos/cordvtn", "event-handler"));
Hyunsun Moond0e932a2015-09-15 22:39:16 -0700158
Hyunsun Moon42c7b4e2016-01-11 15:30:42 -0800159 private final PacketProcessor packetProcessor = new InternalPacketProcessor();
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800160 private final HostListener hostListener = new InternalHostListener();
Hyunsun Moon746956f2016-01-24 21:47:06 -0800161 private final NetworkConfigListener configListener = new InternalConfigListener();
Hyunsun Moon2b530322015-09-23 13:24:35 -0700162
Hyunsun Moon746956f2016-01-24 21:47:06 -0800163 private ApplicationId appId;
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800164 private HostProviderService hostProvider;
Hyunsun Moon9f0814b2015-11-04 17:34:35 -0800165 private CordVtnRuleInstaller ruleInstaller;
Hyunsun Moon42c7b4e2016-01-11 15:30:42 -0800166 private CordVtnArpProxy arpProxy;
Hyunsun Moon576d6872016-04-14 19:04:23 -0700167
Hyunsun Moon4c396632016-05-13 04:17:53 -0700168 private volatile XosAccess xosAccess = null;
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700169 private volatile OpenStackAccess osAccess = null;
Hyunsun Moonae39ae82016-02-17 15:02:06 -0800170 private volatile MacAddress privateGatewayMac = MacAddress.NONE;
Hyunsun Moon8539b042015-11-07 22:08:43 -0800171
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800172 /**
173 * Creates an cordvtn host location provider.
174 */
175 public CordVtn() {
176 super(new ProviderId("host", CORDVTN_APP_ID));
Hyunsun Moon8539b042015-11-07 22:08:43 -0800177 }
Hyunsun Moond0e932a2015-09-15 22:39:16 -0700178
179 @Activate
180 protected void activate() {
Hyunsun Moon1d019182016-05-06 20:13:28 -0700181 appId = coreService.registerApplication(CordVtnService.CORDVTN_APP_ID);
Hyunsun Moonc71231d2015-12-16 20:53:23 -0800182 ruleInstaller = new CordVtnRuleInstaller(appId, flowRuleService,
183 deviceService,
Hyunsun Moonc71231d2015-12-16 20:53:23 -0800184 groupService,
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700185 hostService,
Hyunsun Moonfae776d2016-03-08 18:07:52 -0800186 configRegistry,
Hyunsun Moonc71231d2015-12-16 20:53:23 -0800187 DEFAULT_TUNNEL);
188
Hyunsun Moon9cf43db2016-02-12 15:59:53 -0800189 arpProxy = new CordVtnArpProxy(appId, packetService, hostService);
Hyunsun Moon42c7b4e2016-01-11 15:30:42 -0800190 packetService.addProcessor(packetProcessor, PacketProcessor.director(0));
191 arpProxy.requestPacket();
192
Hyunsun Moond0e932a2015-09-15 22:39:16 -0700193 hostService.addListener(hostListener);
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800194 hostProvider = hostProviderRegistry.register(this);
Hyunsun Moon2b530322015-09-23 13:24:35 -0700195
Hyunsun Moon746956f2016-01-24 21:47:06 -0800196 configRegistry.registerConfigFactory(configFactory);
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700197 configRegistry.addListener(configListener);
Hyunsun Moon746956f2016-01-24 21:47:06 -0800198
Hyunsun Moond0e932a2015-09-15 22:39:16 -0700199 log.info("Started");
200 }
201
202 @Deactivate
203 protected void deactivate() {
Hyunsun Moon746956f2016-01-24 21:47:06 -0800204 hostProviderRegistry.unregister(this);
Hyunsun Moond0e932a2015-09-15 22:39:16 -0700205 hostService.removeListener(hostListener);
Hyunsun Moon746956f2016-01-24 21:47:06 -0800206
Hyunsun Moon42c7b4e2016-01-11 15:30:42 -0800207 packetService.removeProcessor(packetProcessor);
Hyunsun Moon2b530322015-09-23 13:24:35 -0700208
Hyunsun Moon746956f2016-01-24 21:47:06 -0800209 configRegistry.unregisterConfigFactory(configFactory);
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700210 configRegistry.removeListener(configListener);
Hyunsun Moon2b530322015-09-23 13:24:35 -0700211
Hyunsun Moon746956f2016-01-24 21:47:06 -0800212 eventExecutor.shutdown();
Hyunsun Moond0e932a2015-09-15 22:39:16 -0700213 log.info("Stopped");
214 }
215
216 @Override
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800217 public void triggerProbe(Host host) {
218 /*
219 * Note: In CORD deployment, we assume that all hosts are configured.
220 * Therefore no probe is required.
221 */
Hyunsun Moonb219fc42016-01-14 03:42:47 -0800222 }
223
224 @Override
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700225 public void createServiceDependency(VtnServiceId tServiceId, VtnServiceId pServiceId,
Hyunsun Moon640f183e2016-02-10 17:02:37 -0800226 boolean isBidirectional) {
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700227 checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
228 checkNotNull(xosAccess, XOS_ACCESS_ERROR);
229
230 // TODO remove openstack access when XOS provides all information
231 VtnServiceApi serviceApi = xosClient.getClient(xosAccess).vtnService();
232 VtnService tService = serviceApi.service(tServiceId, osAccess);
233 VtnService pService = serviceApi.service(pServiceId, osAccess);
Hyunsun Moonbfc47d12015-12-07 14:06:28 -0800234
Hyunsun Moonc71231d2015-12-16 20:53:23 -0800235 if (tService == null || pService == null) {
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700236 log.error("Failed to create dependency between {} and {}",
237 tServiceId, pServiceId);
Hyunsun Moonc71231d2015-12-16 20:53:23 -0800238 return;
239 }
240
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700241 log.info("Created dependency between {} and {}", tService.name(), pService.name());
Hyunsun Moonc14be422016-04-27 15:06:56 -0500242 ruleInstaller.populateServiceDependencyRules(tService, pService, isBidirectional, true);
Hyunsun Moon699f46b2015-12-04 11:35:25 -0800243 }
244
245 @Override
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700246 public void removeServiceDependency(VtnServiceId tServiceId, VtnServiceId pServiceId) {
247 checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
248 checkNotNull(xosAccess, XOS_ACCESS_ERROR);
249
250 // TODO remove openstack access when XOS provides all information
251 VtnServiceApi serviceApi = xosClient.getClient(xosAccess).vtnService();
252 VtnService tService = serviceApi.service(tServiceId, osAccess);
253 VtnService pService = serviceApi.service(pServiceId, osAccess);
Hyunsun Moonbfc47d12015-12-07 14:06:28 -0800254
Hyunsun Moonc71231d2015-12-16 20:53:23 -0800255 if (tService == null || pService == null) {
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700256 log.error("Failed to remove dependency between {} and {}",
257 tServiceId, pServiceId);
Hyunsun Moonc71231d2015-12-16 20:53:23 -0800258 return;
259 }
260
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700261 log.info("Removed dependency between {} and {}", tService.name(), pService.name());
Hyunsun Moonc14be422016-04-27 15:06:56 -0500262 ruleInstaller.populateServiceDependencyRules(tService, pService, true, false);
Hyunsun Moon699f46b2015-12-04 11:35:25 -0800263 }
264
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800265 @Override
266 public void addServiceVm(CordVtnNode node, ConnectPoint connectPoint) {
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700267 checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
268 checkNotNull(xosAccess, XOS_ACCESS_ERROR);
Hyunsun Moon576d6872016-04-14 19:04:23 -0700269
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800270 Port port = deviceService.getPort(connectPoint.deviceId(), connectPoint.port());
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700271 String portName = port.annotations().value("portName");
272
273 // TODO remove openstack access when XOS provides all information
274 VtnPortApi portApi = xosClient.getClient(xosAccess).vtnPort();
275 VtnPort vtnPort = portApi.vtnPort(portName, osAccess);
276 if (vtnPort == null) {
277 log.warn("Failed to get port information of {}", portName);
Hyunsun Moon8539b042015-11-07 22:08:43 -0800278 return;
279 }
280
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700281 // Added CREATE_TIME intentionally to trigger HOST_UPDATED event for the
282 // existing instances.
Hyunsun Moon6d247342016-02-12 12:48:47 -0800283 DefaultAnnotations.Builder annotations = DefaultAnnotations.builder()
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700284 .set(SERVICE_ID, vtnPort.serviceId().id())
285 .set(PORT_ID, vtnPort.id().id())
Hyunsun Moon6d247342016-02-12 12:48:47 -0800286 .set(DATA_PLANE_IP, node.dpIp().ip().toString())
Hyunsun Moond35420f2016-03-08 21:59:13 -0800287 .set(DATA_PLANE_INTF, node.dpIntf())
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700288 .set(CREATE_TIME, String.valueOf(System.currentTimeMillis()));
Hyunsun Moon6d247342016-02-12 12:48:47 -0800289
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700290 // TODO address service specific task in a separate package
291 String serviceVlan = getServiceVlan(vtnPort);
292 if (!Strings.isNullOrEmpty(serviceVlan)) {
Hyunsun Moon6d247342016-02-12 12:48:47 -0800293 annotations.set(S_TAG, serviceVlan);
294 }
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800295
296 HostDescription hostDesc = new DefaultHostDescription(
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700297 vtnPort.mac(),
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800298 VlanId.NONE,
299 new HostLocation(connectPoint, System.currentTimeMillis()),
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700300 Sets.newHashSet(vtnPort.ip()),
Hyunsun Moon6d247342016-02-12 12:48:47 -0800301 annotations.build());
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800302
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700303 HostId hostId = HostId.hostId(vtnPort.mac());
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800304 hostProvider.hostDetected(hostId, hostDesc, false);
Hyunsun Moon8539b042015-11-07 22:08:43 -0800305 }
306
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800307 @Override
308 public void removeServiceVm(ConnectPoint connectPoint) {
Hyunsun Moon2a225162016-02-17 19:00:50 -0800309 hostService.getConnectedHosts(connectPoint)
Hyunsun Moonc71231d2015-12-16 20:53:23 -0800310 .stream()
Hyunsun Moon2a225162016-02-17 19:00:50 -0800311 .forEach(host -> hostProvider.hostVanished(host.id()));
Hyunsun Moon9f0814b2015-11-04 17:34:35 -0800312 }
313
Hyunsun Moon6d247342016-02-12 12:48:47 -0800314 @Override
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700315 // TODO address service specific task in a separate package
Hyunsun Moon6d247342016-02-12 12:48:47 -0800316 public void updateVirtualSubscriberGateways(HostId vSgHostId, String serviceVlan,
Hyunsun Moonae39ae82016-02-17 15:02:06 -0800317 Map<IpAddress, MacAddress> vSgs) {
Hyunsun Moon98025542016-03-08 04:36:02 -0800318 Host vSgHost = hostService.getHost(vSgHostId);
319 if (vSgHost == null || !vSgHost.annotations().value(S_TAG).equals(serviceVlan)) {
Hyunsun Moon6d247342016-02-12 12:48:47 -0800320 log.debug("Invalid vSG updates for {}", serviceVlan);
321 return;
322 }
323
Hyunsun Moon98025542016-03-08 04:36:02 -0800324 log.info("Updates vSGs in {} with {}", vSgHost.id(), vSgs.toString());
Hyunsun Moonae39ae82016-02-17 15:02:06 -0800325 vSgs.entrySet().stream()
Hyunsun Moon98025542016-03-08 04:36:02 -0800326 .filter(entry -> hostService.getHostsByMac(entry.getValue()).isEmpty())
Hyunsun Moonae39ae82016-02-17 15:02:06 -0800327 .forEach(entry -> addVirtualSubscriberGateway(
Hyunsun Moon98025542016-03-08 04:36:02 -0800328 vSgHost,
Hyunsun Moonae39ae82016-02-17 15:02:06 -0800329 entry.getKey(),
330 entry.getValue(),
331 serviceVlan));
332
Hyunsun Moon98025542016-03-08 04:36:02 -0800333 hostService.getConnectedHosts(vSgHost.location()).stream()
334 .filter(host -> !host.mac().equals(vSgHost.mac()))
Hyunsun Moon2a225162016-02-17 19:00:50 -0800335 .filter(host -> !vSgs.values().contains(host.mac()))
336 .forEach(host -> {
337 log.info("Removed vSG {}", host.toString());
338 hostProvider.hostVanished(host.id());
339 });
Hyunsun Moonae39ae82016-02-17 15:02:06 -0800340 }
341
342 /**
343 * Adds virtual subscriber gateway to the system.
344 *
345 * @param vSgHost host virtual machine of this vSG
346 * @param vSgIp vSG ip address
347 * @param vSgMac vSG mac address
348 * @param serviceVlan service vlan
349 */
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700350 // TODO address service specific task in a separate package
Hyunsun Moon2a225162016-02-17 19:00:50 -0800351 private void addVirtualSubscriberGateway(Host vSgHost, IpAddress vSgIp, MacAddress vSgMac,
352 String serviceVlan) {
Hyunsun Moon98025542016-03-08 04:36:02 -0800353 log.info("vSG with IP({}) MAC({}) added", vSgIp.toString(), vSgMac.toString());
Hyunsun Moonae39ae82016-02-17 15:02:06 -0800354
Hyunsun Moon98025542016-03-08 04:36:02 -0800355 HostId hostId = HostId.hostId(vSgMac);
Hyunsun Moonae39ae82016-02-17 15:02:06 -0800356 DefaultAnnotations.Builder annotations = DefaultAnnotations.builder()
Hyunsun Moon98025542016-03-08 04:36:02 -0800357 .set(S_TAG, serviceVlan)
Hyunsun Moond35420f2016-03-08 21:59:13 -0800358 .set(VSG_HOST_ID, vSgHost.id().toString())
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700359 .set(CREATE_TIME, String.valueOf(System.currentTimeMillis()));
Hyunsun Moonae39ae82016-02-17 15:02:06 -0800360
361 HostDescription hostDesc = new DefaultHostDescription(
362 vSgMac,
363 VlanId.NONE,
364 vSgHost.location(),
365 Sets.newHashSet(vSgIp),
366 annotations.build());
367
368 hostProvider.hostDetected(hostId, hostDesc, false);
Hyunsun Moon6d247342016-02-12 12:48:47 -0800369 }
370
Hyunsun Moon9f0814b2015-11-04 17:34:35 -0800371 /**
Hyunsun Moon32f3b8e2016-03-02 19:27:26 -0800372 * Returns public ip addresses of vSGs running inside a give vSG host.
373 *
374 * @param vSgHost vSG host
375 * @return map of ip and mac address, or empty map
376 */
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700377 // TODO address service specific task in a separate package
Hyunsun Moon32f3b8e2016-03-02 19:27:26 -0800378 private Map<IpAddress, MacAddress> getSubscriberGateways(Host vSgHost) {
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700379 checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
380 checkNotNull(xosAccess, XOS_ACCESS_ERROR);
Hyunsun Moon576d6872016-04-14 19:04:23 -0700381
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700382 String vtnPortId = vSgHost.annotations().value(PORT_ID);
383 String sTag = vSgHost.annotations().value(S_TAG);
Hyunsun Moon32f3b8e2016-03-02 19:27:26 -0800384
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700385 if (Strings.isNullOrEmpty(vtnPortId) || Strings.isNullOrEmpty(sTag)) {
386 log.warn("PORT_ID and S_TAG is not set, ignore {}", vSgHost);
Hyunsun Moon32f3b8e2016-03-02 19:27:26 -0800387 return Maps.newHashMap();
388 }
389
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700390 // TODO remove openstack access when XOS provides all information
391 VtnPortApi portApi = xosClient.getClient(xosAccess).vtnPort();
392 VtnPort vtnPort = portApi.vtnPort(VtnPortId.of(vtnPortId), osAccess);
393 if (vtnPort == null) {
394 log.warn("Failed to get port information of {}", vSgHost);
Hyunsun Moon32f3b8e2016-03-02 19:27:26 -0800395 return Maps.newHashMap();
396 }
397
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700398 if (!sTag.equals(getServiceVlan(vtnPort))) {
399 log.error("Host({}) s-tag does not match with VTN port s-tag", vSgHost);
400 return Maps.newHashMap();
Hyunsun Moonbfc47d12015-12-07 14:06:28 -0800401 }
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700402 return vtnPort.addressPairs();
Hyunsun Moonbfc47d12015-12-07 14:06:28 -0800403 }
404
405 /**
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700406 * Returns s-tag from a given VTN port.
Hyunsun Moon9f0814b2015-11-04 17:34:35 -0800407 *
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700408 * @param vtnPort vtn port
Hyunsun Moon6d247342016-02-12 12:48:47 -0800409 * @return s-tag string
410 */
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700411 // TODO address service specific task in a separate package
412 private String getServiceVlan(VtnPort vtnPort) {
413 checkNotNull(vtnPort);
Hyunsun Moon6d247342016-02-12 12:48:47 -0800414
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700415 String portName = vtnPort.name();
Hyunsun Moon576d6872016-04-14 19:04:23 -0700416 if (portName != null && portName.startsWith(S_TAG)) {
417 return portName.split("-")[1];
Hyunsun Moon6d247342016-02-12 12:48:47 -0800418 } else {
419 return null;
420 }
421 }
422
423 /**
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700424 * Returns instances with a given network service.
Hyunsun Moon32f3b8e2016-03-02 19:27:26 -0800425 *
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700426 * @param serviceId service id
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800427 * @return set of hosts
428 */
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700429 private Set<Host> getInstances(VtnServiceId serviceId) {
Hyunsun Moon32f3b8e2016-03-02 19:27:26 -0800430 return StreamSupport.stream(hostService.getHosts().spliterator(), false)
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700431 .filter(host -> Objects.equals(
432 serviceId.id(),
433 host.annotations().value(SERVICE_ID)))
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800434 .collect(Collectors.toSet());
Hyunsun Moon6d247342016-02-12 12:48:47 -0800435 }
436
437 /**
Hyunsun Moon1d3eac92016-02-03 00:11:11 -0800438 * Registers static DHCP lease for a given host.
439 *
440 * @param host host
441 * @param service cord service
442 */
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700443 private void registerDhcpLease(Host host, VtnService service) {
Hyunsun Moon1d3eac92016-02-03 00:11:11 -0800444 List<Ip4Address> options = Lists.newArrayList();
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700445 options.add(Ip4Address.makeMaskPrefix(service.subnet().prefixLength()));
Hyunsun Moon1d3eac92016-02-03 00:11:11 -0800446 options.add(service.serviceIp().getIp4Address());
447 options.add(service.serviceIp().getIp4Address());
448 options.add(DEFAULT_DNS);
449
450 log.debug("Set static DHCP mapping for {}", host.mac());
451 dhcpService.setStaticMapping(host.mac(),
452 host.ipAddresses().stream().findFirst().get().getIp4Address(),
453 true,
454 options);
455 }
456
457 /**
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800458 * Handles VM detected situation.
459 *
460 * @param host host
461 */
462 private void serviceVmAdded(Host host) {
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700463 checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
464 checkNotNull(xosAccess, XOS_ACCESS_ERROR);
Hyunsun Moon576d6872016-04-14 19:04:23 -0700465
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700466 // TODO address service specific task in a separate package
Hyunsun Moon98025542016-03-08 04:36:02 -0800467 String serviceVlan = host.annotations().value(S_TAG);
468 if (serviceVlan != null) {
469 virtualSubscriberGatewayAdded(host, serviceVlan);
470 }
471
Hyunsun Moonc14be422016-04-27 15:06:56 -0500472 String serviceId = host.annotations().value(SERVICE_ID);
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700473 if (Strings.isNullOrEmpty(serviceId)) {
474 // ignore this host, it is not a service instance
Hyunsun Moonae39ae82016-02-17 15:02:06 -0800475 return;
476 }
477
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700478 log.info("Instance is detected {}", host);
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800479
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700480 // TODO remove openstack access when XOS provides all information
481 VtnServiceApi serviceApi = xosClient.getClient(xosAccess).vtnService();
482 VtnService service = serviceApi.service(VtnServiceId.of(serviceId), osAccess);
Hyunsun Moond52bffc2016-01-29 18:57:05 -0800483 if (service == null) {
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700484 log.warn("Failed to get VtnService for {}", serviceId);
Hyunsun Moond52bffc2016-01-29 18:57:05 -0800485 return;
486 }
487
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700488 switch (service.networkType()) {
Hyunsun Moon1e5caeb2016-03-01 16:36:23 -0800489 case MANAGEMENT:
490 ruleInstaller.populateManagementNetworkRules(host, service);
491 break;
492 case PRIVATE:
Hyunsun Moon1e5caeb2016-03-01 16:36:23 -0800493 arpProxy.addGateway(service.serviceIp(), privateGatewayMac);
Hyunsun Moon098cda82016-03-03 13:27:44 -0800494 case PUBLIC:
Hyunsun Moon1e5caeb2016-03-01 16:36:23 -0800495 default:
Hyunsun Moondd91be22016-04-24 17:43:32 -0700496 // TODO get bidirectional information from XOS once XOS supports
497 service.tenantServices().stream().forEach(
498 tServiceId -> createServiceDependency(tServiceId, service.id(), true));
499 service.providerServices().stream().forEach(
500 pServiceId -> createServiceDependency(service.id(), pServiceId, true));
501
Hyunsun Moonc14be422016-04-27 15:06:56 -0500502 ruleInstaller.updateProviderServiceGroup(service);
Hyunsun Moon1e5caeb2016-03-01 16:36:23 -0800503 // sends gratuitous ARP here for the case of adding existing VMs
504 // when ONOS or cordvtn app is restarted
505 arpProxy.sendGratuitousArpForGateway(service.serviceIp(), Sets.newHashSet(host));
506 break;
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800507 }
508
Hyunsun Moon1d3eac92016-02-03 00:11:11 -0800509 registerDhcpLease(host, service);
Hyunsun Moonc14be422016-04-27 15:06:56 -0500510 ruleInstaller.populateBasicConnectionRules(host, service, true);
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800511 }
512
513 /**
514 * Handles VM removed situation.
515 *
516 * @param host host
517 */
518 private void serviceVmRemoved(Host host) {
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700519 checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
520 checkNotNull(xosAccess, XOS_ACCESS_ERROR);
Hyunsun Moon576d6872016-04-14 19:04:23 -0700521
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700522 // TODO address service specific task in a separate package
Hyunsun Moonc14be422016-04-27 15:06:56 -0500523 if (host.annotations().value(S_TAG) != null) {
Hyunsun Moon98025542016-03-08 04:36:02 -0800524 virtualSubscriberGatewayRemoved(host);
525 }
526
Hyunsun Moonc14be422016-04-27 15:06:56 -0500527 String serviceId = host.annotations().value(SERVICE_ID);
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700528 if (Strings.isNullOrEmpty(serviceId)) {
529 // ignore this host, it is not a service instance
Hyunsun Moon1d3eac92016-02-03 00:11:11 -0800530 return;
531 }
532
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700533 log.info("Instance is vanished {}", host);
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800534
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700535 // TODO remove openstack access when XOS provides all information
536 VtnServiceApi vtnServiceApi = xosClient.getClient(xosAccess).vtnService();
537 VtnService service = vtnServiceApi.service(VtnServiceId.of(serviceId), osAccess);
Hyunsun Moond52bffc2016-01-29 18:57:05 -0800538 if (service == null) {
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700539 log.warn("Failed to get VtnService for {}", serviceId);
Hyunsun Moond52bffc2016-01-29 18:57:05 -0800540 return;
541 }
542
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700543 // TODO need to consider the case that the service is removed also
544 switch (service.networkType()) {
Hyunsun Moon1e5caeb2016-03-01 16:36:23 -0800545 case MANAGEMENT:
Hyunsun Moon1e5caeb2016-03-01 16:36:23 -0800546 break;
547 case PRIVATE:
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700548 if (getInstances(VtnServiceId.of(serviceId)).isEmpty()) {
Hyunsun Moon1e5caeb2016-03-01 16:36:23 -0800549 arpProxy.removeGateway(service.serviceIp());
550 }
Hyunsun Moon098cda82016-03-03 13:27:44 -0800551 case PUBLIC:
Hyunsun Moon1e5caeb2016-03-01 16:36:23 -0800552 default:
Hyunsun Moondd91be22016-04-24 17:43:32 -0700553 if (!service.tenantServices().isEmpty()) {
Hyunsun Moonc14be422016-04-27 15:06:56 -0500554 ruleInstaller.updateProviderServiceGroup(service);
555 }
556 if (!service.providerServices().isEmpty()) {
557 ruleInstaller.updateTenantServiceVm(host, service);
Hyunsun Moondd91be22016-04-24 17:43:32 -0700558 }
Hyunsun Moon1e5caeb2016-03-01 16:36:23 -0800559 break;
Hyunsun Moond0e932a2015-09-15 22:39:16 -0700560 }
Hyunsun Moonc14be422016-04-27 15:06:56 -0500561
562 dhcpService.removeStaticMapping(host.mac());
563 ruleInstaller.populateBasicConnectionRules(host, service, false);
Hyunsun Moond0e932a2015-09-15 22:39:16 -0700564 }
565
Hyunsun Moon98025542016-03-08 04:36:02 -0800566
567 /**
568 * Handles virtual subscriber gateway VM or container.
569 *
570 * @param host new host with stag, it can be vsg VM or vsg
571 * @param serviceVlan service vlan
572 */
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700573 // TODO address service specific task in a separate package
Hyunsun Moon98025542016-03-08 04:36:02 -0800574 private void virtualSubscriberGatewayAdded(Host host, String serviceVlan) {
575 Map<IpAddress, MacAddress> vSgs;
576 Host vSgHost;
577
578 String vSgHostId = host.annotations().value(VSG_HOST_ID);
579 if (vSgHostId == null) {
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700580 log.info("vSG VM detected {}", host.id());
Hyunsun Moon98025542016-03-08 04:36:02 -0800581
582 vSgHost = host;
583 vSgs = getSubscriberGateways(vSgHost);
584 vSgs.entrySet().stream().forEach(entry -> addVirtualSubscriberGateway(
585 vSgHost,
586 entry.getKey(),
587 entry.getValue(),
588 serviceVlan));
589 } else {
590 vSgHost = hostService.getHost(HostId.hostId(vSgHostId));
591 if (vSgHost == null) {
592 return;
593 }
594
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700595 log.info("vSG detected {}", host.id());
Hyunsun Moon98025542016-03-08 04:36:02 -0800596 vSgs = getSubscriberGateways(vSgHost);
597 }
598
599 ruleInstaller.populateSubscriberGatewayRules(vSgHost, vSgs.keySet());
600 }
601
602 /**
603 * Handles virtual subscriber gateway removed.
604 *
605 * @param vSg vsg host to remove
606 */
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700607 // TODO address service specific task in a separate package
Hyunsun Moon98025542016-03-08 04:36:02 -0800608 private void virtualSubscriberGatewayRemoved(Host vSg) {
609 String vSgHostId = vSg.annotations().value(VSG_HOST_ID);
610 if (vSgHostId == null) {
611 return;
612 }
613
614 Host vSgHost = hostService.getHost(HostId.hostId(vSgHostId));
615 if (vSgHost == null) {
616 return;
617 }
618
619 log.info("vSG removed {}", vSg.id());
620 Map<IpAddress, MacAddress> vSgs = getSubscriberGateways(vSgHost);
621 ruleInstaller.populateSubscriberGatewayRules(vSgHost, vSgs.keySet());
622 }
623
Hyunsun Moon746956f2016-01-24 21:47:06 -0800624 /**
625 * Sets service network gateway MAC address and sends out gratuitous ARP to all
626 * VMs to update the gateway MAC address.
627 *
Hyunsun Moonae39ae82016-02-17 15:02:06 -0800628 * @param newMac mac address to update
Hyunsun Moon746956f2016-01-24 21:47:06 -0800629 */
Hyunsun Moonae39ae82016-02-17 15:02:06 -0800630 private void setPrivateGatewayMac(MacAddress newMac) {
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700631 checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
632 checkNotNull(xosAccess, XOS_ACCESS_ERROR);
Hyunsun Moondd91be22016-04-24 17:43:32 -0700633
Hyunsun Moonae39ae82016-02-17 15:02:06 -0800634 if (newMac == null || newMac.equals(privateGatewayMac)) {
635 // no updates, do nothing
636 return;
Hyunsun Moon746956f2016-01-24 21:47:06 -0800637 }
638
Hyunsun Moonae39ae82016-02-17 15:02:06 -0800639 privateGatewayMac = newMac;
640 log.debug("Set service gateway MAC address to {}", privateGatewayMac.toString());
641
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700642 VtnServiceApi vtnServiceApi = xosClient.getClient(xosAccess).vtnService();
643 vtnServiceApi.services().stream().forEach(serviceId -> {
644 VtnService service = vtnServiceApi.service(serviceId, osAccess);
Hyunsun Moon746956f2016-01-24 21:47:06 -0800645 if (service != null) {
Hyunsun Moonae39ae82016-02-17 15:02:06 -0800646 arpProxy.addGateway(service.serviceIp(), privateGatewayMac);
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700647 arpProxy.sendGratuitousArpForGateway(service.serviceIp(), getInstances(serviceId));
Hyunsun Moon746956f2016-01-24 21:47:06 -0800648 }
649 });
650 }
651
652 /**
Hyunsun Moonae39ae82016-02-17 15:02:06 -0800653 * Sets public gateway MAC address.
654 *
655 * @param publicGateways gateway ip and mac address pairs
656 */
657 private void setPublicGatewayMac(Map<IpAddress, MacAddress> publicGateways) {
658 publicGateways.entrySet()
659 .stream()
660 .forEach(entry -> {
661 arpProxy.addGateway(entry.getKey(), entry.getValue());
Hyunsun Moon576d6872016-04-14 19:04:23 -0700662 log.debug("Added public gateway IP {}, MAC {}",
663 entry.getKey().toString(), entry.getValue().toString());
Hyunsun Moonae39ae82016-02-17 15:02:06 -0800664 });
665 // TODO notice gateway MAC change to VMs holds this gateway IP
666 }
667
668 /**
Hyunsun Moon746956f2016-01-24 21:47:06 -0800669 * Updates configurations.
670 */
671 private void readConfiguration() {
672 CordVtnConfig config = configRegistry.getConfig(appId, CordVtnConfig.class);
673 if (config == null) {
674 log.debug("No configuration found");
675 return;
676 }
677
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700678 xosAccess = config.xosAccess();
679 osAccess = config.openstackAccess();
680
Hyunsun Moonae39ae82016-02-17 15:02:06 -0800681 setPrivateGatewayMac(config.privateGatewayMac());
682 setPublicGatewayMac(config.publicGateways());
Hyunsun Moon576d6872016-04-14 19:04:23 -0700683 }
Hyunsun Moon746956f2016-01-24 21:47:06 -0800684
Hyunsun Moond0e932a2015-09-15 22:39:16 -0700685 private class InternalHostListener implements HostListener {
686
687 @Override
688 public void event(HostEvent event) {
Hyunsun Moonb77b60f2016-01-15 20:03:18 -0800689 Host host = event.subject();
Hyunsun Moond35420f2016-03-08 21:59:13 -0800690 if (!mastershipService.isLocalMaster(host.location().deviceId())) {
691 // do not allow to proceed without mastership
692 return;
693 }
Hyunsun Moond0e932a2015-09-15 22:39:16 -0700694
695 switch (event.type()) {
Hyunsun Moond35420f2016-03-08 21:59:13 -0800696 case HOST_UPDATED:
Hyunsun Moond0e932a2015-09-15 22:39:16 -0700697 case HOST_ADDED:
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700698 eventExecutor.execute(() -> serviceVmAdded(host));
Hyunsun Moond0e932a2015-09-15 22:39:16 -0700699 break;
700 case HOST_REMOVED:
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700701 eventExecutor.execute(() -> serviceVmRemoved(host));
Hyunsun Moond0e932a2015-09-15 22:39:16 -0700702 break;
703 default:
704 break;
705 }
706 }
707 }
708
Hyunsun Moon42c7b4e2016-01-11 15:30:42 -0800709 private class InternalPacketProcessor implements PacketProcessor {
710
711 @Override
712 public void process(PacketContext context) {
713 if (context.isHandled()) {
714 return;
715 }
716
717 Ethernet ethPacket = context.inPacket().parsed();
Hyunsun Moon746956f2016-01-24 21:47:06 -0800718 if (ethPacket == null || ethPacket.getEtherType() != Ethernet.TYPE_ARP) {
Hyunsun Moon42c7b4e2016-01-11 15:30:42 -0800719 return;
720 }
721
Hyunsun Moonae39ae82016-02-17 15:02:06 -0800722 arpProxy.processArpPacket(context, ethPacket);
Hyunsun Moon746956f2016-01-24 21:47:06 -0800723 }
724 }
725
726 private class InternalConfigListener implements NetworkConfigListener {
727
728 @Override
729 public void event(NetworkConfigEvent event) {
730 if (!event.configClass().equals(CordVtnConfig.class)) {
Hyunsun Moon42c7b4e2016-01-11 15:30:42 -0800731 return;
732 }
733
Hyunsun Moon746956f2016-01-24 21:47:06 -0800734 switch (event.type()) {
735 case CONFIG_ADDED:
736 case CONFIG_UPDATED:
737 log.info("Network configuration changed");
738 eventExecutor.execute(CordVtn.this::readConfiguration);
739 break;
740 default:
741 break;
742 }
Hyunsun Moon42c7b4e2016-01-11 15:30:42 -0800743 }
744 }
Hyunsun Moond0e932a2015-09-15 22:39:16 -0700745}