Committed by
Gerrit Code Review
CORD-537 Added public IP gateways for ARP proxy
- Added public IP gateway and MAC pairs to network config for ARP proxy - Added vSG as a ONOS host Change-Id: Ia722ba3843297cec7134da5d64bbf188c22762f8
Showing
5 changed files
with
169 additions
and
60 deletions
| ... | @@ -16,6 +16,7 @@ | ... | @@ -16,6 +16,7 @@ |
| 16 | package org.onosproject.cordvtn; | 16 | package org.onosproject.cordvtn; |
| 17 | 17 | ||
| 18 | import com.google.common.collect.Lists; | 18 | import com.google.common.collect.Lists; |
| 19 | +import com.google.common.collect.Maps; | ||
| 19 | import com.google.common.collect.Sets; | 20 | import com.google.common.collect.Sets; |
| 20 | import org.apache.felix.scr.annotations.Activate; | 21 | import org.apache.felix.scr.annotations.Activate; |
| 21 | import org.apache.felix.scr.annotations.Component; | 22 | import org.apache.felix.scr.annotations.Component; |
| ... | @@ -156,7 +157,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -156,7 +157,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
| 156 | private HostProviderService hostProvider; | 157 | private HostProviderService hostProvider; |
| 157 | private CordVtnRuleInstaller ruleInstaller; | 158 | private CordVtnRuleInstaller ruleInstaller; |
| 158 | private CordVtnArpProxy arpProxy; | 159 | private CordVtnArpProxy arpProxy; |
| 159 | - private volatile MacAddress gatewayMac = MacAddress.NONE; | 160 | + private volatile MacAddress privateGatewayMac = MacAddress.NONE; |
| 160 | 161 | ||
| 161 | /** | 162 | /** |
| 162 | * Creates an cordvtn host location provider. | 163 | * Creates an cordvtn host location provider. |
| ... | @@ -305,7 +306,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -305,7 +306,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
| 305 | 306 | ||
| 306 | @Override | 307 | @Override |
| 307 | public void updateVirtualSubscriberGateways(HostId vSgHostId, String serviceVlan, | 308 | public void updateVirtualSubscriberGateways(HostId vSgHostId, String serviceVlan, |
| 308 | - Set<IpAddress> vSgIps) { | 309 | + Map<IpAddress, MacAddress> vSgs) { |
| 309 | Host vSgVm = hostService.getHost(vSgHostId); | 310 | Host vSgVm = hostService.getHost(vSgHostId); |
| 310 | 311 | ||
| 311 | if (vSgVm == null || !vSgVm.annotations().value(S_TAG).equals(serviceVlan)) { | 312 | if (vSgVm == null || !vSgVm.annotations().value(S_TAG).equals(serviceVlan)) { |
| ... | @@ -313,8 +314,45 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -313,8 +314,45 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
| 313 | return; | 314 | return; |
| 314 | } | 315 | } |
| 315 | 316 | ||
| 316 | - log.info("Updates vSGs in {} with {}", vSgVm.id(), vSgIps.toString()); | 317 | + log.info("Updates vSGs in {} with {}", vSgVm.id(), vSgs.toString()); |
| 317 | - ruleInstaller.populateSubscriberGatewayRules(vSgVm, vSgIps); | 318 | + vSgs.entrySet().stream() |
| 319 | + .forEach(entry -> addVirtualSubscriberGateway( | ||
| 320 | + vSgVm, | ||
| 321 | + entry.getKey(), | ||
| 322 | + entry.getValue(), | ||
| 323 | + serviceVlan)); | ||
| 324 | + | ||
| 325 | + ruleInstaller.populateSubscriberGatewayRules(vSgVm, vSgs.keySet()); | ||
| 326 | + } | ||
| 327 | + | ||
| 328 | + /** | ||
| 329 | + * Adds virtual subscriber gateway to the system. | ||
| 330 | + * | ||
| 331 | + * @param vSgHost host virtual machine of this vSG | ||
| 332 | + * @param vSgIp vSG ip address | ||
| 333 | + * @param vSgMac vSG mac address | ||
| 334 | + * @param serviceVlan service vlan | ||
| 335 | + */ | ||
| 336 | + public void addVirtualSubscriberGateway(Host vSgHost, IpAddress vSgIp, MacAddress vSgMac, String serviceVlan) { | ||
| 337 | + HostId hostId = HostId.hostId(vSgMac); | ||
| 338 | + Host host = hostService.getHost(hostId); | ||
| 339 | + if (host != null) { | ||
| 340 | + log.debug("vSG with {} already exists", vSgMac.toString()); | ||
| 341 | + return; | ||
| 342 | + } | ||
| 343 | + | ||
| 344 | + log.info("vSG with IP({}) MAC({}) detected", vSgIp.toString(), vSgMac.toString()); | ||
| 345 | + DefaultAnnotations.Builder annotations = DefaultAnnotations.builder() | ||
| 346 | + .set(S_TAG, serviceVlan); | ||
| 347 | + | ||
| 348 | + HostDescription hostDesc = new DefaultHostDescription( | ||
| 349 | + vSgMac, | ||
| 350 | + VlanId.NONE, | ||
| 351 | + vSgHost.location(), | ||
| 352 | + Sets.newHashSet(vSgIp), | ||
| 353 | + annotations.build()); | ||
| 354 | + | ||
| 355 | + hostProvider.hostDetected(hostId, hostDesc, false); | ||
| 318 | } | 356 | } |
| 319 | 357 | ||
| 320 | /** | 358 | /** |
| ... | @@ -438,24 +476,24 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -438,24 +476,24 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
| 438 | * Returns public ip addresses of vSGs running inside a give vSG host. | 476 | * Returns public ip addresses of vSGs running inside a give vSG host. |
| 439 | * | 477 | * |
| 440 | * @param vSgHost vSG host | 478 | * @param vSgHost vSG host |
| 441 | - * @return set of ip address, or empty set | 479 | + * @return map of ip and mac address, or empty map |
| 442 | */ | 480 | */ |
| 443 | - private Set<IpAddress> getSubscriberGatewayIps(Host vSgHost) { | 481 | + private Map<IpAddress, MacAddress> getSubscriberGateways(Host vSgHost) { |
| 444 | String vPortId = vSgHost.annotations().value(OPENSTACK_PORT_ID); | 482 | String vPortId = vSgHost.annotations().value(OPENSTACK_PORT_ID); |
| 445 | String serviceVlan = vSgHost.annotations().value(S_TAG); | 483 | String serviceVlan = vSgHost.annotations().value(S_TAG); |
| 446 | 484 | ||
| 447 | OpenstackPort vPort = openstackService.port(vPortId); | 485 | OpenstackPort vPort = openstackService.port(vPortId); |
| 448 | if (vPort == null) { | 486 | if (vPort == null) { |
| 449 | log.warn("Failed to get OpenStack port {} for VM {}", vPortId, vSgHost.id()); | 487 | log.warn("Failed to get OpenStack port {} for VM {}", vPortId, vSgHost.id()); |
| 450 | - return Sets.newHashSet(); | 488 | + return Maps.newHashMap(); |
| 451 | } | 489 | } |
| 452 | 490 | ||
| 453 | if (!serviceVlan.equals(getServiceVlan(vPort))) { | 491 | if (!serviceVlan.equals(getServiceVlan(vPort))) { |
| 454 | log.error("Host({}) s-tag does not match with vPort s-tag", vSgHost.id()); | 492 | log.error("Host({}) s-tag does not match with vPort s-tag", vSgHost.id()); |
| 455 | - return Sets.newHashSet(); | 493 | + return Maps.newHashMap(); |
| 456 | } | 494 | } |
| 457 | 495 | ||
| 458 | - return vPort.allowedAddressPairs().keySet(); | 496 | + return vPort.allowedAddressPairs(); |
| 459 | } | 497 | } |
| 460 | 498 | ||
| 461 | /** | 499 | /** |
| ... | @@ -485,6 +523,11 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -485,6 +523,11 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
| 485 | */ | 523 | */ |
| 486 | private void serviceVmAdded(Host host) { | 524 | private void serviceVmAdded(Host host) { |
| 487 | String vNetId = host.annotations().value(SERVICE_ID); | 525 | String vNetId = host.annotations().value(SERVICE_ID); |
| 526 | + if (vNetId == null) { | ||
| 527 | + // ignore this host, it not a VM we injected or a vSG | ||
| 528 | + return; | ||
| 529 | + } | ||
| 530 | + | ||
| 488 | OpenstackNetwork vNet = openstackService.network(vNetId); | 531 | OpenstackNetwork vNet = openstackService.network(vNetId); |
| 489 | if (vNet == null) { | 532 | if (vNet == null) { |
| 490 | log.warn("Failed to get OpenStack network {} for VM {}({}).", | 533 | log.warn("Failed to get OpenStack network {} for VM {}({}).", |
| ... | @@ -509,19 +552,28 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -509,19 +552,28 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
| 509 | } else { | 552 | } else { |
| 510 | // TODO check if the service needs an update on its group buckets after done CORD-433 | 553 | // TODO check if the service needs an update on its group buckets after done CORD-433 |
| 511 | ruleInstaller.updateServiceGroup(service); | 554 | ruleInstaller.updateServiceGroup(service); |
| 512 | - arpProxy.addServiceIp(service.serviceIp()); | 555 | + arpProxy.addGateway(service.serviceIp(), privateGatewayMac); |
| 513 | 556 | ||
| 514 | // sends gratuitous ARP here for the case of adding existing VMs | 557 | // sends gratuitous ARP here for the case of adding existing VMs |
| 515 | // when ONOS or cordvtn app is restarted | 558 | // when ONOS or cordvtn app is restarted |
| 516 | - arpProxy.sendGratuitousArp(service.serviceIp(), gatewayMac, Sets.newHashSet(host)); | 559 | + arpProxy.sendGratuitousArpForGateway(service.serviceIp(), Sets.newHashSet(host)); |
| 517 | } | 560 | } |
| 518 | 561 | ||
| 519 | registerDhcpLease(host, service); | 562 | registerDhcpLease(host, service); |
| 520 | ruleInstaller.populateBasicConnectionRules(host, getTunnelIp(host), vNet); | 563 | ruleInstaller.populateBasicConnectionRules(host, getTunnelIp(host), vNet); |
| 521 | 564 | ||
| 522 | - if (host.annotations().value(S_TAG) != null) { | 565 | + String serviceVlan = host.annotations().value(S_TAG); |
| 566 | + if (serviceVlan != null) { | ||
| 523 | log.debug("vSG VM detected {}", host.id()); | 567 | log.debug("vSG VM detected {}", host.id()); |
| 524 | - ruleInstaller.populateSubscriberGatewayRules(host, getSubscriberGatewayIps(host)); | 568 | + Map<IpAddress, MacAddress> vSgs = getSubscriberGateways(host); |
| 569 | + vSgs.entrySet().stream() | ||
| 570 | + .forEach(entry -> addVirtualSubscriberGateway( | ||
| 571 | + host, | ||
| 572 | + entry.getKey(), | ||
| 573 | + entry.getValue(), | ||
| 574 | + serviceVlan)); | ||
| 575 | + | ||
| 576 | + ruleInstaller.populateSubscriberGatewayRules(host, vSgs.keySet()); | ||
| 525 | } | 577 | } |
| 526 | } | 578 | } |
| 527 | 579 | ||
| ... | @@ -566,7 +618,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -566,7 +618,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
| 566 | ruleInstaller.updateServiceGroup(service); | 618 | ruleInstaller.updateServiceGroup(service); |
| 567 | 619 | ||
| 568 | if (getHostsWithOpenstackNetwork(vNet).isEmpty()) { | 620 | if (getHostsWithOpenstackNetwork(vNet).isEmpty()) { |
| 569 | - arpProxy.removeServiceIp(service.serviceIp()); | 621 | + arpProxy.removeGateway(service.serviceIp()); |
| 570 | } | 622 | } |
| 571 | } | 623 | } |
| 572 | } | 624 | } |
| ... | @@ -575,14 +627,17 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -575,14 +627,17 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
| 575 | * Sets service network gateway MAC address and sends out gratuitous ARP to all | 627 | * Sets service network gateway MAC address and sends out gratuitous ARP to all |
| 576 | * VMs to update the gateway MAC address. | 628 | * VMs to update the gateway MAC address. |
| 577 | * | 629 | * |
| 578 | - * @param mac mac address | 630 | + * @param newMac mac address to update |
| 579 | */ | 631 | */ |
| 580 | - private void setServiceGatewayMac(MacAddress mac) { | 632 | + private void setPrivateGatewayMac(MacAddress newMac) { |
| 581 | - if (mac != null && !mac.equals(gatewayMac)) { | 633 | + if (newMac == null || newMac.equals(privateGatewayMac)) { |
| 582 | - gatewayMac = mac; | 634 | + // no updates, do nothing |
| 583 | - log.debug("Set service gateway MAC address to {}", gatewayMac.toString()); | 635 | + return; |
| 584 | } | 636 | } |
| 585 | 637 | ||
| 638 | + privateGatewayMac = newMac; | ||
| 639 | + log.debug("Set service gateway MAC address to {}", privateGatewayMac.toString()); | ||
| 640 | + | ||
| 586 | // TODO get existing service list from XOS and replace the loop below | 641 | // TODO get existing service list from XOS and replace the loop below |
| 587 | Set<String> vNets = Sets.newHashSet(); | 642 | Set<String> vNets = Sets.newHashSet(); |
| 588 | hostService.getHosts().forEach(host -> vNets.add(host.annotations().value(SERVICE_ID))); | 643 | hostService.getHosts().forEach(host -> vNets.add(host.annotations().value(SERVICE_ID))); |
| ... | @@ -591,15 +646,29 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -591,15 +646,29 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
| 591 | vNets.stream().forEach(vNet -> { | 646 | vNets.stream().forEach(vNet -> { |
| 592 | CordService service = getCordService(CordServiceId.of(vNet)); | 647 | CordService service = getCordService(CordServiceId.of(vNet)); |
| 593 | if (service != null) { | 648 | if (service != null) { |
| 594 | - arpProxy.sendGratuitousArp( | 649 | + arpProxy.addGateway(service.serviceIp(), privateGatewayMac); |
| 595 | - service.serviceIp(), | 650 | + arpProxy.sendGratuitousArpForGateway(service.serviceIp(), service.hosts().keySet()); |
| 596 | - gatewayMac, | ||
| 597 | - service.hosts().keySet()); | ||
| 598 | } | 651 | } |
| 599 | }); | 652 | }); |
| 600 | } | 653 | } |
| 601 | 654 | ||
| 602 | /** | 655 | /** |
| 656 | + * Sets public gateway MAC address. | ||
| 657 | + * | ||
| 658 | + * @param publicGateways gateway ip and mac address pairs | ||
| 659 | + */ | ||
| 660 | + private void setPublicGatewayMac(Map<IpAddress, MacAddress> publicGateways) { | ||
| 661 | + publicGateways.entrySet() | ||
| 662 | + .stream() | ||
| 663 | + .forEach(entry -> { | ||
| 664 | + arpProxy.addGateway(entry.getKey(), entry.getValue()); | ||
| 665 | + log.debug("Added public gateway IP {}, MAC {}", | ||
| 666 | + entry.getKey().toString(), entry.getValue().toString()); | ||
| 667 | + }); | ||
| 668 | + // TODO notice gateway MAC change to VMs holds this gateway IP | ||
| 669 | + } | ||
| 670 | + | ||
| 671 | + /** | ||
| 603 | * Updates configurations. | 672 | * Updates configurations. |
| 604 | */ | 673 | */ |
| 605 | private void readConfiguration() { | 674 | private void readConfiguration() { |
| ... | @@ -609,7 +678,8 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -609,7 +678,8 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
| 609 | return; | 678 | return; |
| 610 | } | 679 | } |
| 611 | 680 | ||
| 612 | - setServiceGatewayMac(config.gatewayMac()); | 681 | + setPrivateGatewayMac(config.privateGatewayMac()); |
| 682 | + setPublicGatewayMac(config.publicGateways()); | ||
| 613 | } | 683 | } |
| 614 | 684 | ||
| 615 | private class InternalHostListener implements HostListener { | 685 | private class InternalHostListener implements HostListener { |
| ... | @@ -644,7 +714,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro | ... | @@ -644,7 +714,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro |
| 644 | return; | 714 | return; |
| 645 | } | 715 | } |
| 646 | 716 | ||
| 647 | - arpProxy.processArpPacket(context, ethPacket, gatewayMac); | 717 | + arpProxy.processArpPacket(context, ethPacket); |
| 648 | } | 718 | } |
| 649 | } | 719 | } |
| 650 | 720 | ... | ... |
| ... | @@ -15,7 +15,7 @@ | ... | @@ -15,7 +15,7 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.cordvtn; | 16 | package org.onosproject.cordvtn; |
| 17 | 17 | ||
| 18 | -import com.google.common.collect.Sets; | 18 | +import com.google.common.collect.Maps; |
| 19 | import org.onlab.packet.ARP; | 19 | import org.onlab.packet.ARP; |
| 20 | import org.onlab.packet.EthType; | 20 | import org.onlab.packet.EthType; |
| 21 | import org.onlab.packet.Ethernet; | 21 | import org.onlab.packet.Ethernet; |
| ... | @@ -36,10 +36,10 @@ import org.onosproject.net.packet.PacketService; | ... | @@ -36,10 +36,10 @@ import org.onosproject.net.packet.PacketService; |
| 36 | import org.slf4j.Logger; | 36 | import org.slf4j.Logger; |
| 37 | 37 | ||
| 38 | import java.nio.ByteBuffer; | 38 | import java.nio.ByteBuffer; |
| 39 | +import java.util.Map; | ||
| 39 | import java.util.Optional; | 40 | import java.util.Optional; |
| 40 | import java.util.Set; | 41 | import java.util.Set; |
| 41 | 42 | ||
| 42 | -import static com.google.common.base.Preconditions.checkArgument; | ||
| 43 | import static com.google.common.base.Preconditions.checkNotNull; | 43 | import static com.google.common.base.Preconditions.checkNotNull; |
| 44 | import static org.slf4j.LoggerFactory.getLogger; | 44 | import static org.slf4j.LoggerFactory.getLogger; |
| 45 | 45 | ||
| ... | @@ -53,7 +53,7 @@ public class CordVtnArpProxy { | ... | @@ -53,7 +53,7 @@ public class CordVtnArpProxy { |
| 53 | private final PacketService packetService; | 53 | private final PacketService packetService; |
| 54 | private final HostService hostService; | 54 | private final HostService hostService; |
| 55 | 55 | ||
| 56 | - private Set<Ip4Address> serviceIPs = Sets.newHashSet(); | 56 | + private final Map<Ip4Address, MacAddress> gateways = Maps.newConcurrentMap(); |
| 57 | 57 | ||
| 58 | /** | 58 | /** |
| 59 | * Default constructor. | 59 | * Default constructor. |
| ... | @@ -96,23 +96,25 @@ public class CordVtnArpProxy { | ... | @@ -96,23 +96,25 @@ public class CordVtnArpProxy { |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | /** | 98 | /** |
| 99 | - * Adds a given service IP address to be served. | 99 | + * Adds a given gateway IP and MAC address to this ARP proxy. |
| 100 | * | 100 | * |
| 101 | - * @param serviceIp service ip | 101 | + * @param gatewayIp gateway ip address |
| 102 | + * @param gatewayMac gateway mac address | ||
| 102 | */ | 103 | */ |
| 103 | - public void addServiceIp(IpAddress serviceIp) { | 104 | + public void addGateway(IpAddress gatewayIp, MacAddress gatewayMac) { |
| 104 | - checkNotNull(serviceIp); | 105 | + checkNotNull(gatewayIp); |
| 105 | - serviceIPs.add(serviceIp.getIp4Address()); | 106 | + checkNotNull(gatewayMac); |
| 107 | + gateways.put(gatewayIp.getIp4Address(), gatewayMac); | ||
| 106 | } | 108 | } |
| 107 | 109 | ||
| 108 | /** | 110 | /** |
| 109 | * Removes a given service IP address from this ARP proxy. | 111 | * Removes a given service IP address from this ARP proxy. |
| 110 | * | 112 | * |
| 111 | - * @param serviceIp service ip | 113 | + * @param gatewayIp gateway ip address |
| 112 | */ | 114 | */ |
| 113 | - public void removeServiceIp(IpAddress serviceIp) { | 115 | + public void removeGateway(IpAddress gatewayIp) { |
| 114 | - checkNotNull(serviceIp); | 116 | + checkNotNull(gatewayIp); |
| 115 | - serviceIPs.remove(serviceIp.getIp4Address()); | 117 | + gateways.remove(gatewayIp.getIp4Address()); |
| 116 | } | 118 | } |
| 117 | 119 | ||
| 118 | /** | 120 | /** |
| ... | @@ -123,27 +125,28 @@ public class CordVtnArpProxy { | ... | @@ -123,27 +125,28 @@ public class CordVtnArpProxy { |
| 123 | * | 125 | * |
| 124 | * @param context packet context | 126 | * @param context packet context |
| 125 | * @param ethPacket ethernet packet | 127 | * @param ethPacket ethernet packet |
| 126 | - * @param gatewayMac gateway mac address | ||
| 127 | */ | 128 | */ |
| 128 | - public void processArpPacket(PacketContext context, Ethernet ethPacket, MacAddress gatewayMac) { | 129 | + public void processArpPacket(PacketContext context, Ethernet ethPacket) { |
| 129 | ARP arpPacket = (ARP) ethPacket.getPayload(); | 130 | ARP arpPacket = (ARP) ethPacket.getPayload(); |
| 130 | if (arpPacket.getOpCode() != ARP.OP_REQUEST) { | 131 | if (arpPacket.getOpCode() != ARP.OP_REQUEST) { |
| 131 | return; | 132 | return; |
| 132 | } | 133 | } |
| 133 | 134 | ||
| 134 | Ip4Address targetIp = Ip4Address.valueOf(arpPacket.getTargetProtocolAddress()); | 135 | Ip4Address targetIp = Ip4Address.valueOf(arpPacket.getTargetProtocolAddress()); |
| 135 | - MacAddress macAddr = serviceIPs.contains(targetIp) ? | ||
| 136 | - gatewayMac : getMacFromHostService(targetIp); | ||
| 137 | 136 | ||
| 138 | - if (macAddr.equals(MacAddress.NONE)) { | 137 | + MacAddress gatewayMac = gateways.get(targetIp); |
| 138 | + MacAddress replyMac = gatewayMac != null ? gatewayMac : getMacFromHostService(targetIp); | ||
| 139 | + | ||
| 140 | + if (replyMac.equals(MacAddress.NONE)) { | ||
| 139 | log.debug("Failed to find MAC for {}", targetIp.toString()); | 141 | log.debug("Failed to find MAC for {}", targetIp.toString()); |
| 140 | context.block(); | 142 | context.block(); |
| 141 | return; | 143 | return; |
| 142 | } | 144 | } |
| 143 | 145 | ||
| 146 | + log.trace("Send ARP reply for {} with {}", targetIp.toString(), replyMac.toString()); | ||
| 144 | Ethernet ethReply = ARP.buildArpReply( | 147 | Ethernet ethReply = ARP.buildArpReply( |
| 145 | targetIp, | 148 | targetIp, |
| 146 | - macAddr, | 149 | + replyMac, |
| 147 | ethPacket); | 150 | ethPacket); |
| 148 | 151 | ||
| 149 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() | 152 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
| ... | @@ -161,14 +164,17 @@ public class CordVtnArpProxy { | ... | @@ -161,14 +164,17 @@ public class CordVtnArpProxy { |
| 161 | /** | 164 | /** |
| 162 | * Emits gratuitous ARP when a gateway mac address has been changed. | 165 | * Emits gratuitous ARP when a gateway mac address has been changed. |
| 163 | * | 166 | * |
| 164 | - * @param ip ip address to update MAC | 167 | + * @param gatewayIp gateway ip address to update MAC |
| 165 | - * @param mac new mac address | ||
| 166 | * @param hosts set of hosts to send gratuitous ARP packet | 168 | * @param hosts set of hosts to send gratuitous ARP packet |
| 167 | */ | 169 | */ |
| 168 | - public void sendGratuitousArp(IpAddress ip, MacAddress mac, Set<Host> hosts) { | 170 | + public void sendGratuitousArpForGateway(IpAddress gatewayIp, Set<Host> hosts) { |
| 169 | - checkArgument(!mac.equals(MacAddress.NONE)); | 171 | + MacAddress gatewayMac = gateways.get(gatewayIp.getIp4Address()); |
| 172 | + if (gatewayMac == null) { | ||
| 173 | + log.debug("Gateway {} is not registered to ARP proxy", gatewayIp.toString()); | ||
| 174 | + return; | ||
| 175 | + } | ||
| 170 | 176 | ||
| 171 | - Ethernet ethArp = buildGratuitousArp(ip.getIp4Address(), mac); | 177 | + Ethernet ethArp = buildGratuitousArp(gatewayIp.getIp4Address(), gatewayMac); |
| 172 | hosts.stream().forEach(host -> { | 178 | hosts.stream().forEach(host -> { |
| 173 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() | 179 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
| 174 | .setOutput(host.location().port()) | 180 | .setOutput(host.location().port()) | ... | ... |
| ... | @@ -16,7 +16,9 @@ | ... | @@ -16,7 +16,9 @@ |
| 16 | package org.onosproject.cordvtn; | 16 | package org.onosproject.cordvtn; |
| 17 | 17 | ||
| 18 | import com.fasterxml.jackson.databind.JsonNode; | 18 | import com.fasterxml.jackson.databind.JsonNode; |
| 19 | +import com.google.common.collect.Maps; | ||
| 19 | import com.google.common.collect.Sets; | 20 | import com.google.common.collect.Sets; |
| 21 | +import org.onlab.packet.IpAddress; | ||
| 20 | import org.onlab.packet.MacAddress; | 22 | import org.onlab.packet.MacAddress; |
| 21 | import org.onlab.packet.TpPort; | 23 | import org.onlab.packet.TpPort; |
| 22 | import org.onosproject.core.ApplicationId; | 24 | import org.onosproject.core.ApplicationId; |
| ... | @@ -24,6 +26,7 @@ import org.onosproject.net.DeviceId; | ... | @@ -24,6 +26,7 @@ import org.onosproject.net.DeviceId; |
| 24 | import org.onosproject.net.config.Config; | 26 | import org.onosproject.net.config.Config; |
| 25 | import org.slf4j.Logger; | 27 | import org.slf4j.Logger; |
| 26 | 28 | ||
| 29 | +import java.util.Map; | ||
| 27 | import java.util.Set; | 30 | import java.util.Set; |
| 28 | 31 | ||
| 29 | import static com.google.common.base.Preconditions.checkNotNull; | 32 | import static com.google.common.base.Preconditions.checkNotNull; |
| ... | @@ -36,6 +39,9 @@ public class CordVtnConfig extends Config<ApplicationId> { | ... | @@ -36,6 +39,9 @@ public class CordVtnConfig extends Config<ApplicationId> { |
| 36 | 39 | ||
| 37 | protected final Logger log = getLogger(getClass()); | 40 | protected final Logger log = getLogger(getClass()); |
| 38 | 41 | ||
| 42 | + public static final String PRIVATE_GATEWAY_MAC = "privateGatewayMac"; | ||
| 43 | + public static final String PUBLIC_GATEWAYS = "publicGateways"; | ||
| 44 | + public static final String GATEWAY_IP = "gatewayIp"; | ||
| 39 | public static final String GATEWAY_MAC = "gatewayMac"; | 45 | public static final String GATEWAY_MAC = "gatewayMac"; |
| 40 | public static final String LOCAL_MANAGEMENT_IP = "localManagementIp"; | 46 | public static final String LOCAL_MANAGEMENT_IP = "localManagementIp"; |
| 41 | public static final String OVSDB_PORT = "ovsdbPort"; | 47 | public static final String OVSDB_PORT = "ovsdbPort"; |
| ... | @@ -80,12 +86,12 @@ public class CordVtnConfig extends Config<ApplicationId> { | ... | @@ -80,12 +86,12 @@ public class CordVtnConfig extends Config<ApplicationId> { |
| 80 | } | 86 | } |
| 81 | 87 | ||
| 82 | /** | 88 | /** |
| 83 | - * Returns gateway MAC address. | 89 | + * Returns private network gateway MAC address. |
| 84 | * | 90 | * |
| 85 | * @return mac address, or null | 91 | * @return mac address, or null |
| 86 | */ | 92 | */ |
| 87 | - public MacAddress gatewayMac() { | 93 | + public MacAddress privateGatewayMac() { |
| 88 | - JsonNode jsonNode = object.get(GATEWAY_MAC); | 94 | + JsonNode jsonNode = object.get(PRIVATE_GATEWAY_MAC); |
| 89 | if (jsonNode == null) { | 95 | if (jsonNode == null) { |
| 90 | return null; | 96 | return null; |
| 91 | } | 97 | } |
| ... | @@ -99,6 +105,31 @@ public class CordVtnConfig extends Config<ApplicationId> { | ... | @@ -99,6 +105,31 @@ public class CordVtnConfig extends Config<ApplicationId> { |
| 99 | } | 105 | } |
| 100 | 106 | ||
| 101 | /** | 107 | /** |
| 108 | + * Returns public network gateway IP and MAC address pairs. | ||
| 109 | + * | ||
| 110 | + * @return map of ip and mac address | ||
| 111 | + */ | ||
| 112 | + public Map<IpAddress, MacAddress> publicGateways() { | ||
| 113 | + JsonNode jsonNodes = object.get(PUBLIC_GATEWAYS); | ||
| 114 | + if (jsonNodes == null) { | ||
| 115 | + return null; | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + Map<IpAddress, MacAddress> publicGateways = Maps.newHashMap(); | ||
| 119 | + jsonNodes.forEach(jsonNode -> { | ||
| 120 | + try { | ||
| 121 | + publicGateways.put( | ||
| 122 | + IpAddress.valueOf(jsonNode.path(GATEWAY_IP).asText()), | ||
| 123 | + MacAddress.valueOf(jsonNode.path(GATEWAY_MAC).asText())); | ||
| 124 | + } catch (IllegalArgumentException | NullPointerException e) { | ||
| 125 | + log.error("Wrong address format {}", e.toString()); | ||
| 126 | + } | ||
| 127 | + }); | ||
| 128 | + | ||
| 129 | + return publicGateways; | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + /** | ||
| 102 | * Returns local management network address. | 133 | * Returns local management network address. |
| 103 | * | 134 | * |
| 104 | * @return network address | 135 | * @return network address | ... | ... |
| ... | @@ -16,10 +16,11 @@ | ... | @@ -16,10 +16,11 @@ |
| 16 | package org.onosproject.cordvtn; | 16 | package org.onosproject.cordvtn; |
| 17 | 17 | ||
| 18 | import org.onlab.packet.IpAddress; | 18 | import org.onlab.packet.IpAddress; |
| 19 | +import org.onlab.packet.MacAddress; | ||
| 19 | import org.onosproject.net.ConnectPoint; | 20 | import org.onosproject.net.ConnectPoint; |
| 20 | import org.onosproject.net.HostId; | 21 | import org.onosproject.net.HostId; |
| 21 | 22 | ||
| 22 | -import java.util.Set; | 23 | +import java.util.Map; |
| 23 | 24 | ||
| 24 | /** | 25 | /** |
| 25 | * Service for provisioning overlay virtual networks on compute nodes. | 26 | * Service for provisioning overlay virtual networks on compute nodes. |
| ... | @@ -67,8 +68,8 @@ public interface CordVtnService { | ... | @@ -67,8 +68,8 @@ public interface CordVtnService { |
| 67 | * | 68 | * |
| 68 | * @param vSgHost host id of vSG host | 69 | * @param vSgHost host id of vSG host |
| 69 | * @param serviceVlan service vlan id | 70 | * @param serviceVlan service vlan id |
| 70 | - * @param vSgIps set of ip address of vSGs running in this vSG host | 71 | + * @param vSgs map of ip and mac address of vSGs running in this vSG host |
| 71 | */ | 72 | */ |
| 72 | void updateVirtualSubscriberGateways(HostId vSgHost, String serviceVlan, | 73 | void updateVirtualSubscriberGateways(HostId vSgHost, String serviceVlan, |
| 73 | - Set<IpAddress> vSgIps); | 74 | + Map<IpAddress, MacAddress> vSgs); |
| 74 | } | 75 | } | ... | ... |
| ... | @@ -17,7 +17,7 @@ package org.onosproject.cordvtn.rest; | ... | @@ -17,7 +17,7 @@ package org.onosproject.cordvtn.rest; |
| 17 | 17 | ||
| 18 | import com.fasterxml.jackson.databind.JsonNode; | 18 | import com.fasterxml.jackson.databind.JsonNode; |
| 19 | import com.fasterxml.jackson.databind.ObjectMapper; | 19 | import com.fasterxml.jackson.databind.ObjectMapper; |
| 20 | -import com.google.common.collect.Sets; | 20 | +import com.google.common.collect.Maps; |
| 21 | import org.onlab.packet.IpAddress; | 21 | import org.onlab.packet.IpAddress; |
| 22 | import org.onlab.packet.MacAddress; | 22 | import org.onlab.packet.MacAddress; |
| 23 | import org.onosproject.cordvtn.CordVtnService; | 23 | import org.onosproject.cordvtn.CordVtnService; |
| ... | @@ -36,7 +36,7 @@ import javax.ws.rs.Produces; | ... | @@ -36,7 +36,7 @@ import javax.ws.rs.Produces; |
| 36 | import javax.ws.rs.core.MediaType; | 36 | import javax.ws.rs.core.MediaType; |
| 37 | import javax.ws.rs.core.Response; | 37 | import javax.ws.rs.core.Response; |
| 38 | import java.io.InputStream; | 38 | import java.io.InputStream; |
| 39 | -import java.util.Set; | 39 | +import java.util.Map; |
| 40 | 40 | ||
| 41 | 41 | ||
| 42 | /** | 42 | /** |
| ... | @@ -88,16 +88,17 @@ public class NeutronMl2PortsWebResource extends AbstractWebResource { | ... | @@ -88,16 +88,17 @@ public class NeutronMl2PortsWebResource extends AbstractWebResource { |
| 88 | 88 | ||
| 89 | // this is allowed address pairs updates | 89 | // this is allowed address pairs updates |
| 90 | MacAddress mac = MacAddress.valueOf(jsonNode.path(MAC_ADDRESS).asText()); | 90 | MacAddress mac = MacAddress.valueOf(jsonNode.path(MAC_ADDRESS).asText()); |
| 91 | - Set<IpAddress> vSgIps = Sets.newHashSet(); | 91 | + Map<IpAddress, MacAddress> vSgs = Maps.newHashMap(); |
| 92 | jsonNode.path(ADDRESS_PAIRS).forEach(addrPair -> { | 92 | jsonNode.path(ADDRESS_PAIRS).forEach(addrPair -> { |
| 93 | - IpAddress ip = IpAddress.valueOf(addrPair.path(IP_ADDERSS).asText()); | 93 | + IpAddress pairIp = IpAddress.valueOf(addrPair.path(IP_ADDERSS).asText()); |
| 94 | - vSgIps.add(ip); | 94 | + MacAddress pairMac = MacAddress.valueOf(addrPair.path(MAC_ADDRESS).asText()); |
| 95 | + vSgs.put(pairIp, pairMac); | ||
| 95 | }); | 96 | }); |
| 96 | 97 | ||
| 97 | service.updateVirtualSubscriberGateways( | 98 | service.updateVirtualSubscriberGateways( |
| 98 | HostId.hostId(mac), | 99 | HostId.hostId(mac), |
| 99 | name.substring(STAG_BEGIN_INDEX), | 100 | name.substring(STAG_BEGIN_INDEX), |
| 100 | - vSgIps); | 101 | + vSgs); |
| 101 | } catch (Exception e) { | 102 | } catch (Exception e) { |
| 102 | return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); | 103 | return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); |
| 103 | } | 104 | } | ... | ... |
-
Please register or login to post a comment