Committed by
Gerrit Code Review
CORD-483 Made virtual network gateway MAC address configurable
- Added 'gatewayMAC' field to network config for cordvtn - Implemented to send gratuitous ARP when gateway MAC is updated Change-Id: I4f9050f4be64f04e0568515bbb95474513bbe057
Showing
4 changed files
with
191 additions
and
39 deletions
| ... | @@ -36,6 +36,12 @@ import org.onosproject.net.HostId; | ... | @@ -36,6 +36,12 @@ import org.onosproject.net.HostId; |
| 36 | import org.onosproject.net.HostLocation; | 36 | import org.onosproject.net.HostLocation; |
| 37 | import org.onosproject.net.Port; | 37 | import org.onosproject.net.Port; |
| 38 | import org.onosproject.net.SparseAnnotations; | 38 | import org.onosproject.net.SparseAnnotations; |
| 39 | +import org.onosproject.net.config.ConfigFactory; | ||
| 40 | +import org.onosproject.net.config.NetworkConfigEvent; | ||
| 41 | +import org.onosproject.net.config.NetworkConfigListener; | ||
| 42 | +import org.onosproject.net.config.NetworkConfigRegistry; | ||
| 43 | +import org.onosproject.net.config.NetworkConfigService; | ||
| 44 | +import org.onosproject.net.config.basics.SubjectFactories; | ||
| 39 | import org.onosproject.net.device.DeviceService; | 45 | import org.onosproject.net.device.DeviceService; |
| 40 | import org.onosproject.net.driver.DriverService; | 46 | import org.onosproject.net.driver.DriverService; |
| 41 | import org.onosproject.net.flow.FlowRuleService; | 47 | import org.onosproject.net.flow.FlowRuleService; |
| ... | @@ -62,10 +68,10 @@ import org.slf4j.Logger; | ... | @@ -62,10 +68,10 @@ import org.slf4j.Logger; |
| 62 | import java.util.Map; | 68 | import java.util.Map; |
| 63 | import java.util.Set; | 69 | import java.util.Set; |
| 64 | import java.util.concurrent.ExecutorService; | 70 | import java.util.concurrent.ExecutorService; |
| 65 | -import java.util.concurrent.Executors; | ||
| 66 | import java.util.stream.Collectors; | 71 | import java.util.stream.Collectors; |
| 67 | 72 | ||
| 68 | import static com.google.common.base.Preconditions.checkNotNull; | 73 | import static com.google.common.base.Preconditions.checkNotNull; |
| 74 | +import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; | ||
| 69 | import static org.onlab.util.Tools.groupedThreads; | 75 | import static org.onlab.util.Tools.groupedThreads; |
| 70 | import static org.slf4j.LoggerFactory.getLogger; | 76 | import static org.slf4j.LoggerFactory.getLogger; |
| 71 | 77 | ||
| ... | @@ -83,6 +89,12 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -83,6 +89,12 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
| 83 | protected CoreService coreService; | 89 | protected CoreService coreService; |
| 84 | 90 | ||
| 85 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 91 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 92 | + protected NetworkConfigRegistry configRegistry; | ||
| 93 | + | ||
| 94 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 95 | + protected NetworkConfigService configService; | ||
| 96 | + | ||
| 97 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 86 | protected HostProviderRegistry hostProviderRegistry; | 98 | protected HostProviderRegistry hostProviderRegistry; |
| 87 | 99 | ||
| 88 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 100 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| ... | @@ -109,21 +121,31 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -109,21 +121,31 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
| 109 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 121 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 110 | protected OpenstackSwitchingService openstackService; | 122 | protected OpenstackSwitchingService openstackService; |
| 111 | 123 | ||
| 112 | - private static final int NUM_THREADS = 1; | 124 | + private final ConfigFactory configFactory = |
| 125 | + new ConfigFactory(SubjectFactories.APP_SUBJECT_FACTORY, CordVtnConfig.class, "cordvtn") { | ||
| 126 | + @Override | ||
| 127 | + public CordVtnConfig createConfig() { | ||
| 128 | + return new CordVtnConfig(); | ||
| 129 | + } | ||
| 130 | + }; | ||
| 131 | + | ||
| 113 | private static final String DEFAULT_TUNNEL = "vxlan"; | 132 | private static final String DEFAULT_TUNNEL = "vxlan"; |
| 114 | private static final String SERVICE_ID = "serviceId"; | 133 | private static final String SERVICE_ID = "serviceId"; |
| 115 | private static final String LOCATION_IP = "locationIp"; | 134 | private static final String LOCATION_IP = "locationIp"; |
| 116 | private static final String OPENSTACK_VM_ID = "openstackVmId"; | 135 | private static final String OPENSTACK_VM_ID = "openstackVmId"; |
| 117 | 136 | ||
| 118 | - private final ExecutorService eventExecutor = Executors | 137 | + private final ExecutorService eventExecutor = |
| 119 | - .newFixedThreadPool(NUM_THREADS, groupedThreads("onos/cordvtn", "event-handler")); | 138 | + newSingleThreadScheduledExecutor(groupedThreads("onos/cordvtn", "event-handler")); |
| 120 | 139 | ||
| 121 | private final PacketProcessor packetProcessor = new InternalPacketProcessor(); | 140 | private final PacketProcessor packetProcessor = new InternalPacketProcessor(); |
| 122 | private final HostListener hostListener = new InternalHostListener(); | 141 | private final HostListener hostListener = new InternalHostListener(); |
| 142 | + private final NetworkConfigListener configListener = new InternalConfigListener(); | ||
| 123 | 143 | ||
| 144 | + private ApplicationId appId; | ||
| 124 | private HostProviderService hostProvider; | 145 | private HostProviderService hostProvider; |
| 125 | private CordVtnRuleInstaller ruleInstaller; | 146 | private CordVtnRuleInstaller ruleInstaller; |
| 126 | private CordVtnArpProxy arpProxy; | 147 | private CordVtnArpProxy arpProxy; |
| 148 | + private volatile MacAddress gatewayMac = MacAddress.NONE; | ||
| 127 | 149 | ||
| 128 | /** | 150 | /** |
| 129 | * Creates an cordvtn host location provider. | 151 | * Creates an cordvtn host location provider. |
| ... | @@ -134,8 +156,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -134,8 +156,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
| 134 | 156 | ||
| 135 | @Activate | 157 | @Activate |
| 136 | protected void activate() { | 158 | protected void activate() { |
| 137 | - ApplicationId appId = coreService.registerApplication("org.onosproject.cordvtn"); | 159 | + appId = coreService.registerApplication("org.onosproject.cordvtn"); |
| 138 | - | ||
| 139 | ruleInstaller = new CordVtnRuleInstaller(appId, flowRuleService, | 160 | ruleInstaller = new CordVtnRuleInstaller(appId, flowRuleService, |
| 140 | deviceService, | 161 | deviceService, |
| 141 | driverService, | 162 | driverService, |
| ... | @@ -150,17 +171,24 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -150,17 +171,24 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
| 150 | hostService.addListener(hostListener); | 171 | hostService.addListener(hostListener); |
| 151 | hostProvider = hostProviderRegistry.register(this); | 172 | hostProvider = hostProviderRegistry.register(this); |
| 152 | 173 | ||
| 174 | + configRegistry.registerConfigFactory(configFactory); | ||
| 175 | + configService.addListener(configListener); | ||
| 176 | + readConfiguration(); | ||
| 177 | + | ||
| 153 | log.info("Started"); | 178 | log.info("Started"); |
| 154 | } | 179 | } |
| 155 | 180 | ||
| 156 | @Deactivate | 181 | @Deactivate |
| 157 | protected void deactivate() { | 182 | protected void deactivate() { |
| 183 | + hostProviderRegistry.unregister(this); | ||
| 158 | hostService.removeListener(hostListener); | 184 | hostService.removeListener(hostListener); |
| 185 | + | ||
| 159 | packetService.removeProcessor(packetProcessor); | 186 | packetService.removeProcessor(packetProcessor); |
| 160 | 187 | ||
| 161 | - eventExecutor.shutdown(); | 188 | + configRegistry.unregisterConfigFactory(configFactory); |
| 162 | - hostProviderRegistry.unregister(this); | 189 | + configService.removeListener(configListener); |
| 163 | 190 | ||
| 191 | + eventExecutor.shutdown(); | ||
| 164 | log.info("Stopped"); | 192 | log.info("Stopped"); |
| 165 | } | 193 | } |
| 166 | 194 | ||
| ... | @@ -379,6 +407,10 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -379,6 +407,10 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
| 379 | // TODO check if the service needs an update on its group buckets after done CORD-433 | 407 | // TODO check if the service needs an update on its group buckets after done CORD-433 |
| 380 | ruleInstaller.updateServiceGroup(service); | 408 | ruleInstaller.updateServiceGroup(service); |
| 381 | arpProxy.addServiceIp(service.serviceIp()); | 409 | arpProxy.addServiceIp(service.serviceIp()); |
| 410 | + | ||
| 411 | + // sends gratuitous ARP here for the case of adding existing VMs | ||
| 412 | + // when ONOS or cordvtn app is restarted | ||
| 413 | + arpProxy.sendGratuitousArp(service.serviceIp(), gatewayMac, Sets.newHashSet(host)); | ||
| 382 | } | 414 | } |
| 383 | 415 | ||
| 384 | ruleInstaller.populateBasicConnectionRules(host, getTunnelIp(host), vNet); | 416 | ruleInstaller.populateBasicConnectionRules(host, getTunnelIp(host), vNet); |
| ... | @@ -418,6 +450,47 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -418,6 +450,47 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
| 418 | } | 450 | } |
| 419 | } | 451 | } |
| 420 | 452 | ||
| 453 | + /** | ||
| 454 | + * Sets service network gateway MAC address and sends out gratuitous ARP to all | ||
| 455 | + * VMs to update the gateway MAC address. | ||
| 456 | + * | ||
| 457 | + * @param mac mac address | ||
| 458 | + */ | ||
| 459 | + private void setServiceGatewayMac(MacAddress mac) { | ||
| 460 | + if (mac != null && !mac.equals(gatewayMac)) { | ||
| 461 | + gatewayMac = mac; | ||
| 462 | + log.debug("Set service gateway MAC address to {}", gatewayMac.toString()); | ||
| 463 | + } | ||
| 464 | + | ||
| 465 | + // TODO get existing service list from XOS and replace the loop below | ||
| 466 | + Set<String> vNets = Sets.newHashSet(); | ||
| 467 | + hostService.getHosts().forEach(host -> vNets.add(host.annotations().value(SERVICE_ID))); | ||
| 468 | + vNets.remove(null); | ||
| 469 | + | ||
| 470 | + vNets.stream().forEach(vNet -> { | ||
| 471 | + CordService service = getCordService(CordServiceId.of(vNet)); | ||
| 472 | + if (service != null) { | ||
| 473 | + arpProxy.sendGratuitousArp( | ||
| 474 | + service.serviceIp(), | ||
| 475 | + gatewayMac, | ||
| 476 | + service.hosts().keySet()); | ||
| 477 | + } | ||
| 478 | + }); | ||
| 479 | + } | ||
| 480 | + | ||
| 481 | + /** | ||
| 482 | + * Updates configurations. | ||
| 483 | + */ | ||
| 484 | + private void readConfiguration() { | ||
| 485 | + CordVtnConfig config = configRegistry.getConfig(appId, CordVtnConfig.class); | ||
| 486 | + if (config == null) { | ||
| 487 | + log.debug("No configuration found"); | ||
| 488 | + return; | ||
| 489 | + } | ||
| 490 | + | ||
| 491 | + setServiceGatewayMac(config.gatewayMac()); | ||
| 492 | + } | ||
| 493 | + | ||
| 421 | private class InternalHostListener implements HostListener { | 494 | private class InternalHostListener implements HostListener { |
| 422 | 495 | ||
| 423 | @Override | 496 | @Override |
| ... | @@ -446,15 +519,31 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -446,15 +519,31 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
| 446 | } | 519 | } |
| 447 | 520 | ||
| 448 | Ethernet ethPacket = context.inPacket().parsed(); | 521 | Ethernet ethPacket = context.inPacket().parsed(); |
| 449 | - if (ethPacket == null) { | 522 | + if (ethPacket == null || ethPacket.getEtherType() != Ethernet.TYPE_ARP) { |
| 450 | return; | 523 | return; |
| 451 | } | 524 | } |
| 452 | 525 | ||
| 453 | - if (ethPacket.getEtherType() != Ethernet.TYPE_ARP) { | 526 | + arpProxy.processArpPacket(context, ethPacket, gatewayMac); |
| 527 | + } | ||
| 528 | + } | ||
| 529 | + | ||
| 530 | + private class InternalConfigListener implements NetworkConfigListener { | ||
| 531 | + | ||
| 532 | + @Override | ||
| 533 | + public void event(NetworkConfigEvent event) { | ||
| 534 | + if (!event.configClass().equals(CordVtnConfig.class)) { | ||
| 454 | return; | 535 | return; |
| 455 | } | 536 | } |
| 456 | 537 | ||
| 457 | - arpProxy.processArpPacket(context, ethPacket); | 538 | + switch (event.type()) { |
| 539 | + case CONFIG_ADDED: | ||
| 540 | + case CONFIG_UPDATED: | ||
| 541 | + log.info("Network configuration changed"); | ||
| 542 | + eventExecutor.execute(CordVtn.this::readConfiguration); | ||
| 543 | + break; | ||
| 544 | + default: | ||
| 545 | + break; | ||
| 546 | + } | ||
| 458 | } | 547 | } |
| 459 | } | 548 | } |
| 460 | } | 549 | } | ... | ... |
| ... | @@ -23,6 +23,7 @@ import org.onlab.packet.Ip4Address; | ... | @@ -23,6 +23,7 @@ import org.onlab.packet.Ip4Address; |
| 23 | import org.onlab.packet.IpAddress; | 23 | import org.onlab.packet.IpAddress; |
| 24 | import org.onlab.packet.MacAddress; | 24 | import org.onlab.packet.MacAddress; |
| 25 | import org.onosproject.core.ApplicationId; | 25 | import org.onosproject.core.ApplicationId; |
| 26 | +import org.onosproject.net.Host; | ||
| 26 | import org.onosproject.net.flow.DefaultTrafficSelector; | 27 | import org.onosproject.net.flow.DefaultTrafficSelector; |
| 27 | import org.onosproject.net.flow.DefaultTrafficTreatment; | 28 | import org.onosproject.net.flow.DefaultTrafficTreatment; |
| 28 | import org.onosproject.net.flow.TrafficSelector; | 29 | import org.onosproject.net.flow.TrafficSelector; |
| ... | @@ -37,6 +38,7 @@ import java.nio.ByteBuffer; | ... | @@ -37,6 +38,7 @@ import java.nio.ByteBuffer; |
| 37 | import java.util.Optional; | 38 | import java.util.Optional; |
| 38 | import java.util.Set; | 39 | import java.util.Set; |
| 39 | 40 | ||
| 41 | +import static com.google.common.base.Preconditions.checkArgument; | ||
| 40 | import static com.google.common.base.Preconditions.checkNotNull; | 42 | import static com.google.common.base.Preconditions.checkNotNull; |
| 41 | import static org.slf4j.LoggerFactory.getLogger; | 43 | import static org.slf4j.LoggerFactory.getLogger; |
| 42 | 44 | ||
| ... | @@ -45,8 +47,6 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -45,8 +47,6 @@ import static org.slf4j.LoggerFactory.getLogger; |
| 45 | */ | 47 | */ |
| 46 | public class CordVtnArpProxy { | 48 | public class CordVtnArpProxy { |
| 47 | protected final Logger log = getLogger(getClass()); | 49 | protected final Logger log = getLogger(getClass()); |
| 48 | - // TODO make gateway MAC address configurable | ||
| 49 | - private static final MacAddress DEFAULT_GATEWAY_MAC = MacAddress.valueOf("00:00:00:00:00:01"); | ||
| 50 | 50 | ||
| 51 | private final ApplicationId appId; | 51 | private final ApplicationId appId; |
| 52 | private final PacketService packetService; | 52 | private final PacketService packetService; |
| ... | @@ -120,22 +120,21 @@ public class CordVtnArpProxy { | ... | @@ -120,22 +120,21 @@ public class CordVtnArpProxy { |
| 120 | * | 120 | * |
| 121 | * @param context packet context | 121 | * @param context packet context |
| 122 | * @param ethPacket ethernet packet | 122 | * @param ethPacket ethernet packet |
| 123 | + * @param gatewayMac gateway mac address | ||
| 123 | */ | 124 | */ |
| 124 | - public void processArpPacket(PacketContext context, Ethernet ethPacket) { | 125 | + public void processArpPacket(PacketContext context, Ethernet ethPacket, MacAddress gatewayMac) { |
| 126 | + checkArgument(!gatewayMac.equals(MacAddress.NONE)); | ||
| 127 | + | ||
| 125 | ARP arpPacket = (ARP) ethPacket.getPayload(); | 128 | ARP arpPacket = (ARP) ethPacket.getPayload(); |
| 126 | Ip4Address targetIp = Ip4Address.valueOf(arpPacket.getTargetProtocolAddress()); | 129 | Ip4Address targetIp = Ip4Address.valueOf(arpPacket.getTargetProtocolAddress()); |
| 127 | 130 | ||
| 128 | - if (arpPacket.getOpCode() != ARP.OP_REQUEST) { | 131 | + if (arpPacket.getOpCode() != ARP.OP_REQUEST || !serviceIPs.contains(targetIp)) { |
| 129 | return; | 132 | return; |
| 130 | } | 133 | } |
| 131 | 134 | ||
| 132 | - if (!serviceIPs.contains(targetIp)) { | ||
| 133 | - return; | ||
| 134 | - } | ||
| 135 | - | ||
| 136 | Ethernet ethReply = ARP.buildArpReply( | 135 | Ethernet ethReply = ARP.buildArpReply( |
| 137 | targetIp, | 136 | targetIp, |
| 138 | - DEFAULT_GATEWAY_MAC, | 137 | + gatewayMac, |
| 139 | ethPacket); | 138 | ethPacket); |
| 140 | 139 | ||
| 141 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() | 140 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
| ... | @@ -149,4 +148,57 @@ public class CordVtnArpProxy { | ... | @@ -149,4 +148,57 @@ public class CordVtnArpProxy { |
| 149 | 148 | ||
| 150 | context.block(); | 149 | context.block(); |
| 151 | } | 150 | } |
| 151 | + | ||
| 152 | + /** | ||
| 153 | + * Emits gratuitous ARP when a gateway mac address has been changed. | ||
| 154 | + * | ||
| 155 | + * @param ip ip address to update MAC | ||
| 156 | + * @param mac new mac address | ||
| 157 | + * @param hosts set of hosts to send gratuitous ARP packet | ||
| 158 | + */ | ||
| 159 | + public void sendGratuitousArp(IpAddress ip, MacAddress mac, Set<Host> hosts) { | ||
| 160 | + checkArgument(!mac.equals(MacAddress.NONE)); | ||
| 161 | + | ||
| 162 | + Ethernet ethArp = buildGratuitousArp(ip.getIp4Address(), mac); | ||
| 163 | + hosts.stream().forEach(host -> { | ||
| 164 | + TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
| 165 | + .setOutput(host.location().port()) | ||
| 166 | + .build(); | ||
| 167 | + | ||
| 168 | + packetService.emit(new DefaultOutboundPacket( | ||
| 169 | + host.location().deviceId(), | ||
| 170 | + treatment, | ||
| 171 | + ByteBuffer.wrap(ethArp.serialize()))); | ||
| 172 | + }); | ||
| 173 | + } | ||
| 174 | + | ||
| 175 | + /** | ||
| 176 | + * Builds gratuitous ARP packet with a given IP and MAC address. | ||
| 177 | + * | ||
| 178 | + * @param ip ip address for TPA and SPA | ||
| 179 | + * @param mac new mac address | ||
| 180 | + * @return ethernet packet | ||
| 181 | + */ | ||
| 182 | + private Ethernet buildGratuitousArp(IpAddress ip, MacAddress mac) { | ||
| 183 | + Ethernet eth = new Ethernet(); | ||
| 184 | + | ||
| 185 | + eth.setEtherType(Ethernet.TYPE_ARP); | ||
| 186 | + eth.setSourceMACAddress(mac); | ||
| 187 | + eth.setDestinationMACAddress(MacAddress.BROADCAST); | ||
| 188 | + | ||
| 189 | + ARP arp = new ARP(); | ||
| 190 | + arp.setOpCode(ARP.OP_REQUEST); | ||
| 191 | + arp.setHardwareType(ARP.HW_TYPE_ETHERNET); | ||
| 192 | + arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH); | ||
| 193 | + arp.setProtocolType(ARP.PROTO_TYPE_IP); | ||
| 194 | + arp.setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH); | ||
| 195 | + | ||
| 196 | + arp.setSenderHardwareAddress(mac.toBytes()); | ||
| 197 | + arp.setTargetHardwareAddress(MacAddress.BROADCAST.toBytes()); | ||
| 198 | + arp.setSenderProtocolAddress(ip.getIp4Address().toOctets()); | ||
| 199 | + arp.setTargetProtocolAddress(ip.getIp4Address().toOctets()); | ||
| 200 | + | ||
| 201 | + eth.setPayload(arp); | ||
| 202 | + return eth; | ||
| 203 | + } | ||
| 152 | } | 204 | } | ... | ... |
| ... | @@ -18,20 +18,25 @@ package org.onosproject.cordvtn; | ... | @@ -18,20 +18,25 @@ package org.onosproject.cordvtn; |
| 18 | import com.fasterxml.jackson.databind.JsonNode; | 18 | import com.fasterxml.jackson.databind.JsonNode; |
| 19 | import com.google.common.collect.Sets; | 19 | import com.google.common.collect.Sets; |
| 20 | import org.onlab.packet.IpAddress; | 20 | import org.onlab.packet.IpAddress; |
| 21 | +import org.onlab.packet.MacAddress; | ||
| 21 | import org.onlab.packet.TpPort; | 22 | import org.onlab.packet.TpPort; |
| 22 | import org.onosproject.core.ApplicationId; | 23 | import org.onosproject.core.ApplicationId; |
| 23 | import org.onosproject.net.DeviceId; | 24 | import org.onosproject.net.DeviceId; |
| 24 | import org.onosproject.net.config.Config; | 25 | import org.onosproject.net.config.Config; |
| 26 | +import org.slf4j.Logger; | ||
| 25 | 27 | ||
| 26 | import java.util.Set; | 28 | import java.util.Set; |
| 27 | 29 | ||
| 28 | import static com.google.common.base.Preconditions.checkNotNull; | 30 | import static com.google.common.base.Preconditions.checkNotNull; |
| 31 | +import static org.slf4j.LoggerFactory.getLogger; | ||
| 29 | 32 | ||
| 30 | /** | 33 | /** |
| 31 | * Configuration object for CordVtn service. | 34 | * Configuration object for CordVtn service. |
| 32 | */ | 35 | */ |
| 33 | public class CordVtnConfig extends Config<ApplicationId> { | 36 | public class CordVtnConfig extends Config<ApplicationId> { |
| 34 | 37 | ||
| 38 | + protected final Logger log = getLogger(getClass()); | ||
| 39 | + | ||
| 35 | public static final String CORDVTN_NODES = "nodes"; | 40 | public static final String CORDVTN_NODES = "nodes"; |
| 36 | public static final String HOSTNAME = "hostname"; | 41 | public static final String HOSTNAME = "hostname"; |
| 37 | public static final String OVSDB_IP = "ovsdbIp"; | 42 | public static final String OVSDB_IP = "ovsdbIp"; |
| ... | @@ -39,6 +44,7 @@ public class CordVtnConfig extends Config<ApplicationId> { | ... | @@ -39,6 +44,7 @@ public class CordVtnConfig extends Config<ApplicationId> { |
| 39 | public static final String BRIDGE_ID = "bridgeId"; | 44 | public static final String BRIDGE_ID = "bridgeId"; |
| 40 | public static final String PHYSICAL_PORT_NAME = "phyPortName"; | 45 | public static final String PHYSICAL_PORT_NAME = "phyPortName"; |
| 41 | public static final String LOCAL_IP = "localIp"; | 46 | public static final String LOCAL_IP = "localIp"; |
| 47 | + public static final String GATEWAY_MAC = "gatewayMac"; | ||
| 42 | 48 | ||
| 43 | /** | 49 | /** |
| 44 | * Returns the set of nodes read from network config. | 50 | * Returns the set of nodes read from network config. |
| ... | @@ -64,6 +70,25 @@ public class CordVtnConfig extends Config<ApplicationId> { | ... | @@ -64,6 +70,25 @@ public class CordVtnConfig extends Config<ApplicationId> { |
| 64 | } | 70 | } |
| 65 | 71 | ||
| 66 | /** | 72 | /** |
| 73 | + * Returns gateway MAC address. | ||
| 74 | + * | ||
| 75 | + * @return mac address, or null | ||
| 76 | + */ | ||
| 77 | + public MacAddress gatewayMac() { | ||
| 78 | + JsonNode jsonNode = object.get(GATEWAY_MAC); | ||
| 79 | + if (jsonNode == null) { | ||
| 80 | + return null; | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + try { | ||
| 84 | + return MacAddress.valueOf(jsonNode.asText()); | ||
| 85 | + } catch (IllegalArgumentException e) { | ||
| 86 | + log.error("Wrong MAC address format {}", jsonNode.asText()); | ||
| 87 | + return null; | ||
| 88 | + } | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + /** | ||
| 67 | * Configuration for CordVtn node. | 92 | * Configuration for CordVtn node. |
| 68 | */ | 93 | */ |
| 69 | public static class CordVtnNodeConfig { | 94 | public static class CordVtnNodeConfig { | ... | ... |
| ... | @@ -41,12 +41,10 @@ import org.onosproject.net.behaviour.DefaultTunnelDescription; | ... | @@ -41,12 +41,10 @@ import org.onosproject.net.behaviour.DefaultTunnelDescription; |
| 41 | import org.onosproject.net.behaviour.TunnelConfig; | 41 | import org.onosproject.net.behaviour.TunnelConfig; |
| 42 | import org.onosproject.net.behaviour.TunnelDescription; | 42 | import org.onosproject.net.behaviour.TunnelDescription; |
| 43 | import org.onosproject.net.behaviour.TunnelName; | 43 | import org.onosproject.net.behaviour.TunnelName; |
| 44 | -import org.onosproject.net.config.ConfigFactory; | ||
| 45 | import org.onosproject.net.config.NetworkConfigEvent; | 44 | import org.onosproject.net.config.NetworkConfigEvent; |
| 46 | import org.onosproject.net.config.NetworkConfigListener; | 45 | import org.onosproject.net.config.NetworkConfigListener; |
| 47 | import org.onosproject.net.config.NetworkConfigRegistry; | 46 | import org.onosproject.net.config.NetworkConfigRegistry; |
| 48 | import org.onosproject.net.config.NetworkConfigService; | 47 | import org.onosproject.net.config.NetworkConfigService; |
| 49 | -import org.onosproject.net.config.basics.SubjectFactories; | ||
| 50 | import org.onosproject.net.device.DeviceAdminService; | 48 | import org.onosproject.net.device.DeviceAdminService; |
| 51 | import org.onosproject.net.device.DeviceEvent; | 49 | import org.onosproject.net.device.DeviceEvent; |
| 52 | import org.onosproject.net.device.DeviceListener; | 50 | import org.onosproject.net.device.DeviceListener; |
| ... | @@ -151,14 +149,6 @@ public class CordVtnNodeManager { | ... | @@ -151,14 +149,6 @@ public class CordVtnNodeManager { |
| 151 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 149 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 152 | protected CordVtnService cordVtnService; | 150 | protected CordVtnService cordVtnService; |
| 153 | 151 | ||
| 154 | - private final ConfigFactory configFactory = | ||
| 155 | - new ConfigFactory(SubjectFactories.APP_SUBJECT_FACTORY, CordVtnConfig.class, "cordvtn") { | ||
| 156 | - @Override | ||
| 157 | - public CordVtnConfig createConfig() { | ||
| 158 | - return new CordVtnConfig(); | ||
| 159 | - } | ||
| 160 | - }; | ||
| 161 | - | ||
| 162 | private final ExecutorService eventExecutor = | 152 | private final ExecutorService eventExecutor = |
| 163 | newSingleThreadScheduledExecutor(groupedThreads("onos/cordvtncfg", "event-handler")); | 153 | newSingleThreadScheduledExecutor(groupedThreads("onos/cordvtncfg", "event-handler")); |
| 164 | 154 | ||
| ... | @@ -231,7 +221,6 @@ public class CordVtnNodeManager { | ... | @@ -231,7 +221,6 @@ public class CordVtnNodeManager { |
| 231 | @Activate | 221 | @Activate |
| 232 | protected void active() { | 222 | protected void active() { |
| 233 | appId = coreService.getAppId(CordVtnService.CORDVTN_APP_ID); | 223 | appId = coreService.getAppId(CordVtnService.CORDVTN_APP_ID); |
| 234 | - | ||
| 235 | nodeStore = storageService.<CordVtnNode, NodeState>consistentMapBuilder() | 224 | nodeStore = storageService.<CordVtnNode, NodeState>consistentMapBuilder() |
| 236 | .withSerializer(Serializer.using(NODE_SERIALIZER.build())) | 225 | .withSerializer(Serializer.using(NODE_SERIALIZER.build())) |
| 237 | .withName("cordvtn-nodestore") | 226 | .withName("cordvtn-nodestore") |
| ... | @@ -247,12 +236,11 @@ public class CordVtnNodeManager { | ... | @@ -247,12 +236,11 @@ public class CordVtnNodeManager { |
| 247 | 236 | ||
| 248 | deviceService.addListener(deviceListener); | 237 | deviceService.addListener(deviceListener); |
| 249 | configService.addListener(configListener); | 238 | configService.addListener(configListener); |
| 250 | - configRegistry.registerConfigFactory(configFactory); | 239 | + readConfiguration(); |
| 251 | } | 240 | } |
| 252 | 241 | ||
| 253 | @Deactivate | 242 | @Deactivate |
| 254 | protected void deactivate() { | 243 | protected void deactivate() { |
| 255 | - configRegistry.unregisterConfigFactory(configFactory); | ||
| 256 | configService.removeListener(configListener); | 244 | configService.removeListener(configListener); |
| 257 | deviceService.removeListener(deviceListener); | 245 | deviceService.removeListener(deviceListener); |
| 258 | 246 | ||
| ... | @@ -820,13 +808,13 @@ public class CordVtnNodeManager { | ... | @@ -820,13 +808,13 @@ public class CordVtnNodeManager { |
| 820 | } | 808 | } |
| 821 | 809 | ||
| 822 | /** | 810 | /** |
| 823 | - * Reads node configuration from config file. | 811 | + * Reads cordvtn nodes from config file. |
| 824 | */ | 812 | */ |
| 825 | private void readConfiguration() { | 813 | private void readConfiguration() { |
| 826 | CordVtnConfig config = configRegistry.getConfig(appId, CordVtnConfig.class); | 814 | CordVtnConfig config = configRegistry.getConfig(appId, CordVtnConfig.class); |
| 827 | 815 | ||
| 828 | if (config == null) { | 816 | if (config == null) { |
| 829 | - log.warn("No configuration found"); | 817 | + log.debug("No configuration found"); |
| 830 | return; | 818 | return; |
| 831 | } | 819 | } |
| 832 | 820 | ||
| ... | @@ -841,6 +829,8 @@ public class CordVtnNodeManager { | ... | @@ -841,6 +829,8 @@ public class CordVtnNodeManager { |
| 841 | 829 | ||
| 842 | addNode(cordVtnNode); | 830 | addNode(cordVtnNode); |
| 843 | }); | 831 | }); |
| 832 | + | ||
| 833 | + // TODO remove nodes if needed | ||
| 844 | } | 834 | } |
| 845 | 835 | ||
| 846 | private class InternalConfigListener implements NetworkConfigListener { | 836 | private class InternalConfigListener implements NetworkConfigListener { |
| ... | @@ -853,11 +843,7 @@ public class CordVtnNodeManager { | ... | @@ -853,11 +843,7 @@ public class CordVtnNodeManager { |
| 853 | 843 | ||
| 854 | switch (event.type()) { | 844 | switch (event.type()) { |
| 855 | case CONFIG_ADDED: | 845 | case CONFIG_ADDED: |
| 856 | - log.info("Network configuration added"); | ||
| 857 | - eventExecutor.execute(CordVtnNodeManager.this::readConfiguration); | ||
| 858 | - break; | ||
| 859 | case CONFIG_UPDATED: | 846 | case CONFIG_UPDATED: |
| 860 | - log.info("Network configuration updated"); | ||
| 861 | eventExecutor.execute(CordVtnNodeManager.this::readConfiguration); | 847 | eventExecutor.execute(CordVtnNodeManager.this::readConfiguration); |
| 862 | break; | 848 | break; |
| 863 | default: | 849 | default: | ... | ... |
-
Please register or login to post a comment