sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2015 Open Networking Laboratory |
| 3 | * |
| 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 | */ |
| 16 | package org.onosproject.openstackswitching; |
| 17 | |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 18 | import com.google.common.collect.ImmutableSet; |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 19 | import com.google.common.collect.Lists; |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 20 | import org.apache.felix.scr.annotations.Activate; |
| 21 | import org.apache.felix.scr.annotations.Component; |
| 22 | import org.apache.felix.scr.annotations.Deactivate; |
| 23 | import org.apache.felix.scr.annotations.Reference; |
| 24 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
| 25 | import org.apache.felix.scr.annotations.Service; |
| 26 | import org.onlab.packet.Ethernet; |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 27 | import org.onlab.packet.Ip4Address; |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 28 | import org.onosproject.core.ApplicationId; |
| 29 | import org.onosproject.core.CoreService; |
daniel | bb83ebc | 2015-10-29 15:13:06 +0900 | [diff] [blame] | 30 | import org.onosproject.dhcp.DhcpService; |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 31 | import org.onosproject.net.Device; |
| 32 | import org.onosproject.net.DeviceId; |
| 33 | import org.onosproject.net.Port; |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 34 | import org.onosproject.net.config.ConfigFactory; |
| 35 | import org.onosproject.net.config.NetworkConfigEvent; |
| 36 | import org.onosproject.net.config.NetworkConfigListener; |
| 37 | import org.onosproject.net.config.NetworkConfigRegistry; |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 38 | import org.onosproject.net.device.DeviceEvent; |
| 39 | import org.onosproject.net.device.DeviceListener; |
| 40 | import org.onosproject.net.device.DeviceService; |
sanghoshin | f25d2e0 | 2015-11-11 23:07:17 +0900 | [diff] [blame] | 41 | import org.onosproject.net.driver.DriverService; |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 42 | import org.onosproject.net.flowobjective.FlowObjectiveService; |
| 43 | import org.onosproject.net.packet.InboundPacket; |
| 44 | import org.onosproject.net.packet.PacketContext; |
| 45 | import org.onosproject.net.packet.PacketProcessor; |
| 46 | import org.onosproject.net.packet.PacketService; |
| 47 | import org.slf4j.Logger; |
| 48 | import org.slf4j.LoggerFactory; |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 49 | import java.util.List; |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 50 | import java.util.Collection; |
| 51 | import java.util.Set; |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 52 | import java.util.concurrent.ExecutorService; |
| 53 | import java.util.concurrent.Executors; |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 54 | import java.util.stream.Collectors; |
| 55 | |
| 56 | import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY; |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 57 | |
| 58 | @SuppressWarnings("ALL") |
| 59 | @Service |
| 60 | @Component(immediate = true) |
| 61 | /** |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 62 | * Populates forwarding rules for VMs created by Openstack. |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 63 | */ |
| 64 | public class OpenstackSwitchingManager implements OpenstackSwitchingService { |
| 65 | |
| 66 | private static Logger log = LoggerFactory |
| 67 | .getLogger(OpenstackSwitchingManager.class); |
| 68 | |
| 69 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 70 | protected CoreService coreService; |
| 71 | |
| 72 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 73 | protected PacketService packetService; |
| 74 | |
| 75 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 76 | protected DeviceService deviceService; |
| 77 | |
| 78 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 79 | protected FlowObjectiveService flowObjectiveService; |
| 80 | |
daniel | bb83ebc | 2015-10-29 15:13:06 +0900 | [diff] [blame] | 81 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
sanghoshin | f25d2e0 | 2015-11-11 23:07:17 +0900 | [diff] [blame] | 82 | protected DhcpService dhcpService; |
| 83 | |
| 84 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 85 | protected NetworkConfigRegistry cfgService; |
| 86 | |
| 87 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
sanghoshin | f25d2e0 | 2015-11-11 23:07:17 +0900 | [diff] [blame] | 88 | protected DriverService driverService; |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 89 | |
| 90 | private ApplicationId appId; |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 91 | private boolean doNotPushFlows; |
sanghoshin | f25d2e0 | 2015-11-11 23:07:17 +0900 | [diff] [blame] | 92 | private Ip4Address neutronServer; |
| 93 | private Ip4Address keystoneServer; |
| 94 | private String userName; |
| 95 | private String password; |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 96 | private OpenstackArpHandler arpHandler; |
sanghoshin | f25d2e0 | 2015-11-11 23:07:17 +0900 | [diff] [blame] | 97 | private OpenstackRestHandler restHandler; |
daniel | bb83ebc | 2015-10-29 15:13:06 +0900 | [diff] [blame] | 98 | |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 99 | private ExecutorService deviceEventExcutorService = Executors.newFixedThreadPool(10); |
| 100 | |
| 101 | private InternalPacketProcessor internalPacketProcessor = new InternalPacketProcessor(); |
| 102 | private InternalDeviceListener internalDeviceListener = new InternalDeviceListener(); |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 103 | private InternalConfigListener internalConfigListener = new InternalConfigListener(); |
| 104 | private final Set<ConfigFactory> factories = ImmutableSet.of( |
| 105 | new ConfigFactory<ApplicationId, OpenstackSwitchingConfig>(APP_SUBJECT_FACTORY, |
| 106 | OpenstackSwitchingConfig.class, |
| 107 | "openstackswitching") { |
| 108 | @Override |
| 109 | public OpenstackSwitchingConfig createConfig() { |
| 110 | return new OpenstackSwitchingConfig(); |
| 111 | } |
| 112 | } |
| 113 | ); |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 114 | |
| 115 | @Activate |
| 116 | protected void activate() { |
| 117 | appId = coreService |
| 118 | .registerApplication("org.onosproject.openstackswitching"); |
sanghoshin | f25d2e0 | 2015-11-11 23:07:17 +0900 | [diff] [blame] | 119 | |
| 120 | factories.forEach(cfgService::registerConfigFactory); |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 121 | packetService.addProcessor(internalPacketProcessor, PacketProcessor.director(1)); |
| 122 | deviceService.addListener(internalDeviceListener); |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 123 | cfgService.addListener(internalConfigListener); |
daniel | bb83ebc | 2015-10-29 15:13:06 +0900 | [diff] [blame] | 124 | |
sanghoshin | f25d2e0 | 2015-11-11 23:07:17 +0900 | [diff] [blame] | 125 | internalConfigListener.configureNetwork(); |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 126 | |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 127 | log.info("Started"); |
| 128 | } |
| 129 | |
| 130 | @Deactivate |
| 131 | protected void deactivate() { |
| 132 | packetService.removeProcessor(internalPacketProcessor); |
| 133 | deviceService.removeListener(internalDeviceListener); |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 134 | cfgService.removeListener(internalConfigListener); |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 135 | |
| 136 | deviceEventExcutorService.shutdown(); |
| 137 | |
| 138 | log.info("Stopped"); |
| 139 | } |
| 140 | |
| 141 | @Override |
| 142 | public void createPorts(OpenstackPort openstackPort) { |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 143 | registerDhcpInfo(openstackPort); |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 144 | } |
| 145 | |
| 146 | @Override |
| 147 | public void deletePorts() { |
| 148 | |
| 149 | } |
| 150 | |
| 151 | @Override |
| 152 | public void updatePorts() { |
| 153 | |
| 154 | } |
| 155 | |
| 156 | @Override |
| 157 | public void createNetwork(OpenstackNetwork openstackNetwork) { |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 158 | } |
| 159 | |
daniel | bb83ebc | 2015-10-29 15:13:06 +0900 | [diff] [blame] | 160 | @Override |
| 161 | public void createSubnet(OpenstackSubnet openstackSubnet) { |
daniel | bb83ebc | 2015-10-29 15:13:06 +0900 | [diff] [blame] | 162 | } |
| 163 | |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 164 | @Override |
| 165 | public Collection<OpenstackPort> ports(String networkId) { |
sanghoshin | f25d2e0 | 2015-11-11 23:07:17 +0900 | [diff] [blame] | 166 | Collection<OpenstackPort> ports = restHandler.getPorts(); |
| 167 | List<OpenstackPort> portList = ports.stream() |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 168 | .filter(p -> p.networkId().equals(networkId)) |
| 169 | .collect(Collectors.toList()); |
| 170 | |
| 171 | return portList; |
| 172 | } |
| 173 | |
| 174 | @Override |
sanghoshin | f25d2e0 | 2015-11-11 23:07:17 +0900 | [diff] [blame] | 175 | public OpenstackPort port(Port port) { |
| 176 | Collection<OpenstackPort> ports = restHandler.getPorts(); |
| 177 | String uuid = port.annotations().value("portName").substring(3); |
| 178 | return ports.stream() |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 179 | .filter(p -> p.id().startsWith(uuid)) |
sanghoshin | f25d2e0 | 2015-11-11 23:07:17 +0900 | [diff] [blame] | 180 | .findFirst().orElse(null); |
| 181 | } |
| 182 | |
| 183 | @Override |
| 184 | public OpenstackPort port(String portId) { |
| 185 | Collection<OpenstackPort> ports = restHandler.getPorts(); |
| 186 | return ports.stream() |
| 187 | .filter(p -> p.id().equals(portId)) |
| 188 | .findFirst().orElse(null); |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 189 | } |
| 190 | |
| 191 | @Override |
| 192 | public OpenstackNetwork network(String networkId) { |
sanghoshin | f25d2e0 | 2015-11-11 23:07:17 +0900 | [diff] [blame] | 193 | Collection<OpenstackNetwork> networks = restHandler.getNetworks(); |
| 194 | return networks.stream() |
| 195 | .filter(n -> n.id().equals(networkId)) |
| 196 | .findFirst().orElse(null); |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 197 | } |
| 198 | |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 199 | private void processDeviceAdded(Device device) { |
daniel | bb83ebc | 2015-10-29 15:13:06 +0900 | [diff] [blame] | 200 | log.debug("device {} is added", device.id()); |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 201 | } |
| 202 | |
| 203 | private void processPortAdded(Device device, Port port) { |
sanghoshin | f25d2e0 | 2015-11-11 23:07:17 +0900 | [diff] [blame] | 204 | if (!port.annotations().value("portName").equals("vxlan")) { |
| 205 | OpenstackSwitchingRulePopulator rulePopulator = |
| 206 | new OpenstackSwitchingRulePopulator(appId, flowObjectiveService, |
| 207 | deviceService, restHandler, driverService); |
| 208 | rulePopulator.populateSwitchingRules(device, port); |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 209 | } |
| 210 | } |
| 211 | |
| 212 | private void processPortRemoved(Device device, Port port) { |
sanghoshin | f25d2e0 | 2015-11-11 23:07:17 +0900 | [diff] [blame] | 213 | // TODO: Remove flow rules for the VM removed |
daniel | bb83ebc | 2015-10-29 15:13:06 +0900 | [diff] [blame] | 214 | log.debug("port {} is removed", port.toString()); |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 215 | } |
| 216 | |
sanghoshin | 075e3e7 | 2015-11-25 16:34:29 +0900 | [diff] [blame^] | 217 | private void initializeFlowRules() { |
| 218 | OpenstackSwitchingRulePopulator rulePopulator = |
| 219 | new OpenstackSwitchingRulePopulator(appId, flowObjectiveService, |
| 220 | deviceService, restHandler, driverService); |
| 221 | |
| 222 | deviceService.getDevices().forEach(device -> { |
| 223 | log.debug("device {} num of ports {} ", device.id(), |
| 224 | deviceService.getPorts(device.id()).size()); |
| 225 | deviceService.getPorts(device.id()).stream() |
| 226 | .filter(port -> port.annotations().value("portName").startsWith("tap")) |
| 227 | .forEach(vmPort -> { |
| 228 | OpenstackPort osPort = rulePopulator.openstackPort(vmPort); |
| 229 | if (osPort != null) { |
| 230 | rulePopulator.populateSwitchingRules(device, vmPort); |
| 231 | registerDhcpInfo(osPort); |
| 232 | } else { |
| 233 | log.warn("No openstackPort information for port {}", vmPort); |
| 234 | } |
| 235 | } |
| 236 | ); |
| 237 | } |
| 238 | ); |
| 239 | } |
| 240 | |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 241 | private void registerDhcpInfo(OpenstackPort openstackPort) { |
| 242 | Ip4Address ip4Address; |
| 243 | Ip4Address subnetMask; |
| 244 | Ip4Address dhcpServer; |
| 245 | Ip4Address gatewayIPAddress; |
| 246 | Ip4Address domainServer; |
| 247 | OpenstackSubnet openstackSubnet; |
| 248 | |
| 249 | ip4Address = (Ip4Address) openstackPort.fixedIps().values().toArray()[0]; |
| 250 | |
sanghoshin | f25d2e0 | 2015-11-11 23:07:17 +0900 | [diff] [blame] | 251 | openstackSubnet = restHandler.getSubnets().stream() |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 252 | .filter(n -> n.networkId().equals(openstackPort.networkId())) |
| 253 | .findFirst().get(); |
| 254 | |
| 255 | subnetMask = Ip4Address.valueOf(buildSubnetMask(openstackSubnet.cidr())); |
| 256 | gatewayIPAddress = Ip4Address.valueOf(openstackSubnet.gatewayIp()); |
| 257 | dhcpServer = gatewayIPAddress; |
| 258 | // TODO: supports multiple DNS servers |
| 259 | if (openstackSubnet.dnsNameservers().isEmpty()) { |
| 260 | domainServer = Ip4Address.valueOf("8.8.8.8"); |
| 261 | } else { |
| 262 | domainServer = openstackSubnet.dnsNameservers().get(0); |
| 263 | } |
| 264 | List<Ip4Address> options = Lists.newArrayList(); |
| 265 | options.add(subnetMask); |
| 266 | options.add(dhcpServer); |
| 267 | options.add(gatewayIPAddress); |
| 268 | options.add(domainServer); |
| 269 | |
| 270 | dhcpService.setStaticMapping(openstackPort.macAddress(), ip4Address, true, options); |
| 271 | } |
| 272 | |
| 273 | private byte[] buildSubnetMask(String cidr) { |
| 274 | int prefix; |
| 275 | String[] parts = cidr.split("/"); |
| 276 | prefix = Integer.parseInt(parts[1]); |
| 277 | int mask = 0xffffffff << (32 - prefix); |
| 278 | byte[] bytes = new byte[]{(byte) (mask >>> 24), |
| 279 | (byte) (mask >> 16 & 0xff), (byte) (mask >> 8 & 0xff), (byte) (mask & 0xff)}; |
| 280 | |
| 281 | return bytes; |
| 282 | } |
| 283 | |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 284 | |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 285 | |
| 286 | private class InternalPacketProcessor implements PacketProcessor { |
| 287 | |
| 288 | @Override |
| 289 | public void process(PacketContext context) { |
| 290 | |
| 291 | if (context.isHandled()) { |
| 292 | return; |
| 293 | } |
| 294 | |
| 295 | InboundPacket pkt = context.inPacket(); |
| 296 | Ethernet ethernet = pkt.parsed(); |
| 297 | |
| 298 | if (ethernet.getEtherType() == Ethernet.TYPE_ARP) { |
| 299 | arpHandler.processPacketIn(pkt); |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 300 | } |
| 301 | } |
| 302 | } |
| 303 | |
| 304 | private class InternalDeviceListener implements DeviceListener { |
| 305 | |
| 306 | @Override |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 307 | public void event(DeviceEvent deviceEvent) { |
| 308 | deviceEventExcutorService.execute(new InternalEventHandler(deviceEvent)); |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 309 | } |
| 310 | } |
| 311 | |
| 312 | private class InternalEventHandler implements Runnable { |
| 313 | |
| 314 | volatile DeviceEvent deviceEvent; |
| 315 | |
| 316 | InternalEventHandler(DeviceEvent deviceEvent) { |
| 317 | this.deviceEvent = deviceEvent; |
| 318 | } |
| 319 | |
| 320 | @Override |
| 321 | public void run() { |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 322 | |
| 323 | if (doNotPushFlows) { |
| 324 | return; |
| 325 | } |
| 326 | |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 327 | switch (deviceEvent.type()) { |
| 328 | case DEVICE_ADDED: |
| 329 | processDeviceAdded((Device) deviceEvent.subject()); |
| 330 | break; |
| 331 | case DEVICE_UPDATED: |
| 332 | Port port = (Port) deviceEvent.subject(); |
| 333 | if (port.isEnabled()) { |
| 334 | processPortAdded((Device) deviceEvent.subject(), deviceEvent.port()); |
| 335 | } |
| 336 | break; |
| 337 | case DEVICE_AVAILABILITY_CHANGED: |
| 338 | Device device = (Device) deviceEvent.subject(); |
| 339 | if (deviceService.isAvailable(device.id())) { |
| 340 | processDeviceAdded(device); |
| 341 | } |
| 342 | break; |
| 343 | case PORT_ADDED: |
| 344 | processPortAdded((Device) deviceEvent.subject(), deviceEvent.port()); |
| 345 | break; |
| 346 | case PORT_UPDATED: |
| 347 | processPortAdded((Device) deviceEvent.subject(), deviceEvent.port()); |
| 348 | break; |
| 349 | case PORT_REMOVED: |
| 350 | processPortRemoved((Device) deviceEvent.subject(), deviceEvent.port()); |
| 351 | break; |
| 352 | default: |
| 353 | break; |
| 354 | } |
| 355 | } |
| 356 | } |
| 357 | |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 358 | private class InternalConfigListener implements NetworkConfigListener { |
| 359 | |
sanghoshin | f25d2e0 | 2015-11-11 23:07:17 +0900 | [diff] [blame] | 360 | public void configureNetwork() { |
| 361 | OpenstackSwitchingConfig cfg = |
| 362 | cfgService.getConfig(appId, OpenstackSwitchingConfig.class); |
| 363 | if (cfg == null) { |
| 364 | log.error("There is no openstack server information in config."); |
| 365 | return; |
| 366 | } |
| 367 | doNotPushFlows = cfg.doNotPushFlows(); |
| 368 | restHandler = new OpenstackRestHandler(cfg); |
| 369 | arpHandler = new OpenstackArpHandler(restHandler, packetService); |
sanghoshin | 075e3e7 | 2015-11-25 16:34:29 +0900 | [diff] [blame^] | 370 | initializeFlowRules(); |
sanghoshin | f25d2e0 | 2015-11-11 23:07:17 +0900 | [diff] [blame] | 371 | } |
| 372 | |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 373 | @Override |
| 374 | public void event(NetworkConfigEvent event) { |
| 375 | if (((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED || |
| 376 | event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED)) && |
| 377 | event.configClass().equals(OpenstackSwitchingConfig.class)) { |
sanghoshin | f25d2e0 | 2015-11-11 23:07:17 +0900 | [diff] [blame] | 378 | configureNetwork(); |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 379 | } |
| 380 | } |
sanghoshin | f25d2e0 | 2015-11-11 23:07:17 +0900 | [diff] [blame] | 381 | |
| 382 | } |
sanghoshin | 46297d2 | 2015-11-03 17:51:24 +0900 | [diff] [blame] | 383 | |
sanghoshin | 94872a1 | 2015-10-16 18:04:34 +0900 | [diff] [blame] | 384 | private final class PortInfo { |
| 385 | DeviceId deviceId; |
| 386 | String portName; |
| 387 | Ip4Address fixedIp; |
| 388 | Ip4Address hostIp; |
| 389 | |
| 390 | private PortInfo(DeviceId deviceId, String portName, Ip4Address fixedIp, |
| 391 | Ip4Address hostIp) { |
| 392 | this.deviceId = deviceId; |
| 393 | this.portName = portName; |
| 394 | this.fixedIp = fixedIp; |
| 395 | this.hostIp = hostIp; |
| 396 | } |
| 397 | } |
| 398 | |
| 399 | } |