L3_FORWARDING ((short) 70, "Layer 3 forwarding/lookup service"),
L2_REWRITE ((short) 80, "Layer2 rewrite service"),
INGRESS_ACL ((short) 90, "Ingress Acces-control"),
- OUTBOUND_NAT ((short) 100, "SNAT for traffic accessing external network"),
+ OUTBOUND_NAT ((short) 100, "DNAT for outbound floating-ip traffic"),
L2_FORWARDING ((short) 110, "Layer2 mac,vlan based forwarding");
short table;
package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services;
import java.math.BigInteger;
+import java.net.Inet6Address;
import java.net.InetAddress;
import java.util.List;
import com.google.common.collect.Lists;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class RoutingService extends AbstractServiceInstance implements RoutingProvider, ConfigInterface {
+ private static final Logger LOG = LoggerFactory.getLogger(RoutingService.class);
public RoutingService() {
super(Service.ROUTING);
}
MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(sourceSegId));
}
+ if (address instanceof Inet6Address) {
+ // WORKAROUND: For now ipv6 is not supported
+ // TODO: implement ipv6 case
+ LOG.debug("ipv6 address is not implemented yet. address {}",
+ address);
+ new Status(StatusCode.NOTIMPLEMENTED);
+ }
final String prefixString = address.getHostAddress() + "/" + mask;
MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(prefixString));
public final class ArpResolverMetadata {
+ private final Ipv4Address gatewayIpAddress;
+ private final Long externalNetworkBridgeDpid;
+ private final Ipv4Address arpRequestSourceIp;
+ private final MacAddress arpRequestSourceMacAddress;
+ private final boolean periodicRefresh;
private RemoveFlowInput flowToRemove;
- private Ipv4Address gatewayIpAddress;
private MacAddress gatewayMacAddress;
- private boolean periodicRefresh;
- public ArpResolverMetadata(){
-
- }
- public ArpResolverMetadata(RemoveFlowInput flowToRemove, Ipv4Address gatewayIpAddress, boolean periodicRefresh){
- this.flowToRemove = flowToRemove;
+ public ArpResolverMetadata(final Long externalNetworkBridgeDpid,
+ final Ipv4Address gatewayIpAddress, final Ipv4Address arpRequestSourceIp,
+ final MacAddress arpRequestMacAddress, final boolean periodicRefresh){
+ this.externalNetworkBridgeDpid = externalNetworkBridgeDpid;
this.gatewayIpAddress = gatewayIpAddress;
- this.periodicRefresh = periodicRefresh;
- }
-
- public ArpResolverMetadata(RemoveFlowInput flowToRemove, Ipv4Address gatewayIpAddress, MacAddress gatewayMacAddress, boolean periodicRefresh){
- this.flowToRemove = flowToRemove;
- this.gatewayIpAddress = gatewayIpAddress;
- this.gatewayMacAddress = gatewayMacAddress;
+ this.arpRequestSourceIp = arpRequestSourceIp;
+ this.arpRequestSourceMacAddress = arpRequestMacAddress;
this.periodicRefresh = periodicRefresh;
}
public boolean isPeriodicRefresh() {
return periodicRefresh;
}
- public void setPeriodicRefresh(boolean periodicRefresh) {
- this.periodicRefresh = periodicRefresh;
- }
public void setFlowToRemove(RemoveFlowInput flowToRemove) {
this.flowToRemove = flowToRemove;
}
public Ipv4Address getGatewayIpAddress() {
return gatewayIpAddress;
}
- public void setGatewayIpAddress(Ipv4Address gatewayIpAddress) {
- this.gatewayIpAddress = gatewayIpAddress;
- }
public MacAddress getGatewayMacAddress() {
return gatewayMacAddress;
}
this.gatewayMacAddress = gatewayMacAddress;
}
+ public Long getExternalNetworkBridgeDpid() {
+ return externalNetworkBridgeDpid;
+ }
+ public Ipv4Address getArpRequestSourceIp() {
+ return arpRequestSourceIp;
+ }
+ public MacAddress getArpRequestMacAddress() {
+ return arpRequestSourceMacAddress;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime
+ * result
+ + ((arpRequestSourceMacAddress == null) ? 0 : arpRequestSourceMacAddress
+ .hashCode());
+ result = prime
+ * result
+ + ((arpRequestSourceIp == null) ? 0 : arpRequestSourceIp
+ .hashCode());
+ result = prime
+ * result
+ + ((externalNetworkBridgeDpid == null) ? 0
+ : externalNetworkBridgeDpid.hashCode());
+ result = prime
+ * result
+ + ((gatewayIpAddress == null) ? 0 : gatewayIpAddress.hashCode());
+ result = prime * result + (periodicRefresh ? 1231 : 1237);
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ArpResolverMetadata other = (ArpResolverMetadata) obj;
+ if (arpRequestSourceMacAddress == null) {
+ if (other.arpRequestSourceMacAddress != null)
+ return false;
+ } else if (!arpRequestSourceMacAddress.equals(other.arpRequestSourceMacAddress))
+ return false;
+ if (arpRequestSourceIp == null) {
+ if (other.arpRequestSourceIp != null)
+ return false;
+ } else if (!arpRequestSourceIp.equals(other.arpRequestSourceIp))
+ return false;
+ if (externalNetworkBridgeDpid == null) {
+ if (other.externalNetworkBridgeDpid != null)
+ return false;
+ } else if (!externalNetworkBridgeDpid
+ .equals(other.externalNetworkBridgeDpid))
+ return false;
+ if (gatewayIpAddress == null) {
+ if (other.gatewayIpAddress != null)
+ return false;
+ } else if (!gatewayIpAddress.equals(other.gatewayIpAddress))
+ return false;
+ if (periodicRefresh != other.periodicRefresh)
+ return false;
+ return true;
+ }
+
}
import org.opendaylight.controller.liblldp.NetUtils;
import org.opendaylight.controller.liblldp.PacketException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class ArpResolverUtils {
+ private static final Logger LOG = LoggerFactory.getLogger(ArpResolverUtils.class);
+
static {
Ethernet.etherTypeClassMap.put(EtherTypes.ARP.shortValue(), Arp.class);
*
* @param potentialArp the packet for deserialization
* @return ARP packet if received packet is ARP and deserialization was successful
- * @throws PacketException if packet is not ARP or deserialization was not successful
*/
- public static Arp getArpFrom(PacketReceived potentialArp) throws PacketException {
+ public static Arp getArpFrom(PacketReceived potentialArp) {
byte[] payload = potentialArp.getPayload();
Ethernet ethPkt = new Ethernet();
- ethPkt.deserialize(payload, 0, payload.length * NetUtils.NumBitsInAByte);
+ try {
+ ethPkt.deserialize(payload, 0, payload.length * NetUtils.NumBitsInAByte);
+ } catch (PacketException e) {
+ LOG.trace("Failed to decode the incoming packet. ignoring it.");
+ }
if (ethPkt.getPayload() instanceof Arp) {
return (Arp) ethPkt.getPayload();
}
- throw new PacketException("Packet is not ARP: " + potentialArp);
+ return null;
}
}
import static com.google.common.base.Preconditions.checkNotNull;
import java.math.BigInteger;
-import java.util.Map;
+import java.util.Map.Entry;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
private ArpSender arpSender;
private SalFlowService flowService;
private final AtomicLong flowCookie = new AtomicLong();
- private final Map<Ipv4Address, ArpResolverMetadata> arpRemoveFlowInputAndL3EpKeyById =
+ private final ConcurrentMap<Ipv4Address, ArpResolverMetadata> gatewayToArpMetadataMap =
new ConcurrentHashMap<Ipv4Address, ArpResolverMetadata>();
private final int ARP_WATCH_BROTHERS = 10;
private final int WAIT_CYCLES = 3;
private final int PER_CYCLE_WAIT_DURATION = 1000;
+ private final int REFRESH_INTERVAL = 10;
private final ListeningExecutorService arpWatcherWall = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(ARP_WATCH_BROTHERS));
+ private final ScheduledExecutorService gatewayMacRefresherPool = Executors.newScheduledThreadPool(1);
+ private final ScheduledExecutorService refreshRequester = Executors.newSingleThreadScheduledExecutor();
private AtomicBoolean initializationDone = new AtomicBoolean(false);
static {
this.arpSender = null;
}
flowService = providerContext.getRpcService(SalFlowService.class);
+ refreshRequester.scheduleWithFixedDelay(new Runnable(){
+
+ @Override
+ public void run() {
+ if (!gatewayToArpMetadataMap.isEmpty()){
+ for(final Entry<Ipv4Address, ArpResolverMetadata> gatewayToArpMetadataEntry : gatewayToArpMetadataMap.entrySet()){
+ final Ipv4Address gatewayIp = gatewayToArpMetadataEntry.getKey();
+ final ArpResolverMetadata gatewayMetaData = gatewayToArpMetadataEntry.getValue();
+ gatewayMacRefresherPool.schedule(new Runnable(){
+
+ @Override
+ public void run() {
+
+ final Node externalNetworkBridge = getExternalBridge(gatewayMetaData.getExternalNetworkBridgeDpid());
+ if(externalNetworkBridge == null){
+ LOG.error("MAC address for gateway {} can not be resolved, because external bridge {} "
+ + "is not connected to controller.",gatewayIp.getValue(),gatewayMetaData.getExternalNetworkBridgeDpid() );
+ }
+
+ LOG.debug("Refresh Gateway Mac for gateway {} using source ip {} and mac {} for ARP request",
+ gatewayIp.getValue(),gatewayMetaData.getArpRequestSourceIp().getValue(),gatewayMetaData.getArpRequestMacAddress().getValue());
+
+ sendGatewayArpRequest(externalNetworkBridge,gatewayIp,gatewayMetaData.getArpRequestSourceIp(), gatewayMetaData.getArpRequestMacAddress());
+ }
+ }, 1, TimeUnit.SECONDS);
+ }
+ }
+ }
+ }, REFRESH_INTERVAL, REFRESH_INTERVAL, TimeUnit.SECONDS);
}
}
/**
gatewayIp.getValue(),sourceIpAddress.getValue(),sourceMacAddress.getValue());
init();
- if(arpRemoveFlowInputAndL3EpKeyById.containsKey(gatewayIp)){
- if(arpRemoveFlowInputAndL3EpKeyById.get(gatewayIp).getGatewayMacAddress() != null){
+ if(gatewayToArpMetadataMap.containsKey(gatewayIp)){
+ if(gatewayToArpMetadataMap.get(gatewayIp).getGatewayMacAddress() != null){
return arpWatcherWall.submit(new Callable<MacAddress>(){
@Override
public MacAddress call() throws Exception {
- return arpRemoveFlowInputAndL3EpKeyById.get(gatewayIp).getGatewayMacAddress();
+ return gatewayToArpMetadataMap.get(gatewayIp).getGatewayMacAddress();
}
});
}
}else{
- arpRemoveFlowInputAndL3EpKeyById.put(gatewayIp,
- new ArpResolverMetadata(null, gatewayIp,periodicRefresh));
+ gatewayToArpMetadataMap.put(gatewayIp,new ArpResolverMetadata(
+ externalNetworkBridgeDpid, gatewayIp,sourceIpAddress,sourceMacAddress,periodicRefresh));
}
- final ArpMessageAddress senderAddress = new ArpMessageAddress(sourceMacAddress,sourceIpAddress);
-
- final String nodeName = OPENFLOW + externalNetworkBridgeDpid;
- final Node externalNetworkBridge = getOpenFlowNode(nodeName);
+ final Node externalNetworkBridge = getExternalBridge(externalNetworkBridgeDpid);
if(externalNetworkBridge == null){
LOG.error("MAC address for gateway {} can not be resolved, because external bridge {} "
+ "is not connected to controller.",gatewayIp.getValue(),externalNetworkBridgeDpid );
return null;
}
+
+ sendGatewayArpRequest(externalNetworkBridge,gatewayIp,sourceIpAddress, sourceMacAddress);
+
+ //Wait for MacAddress population in cache
+ return waitForMacAddress(gatewayIp);
+ }
+
+ private Node getExternalBridge(final Long externalNetworkBridgeDpid){
+ final String nodeName = OPENFLOW + externalNetworkBridgeDpid;
+
+ return getOpenFlowNode(nodeName);
+ }
+
+ private void sendGatewayArpRequest(final Node externalNetworkBridge,final Ipv4Address gatewayIp,
+ final Ipv4Address sourceIpAddress, final MacAddress sourceMacAddress){
+ final ArpMessageAddress senderAddress = new ArpMessageAddress(sourceMacAddress,sourceIpAddress);
+
//Build arp reply router flow
final Flow arpReplyToControllerFlow = createArpReplyToControllerFlow(senderAddress, gatewayIp);
-
final InstanceIdentifier<Node> nodeIid = InstanceIdentifier.builder(Nodes.class)
.child(Node.class, externalNetworkBridge.getKey())
.build();
LOG.debug("Flow to route ARP Reply to Controller installed successfully : {}", flowIid);
//cache metadata
- arpRemoveFlowInputAndL3EpKeyById.get(gatewayIp).setFlowToRemove(
+ gatewayToArpMetadataMap.get(gatewayIp).setFlowToRemove(
new RemoveFlowInputBuilder(arpReplyToControllerFlow).setNode(nodeRef).build());
//Broadcast ARP request packets
}
}
);
- //Wait for MacAddress population in cache
- return waitForMacAddress(gatewayIp);
}
private ListenableFuture<MacAddress> waitForMacAddress(final Ipv4Address gatewayIp){
//Sleep before checking mac address, so meanwhile ARP request packets
// will be broadcasted on the bridge.
Thread.sleep(PER_CYCLE_WAIT_DURATION);
- ArpResolverMetadata arpResolverMetadata = arpRemoveFlowInputAndL3EpKeyById.get(gatewayIp);
+ ArpResolverMetadata arpResolverMetadata = gatewayToArpMetadataMap.get(gatewayIp);
if(arpResolverMetadata != null && arpResolverMetadata.getGatewayMacAddress() != null){
if(!arpResolverMetadata.isPeriodicRefresh()){
- return arpRemoveFlowInputAndL3EpKeyById.remove(gatewayIp).getGatewayMacAddress();
+ return gatewayToArpMetadataMap.remove(gatewayIp).getGatewayMacAddress();
}
return arpResolverMetadata.getGatewayMacAddress();
}
}
});
}
+
private static @Nullable Ipv4Address getIPv4Addresses(IpAddress ipAddress) {
if (ipAddress.getIpv4Address() == null) {
return null;
@Override
public void onPacketReceived(PacketReceived potentialArp) {
- Arp arp = null;
- try {
- arp = ArpResolverUtils.getArpFrom(potentialArp);
- } catch (Exception e) {
- LOG.trace(
- "Failed to decode potential ARP packet. This could occur when other than ARP packet was received.",
- e);
- return;
- }
- if (arp.getOperation() != ArpOperation.REPLY.intValue()) {
- LOG.trace("Packet is not ARP REPLY packet.");
- return;
- }
- if (LOG.isTraceEnabled()) {
- LOG.trace("ARP REPLY received - {}", ArpUtils.getArpToStringFormat(arp));
- }
- NodeKey nodeKey = potentialArp.getIngress().getValue().firstKeyOf(Node.class, NodeKey.class);
- if (nodeKey == null) {
- LOG.info("Unknown source node of ARP packet: {}", potentialArp);
- return;
- }
- Ipv4Address gatewayIpAddress = ArpUtils.bytesToIp(arp.getSenderProtocolAddress());
- MacAddress gatewayMacAddress = ArpUtils.bytesToMac(arp.getSenderHardwareAddress());
- ArpResolverMetadata removeFlowInputAndL3EpKey = arpRemoveFlowInputAndL3EpKeyById.get(gatewayIpAddress);
- if(removeFlowInputAndL3EpKey != null){
- removeFlowInputAndL3EpKey.setGatewayMacAddress(gatewayMacAddress);
- flowService.removeFlow(removeFlowInputAndL3EpKey.getFlowToRemove());
+ Arp arp = ArpResolverUtils.getArpFrom(potentialArp);
+ if(arp != null){
+ if (arp.getOperation() != ArpOperation.REPLY.intValue()) {
+ LOG.trace("Packet is not ARP REPLY packet.");
+ return;
+ }
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("ARP REPLY received - {}", ArpUtils.getArpToStringFormat(arp));
+ }
+ NodeKey nodeKey = potentialArp.getIngress().getValue().firstKeyOf(Node.class, NodeKey.class);
+ if (nodeKey == null) {
+ LOG.info("Unknown source node of ARP packet: {}", potentialArp);
+ return;
+ }
+ Ipv4Address gatewayIpAddress = ArpUtils.bytesToIp(arp.getSenderProtocolAddress());
+ MacAddress gatewayMacAddress = ArpUtils.bytesToMac(arp.getSenderHardwareAddress());
+ ArpResolverMetadata candidateGatewayIp = gatewayToArpMetadataMap.get(gatewayIpAddress);
+ if(candidateGatewayIp != null){
+ LOG.debug("Resolved MAC for Gateway Ip {} is {}",gatewayIpAddress.getValue(),gatewayMacAddress.getValue());
+ candidateGatewayIp.setGatewayMacAddress(gatewayMacAddress);
+ flowService.removeFlow(candidateGatewayIp.getFlowToRemove());
+ }
}
}
public void setDependencies(Object impl) {}
@Override
- public void stopPeriodicReferesh(Ipv4Address gatewayIp) {
+ public void stopPeriodicRefresh(Ipv4Address gatewayIp) {
init();
- arpRemoveFlowInputAndL3EpKeyById.remove(gatewayIp);
+ gatewayToArpMetadataMap.remove(gatewayIp);
}
}
String memberSubnetID = neutronLBPoolMember.getPoolMemberSubnetID();
if (memberSubnetID != null && memberAdminStateIsUp != null &&
memberSubnetID.equals(loadBalancerSubnetID) && memberAdminStateIsUp) {
- String memberID = neutronLBPoolMember.getPoolMemberID();
+ String memberID = neutronLBPoolMember.getID();
String memberIP = neutronLBPoolMember.getPoolMemberAddress();
Integer memberPort = neutronLBPoolMember.getPoolMemberProtoPort();
if (memberID == null || memberIP == null || memberPort == null) {
List<LoadBalancerConfiguration> lbConfigList = extractLBConfiguration(neutronLBPool);
final List<Node> nodes = nodeCacheManager.getBridgeNodes();
if (lbConfigList == null) {
- LOG.debug("Neutron LB configuration invalid for pool {} ", neutronLBPool.getLoadBalancerPoolID());
+ LOG.debug("Neutron LB configuration invalid for pool {} ", neutronLBPool.getID());
} else if (lbConfigList.size() == 0) {
- LOG.debug("No Neutron LB VIP not created yet for pool {} ", neutronLBPool.getLoadBalancerPoolID());
+ LOG.debug("No Neutron LB VIP not created yet for pool {} ", neutronLBPool.getID());
} else if (nodes.isEmpty()) {
- LOG.debug("Noop with LB pool {} creation because no nodes available.", neutronLBPool.getLoadBalancerPoolID());
+ LOG.debug("Noop with LB pool {} creation because no nodes available.", neutronLBPool.getID());
} else {
for (LoadBalancerConfiguration lbConfig: lbConfigList) {
if (!lbConfig.isValid()) {
List<LoadBalancerConfiguration> lbConfigList = extractLBConfiguration(neutronLBPool);
final List<Node> nodes = nodeCacheManager.getBridgeNodes();
if (lbConfigList == null) {
- LOG.debug("Neutron LB configuration invalid for pool {} ", neutronLBPool.getLoadBalancerPoolID());
+ LOG.debug("Neutron LB configuration invalid for pool {} ", neutronLBPool.getID());
} else if (lbConfigList.size() == 0) {
- LOG.debug("No Neutron LB VIP not created yet for pool {} ", neutronLBPool.getLoadBalancerPoolID());
+ LOG.debug("No Neutron LB VIP not created yet for pool {} ", neutronLBPool.getID());
} else if (nodes.isEmpty()) {
- LOG.debug("Noop with LB pool {} deletion because no nodes available.", neutronLBPool.getLoadBalancerPoolID());
+ LOG.debug("Noop with LB pool {} deletion because no nodes available.", neutronLBPool.getID());
} else {
for (LoadBalancerConfiguration lbConfig: lbConfigList) {
if (!lbConfig.isValid()) {
memberSubnetID = neutronLBPoolMember.getPoolMemberSubnetID();
if (memberSubnetID != null && memberAdminStateIsUp != null &&
memberSubnetID.equals(loadBalancerSubnetID) && memberAdminStateIsUp) {
- memberID = neutronLBPoolMember.getPoolMemberID();
+ memberID = neutronLBPoolMember.getID();
memberIP = neutronLBPoolMember.getPoolMemberAddress();
memberPort = neutronLBPoolMember.getPoolMemberProtoPort();
if (memberID == null || memberIP == null || memberPort == null) {
if (lbConfig == null) {
LOG.debug("Neutron LB configuration invalid for member {} ", neutronLBPoolMember.getPoolMemberAddress());
} else if (lbConfig.getVip() == null) {
- LOG.debug("Neutron LB VIP not created yet for member {} ", neutronLBPoolMember.getPoolMemberID());
+ LOG.debug("Neutron LB VIP not created yet for member {} ", neutronLBPoolMember.getID());
} else if (!lbConfig.isValid()) {
LOG.debug("Neutron LB pool configuration invalid for {} ", lbConfig.getName());
} else if (nodes.isEmpty()) {
- LOG.debug("Noop with LB pool member {} creation because no nodes available.", neutronLBPoolMember.getPoolMemberID());
+ LOG.debug("Noop with LB pool member {} creation because no nodes available.", neutronLBPoolMember.getID());
} else {
for (Node node : nodes) {
loadBalancerProvider.programLoadBalancerPoolMemberRules(node,
lbConfig,
- lbConfig.getMembers().get(neutronLBPoolMember.getPoolMemberID()), Action.ADD);
+ lbConfig.getMembers().get(neutronLBPoolMember.getID()), Action.ADD);
}
}
}
if (lbConfig == null) {
LOG.debug("Neutron LB configuration invalid for member {} ", neutronLBPoolMember.getPoolMemberAddress());
} else if (lbConfig.getVip() == null) {
- LOG.debug("Neutron LB VIP not created yet for member {} ", neutronLBPoolMember.getPoolMemberID());
+ LOG.debug("Neutron LB VIP not created yet for member {} ", neutronLBPoolMember.getID());
} else if (!lbConfig.isValid()) {
LOG.debug("Neutron LB pool configuration invalid for {} ", lbConfig.getName());
} else if (nodes.isEmpty()) {
- LOG.debug("Noop with LB pool member {} deletion because no nodes available.", neutronLBPoolMember.getPoolMemberID());
+ LOG.debug("Noop with LB pool member {} deletion because no nodes available.", neutronLBPoolMember.getID());
} else {
/* As of now, deleting a member involves recomputing member indices.
* This is best done through a complete update of the load balancer instance.
*/
LoadBalancerConfiguration newLBConfig = new LoadBalancerConfiguration(lbConfig);
- newLBConfig.removeMember(neutronLBPoolMember.getPoolMemberID());
+ newLBConfig.removeMember(neutronLBPoolMember.getID());
for (Node node : nodes) {
loadBalancerProvider.programLoadBalancerRules(node, lbConfig, Action.DELETE);
* configuration from the neutron LB cache based on member info
*/
public LoadBalancerConfiguration extractLBConfiguration(NeutronLoadBalancerPoolMember neutronLBPoolMember) {
- String memberID = neutronLBPoolMember.getPoolMemberID();
+ String memberID = neutronLBPoolMember.getID();
String memberIP = neutronLBPoolMember.getPoolMemberAddress();
String memberSubnetID = neutronLBPoolMember.getPoolMemberSubnetID();
Integer memberPort = neutronLBPoolMember.getPoolMemberProtoPort();
Integer otherMemberPort;
for (NeutronLoadBalancerPoolMember otherMember: neutronLBPool.getLoadBalancerPoolMembers()) {
- otherMemberID = otherMember.getPoolMemberID();
+ otherMemberID = otherMember.getID();
if (otherMemberID.equals(memberID)) {
continue; //skip
}
/**
* Method will trigger the mac resolution for gateway IP. If user set periodicRefresh to true,
- * it will periodically trigger the gateway resolution after a specific time interval. If
- * periodicRefresh is false, it will just do one time gateway resolution.
- * @param externalNetworkBridgeDpid
- * @param gatewayIp
- * @param periodicReferesh
+ * it will periodically trigger the gateway resolution after a specific time interval using the
+ * given source IP and MAC addresses. It will also cache the source IP & MAC in case of periodicRefresh.
+ * If periodicRefresh is false, it will just do one time gateway resolution and won't cache any internal data.
+ * If user call the same method with different source ip and mac address, GatewayMacResolver service will
+ * update the internally cached data with these new source ip and mac address and will use it as per
+ * periodicRefresh flag.
+ * @param externalNetworkBridgeDpid This bridge will be used for sending ARP request
+ * @param gatewayIp ARP request will be send for this ip address
+ * @param periodicReferesh Do you want to periodically refresh the gateway mac?
* @return
*/
public ListenableFuture<MacAddress> resolveMacAddress( final Long externalNetworkBridgeDpid, final Ipv4Address gatewayIp,
* Method will stop the periodic refresh of the given gateway ip address.
* @param gatewayIp
*/
- public void stopPeriodicReferesh(final Ipv4Address gatewayIp);
+ public void stopPeriodicRefresh(final Ipv4Address gatewayIp);
}
if(externalNetwork != null){
if(externalNetwork.isRouterExternal()){
final NeutronSubnet externalSubnet = getExternalNetworkSubnet(neutronPort);
- if(externalSubnet != null){
- gatewayMacResolver.stopPeriodicReferesh(new Ipv4Address(externalSubnet.getGatewayIP()));
+ // TODO support IPv6
+ if (externalSubnet != null &&
+ externalSubnet.getIpVersion() == 4) {
+ gatewayMacResolver.stopPeriodicRefresh(new Ipv4Address(externalSubnet.getGatewayIP()));
}
}
}
// there.
//
if (!isDelete) {
- for (Neutron_IPs neutronIP : neutronPort.getFixedIPs()) {
- NeutronRouter_Interface neutronRouterInterface =
+ if (neutronPort.getFixedIPs() != null) {
+ for (Neutron_IPs neutronIP : neutronPort.getFixedIPs()) {
+ NeutronRouter_Interface neutronRouterInterface =
subnetIdToRouterInterfaceCache.get(neutronIP.getSubnetUUID());
- if (neutronRouterInterface != null) {
- this.handleNeutronRouterInterfaceEvent(null /*neutronRouter*/, neutronRouterInterface, action);
+ if (neutronRouterInterface != null) {
+ this.handleNeutronRouterInterfaceEvent(null /*neutronRouter*/, neutronRouterInterface, action);
+ }
}
}
}
}
private NeutronSubnet getExternalNetworkSubnet(NeutronPort gatewayPort){
- NeutronSubnet extSubnet = null;
- for (NeutronSubnet subnet : neutronSubnetCache.getAllSubnets()){
- if(subnet.getPortsInSubnet().contains(gatewayPort)){
- extSubnet = subnet;
- break;
+ for (Neutron_IPs neutronIPs : gatewayPort.getFixedIPs()) {
+ String subnetUUID = neutronIPs.getSubnetUUID();
+ NeutronSubnet extSubnet = neutronSubnetCache.getSubnet(subnetUUID);
+ if (extSubnet.getGatewayIP() == null) {
+ continue;
}
+ return extSubnet;
}
- return extSubnet;
+ return null;
}
public void triggerGatewayMacResolver(final Node node, final NeutronPort gatewayPort ){
if(externalNetwork != null){
if(externalNetwork.isRouterExternal()){
final NeutronSubnet externalSubnet = getExternalNetworkSubnet(gatewayPort);
- if(externalSubnet != null){
- if(externalSubnet.getGatewayIP() != null){
- LOG.info("Trigger MAC resolution for gateway ip {} on Node {}", externalSubnet.getGatewayIP(), node.getNodeId());
-
- ListenableFuture<MacAddress> gatewayMacAddress =
- gatewayMacResolver.resolveMacAddress(getDpidForExternalBridge(node),
- new Ipv4Address(externalSubnet.getGatewayIP()),
- new Ipv4Address(gatewayPort.getFixedIPs().get(0).getIpAddress()),
- new MacAddress(gatewayPort.getMacAddress()),
- false);
- if(gatewayMacAddress != null){
- Futures.addCallback(gatewayMacAddress, new FutureCallback<MacAddress>(){
- @Override
- public void onSuccess(MacAddress result) {
- if(result != null){
+
+ // TODO: address IPv6 case.
+ if (externalSubnet != null &&
+ externalSubnet.getIpVersion() == 4) {
+ LOG.info("Trigger MAC resolution for gateway ip {} on Node {}",externalSubnet.getGatewayIP(),node.getNodeId());
+ ListenableFuture<MacAddress> gatewayMacAddress =
+ gatewayMacResolver.resolveMacAddress(getDpidForExternalBridge(node),
+ new Ipv4Address(externalSubnet.getGatewayIP()),
+ new Ipv4Address(gatewayPort.getFixedIPs().get(0).getIpAddress()),
+ new MacAddress(gatewayPort.getMacAddress()),
+ true);
+ if(gatewayMacAddress != null){
+ Futures.addCallback(gatewayMacAddress, new FutureCallback<MacAddress>(){
+ @Override
+ public void onSuccess(MacAddress result) {
+ if(result != null){
+ if(!result.getValue().equals(externalRouterMac)){
updateExternalRouterMac(result.getValue());
- LOG.info("Resolved MAC address for gateway IP {} is {}", externalSubnet.getGatewayIP(), result.getValue());
- }else{
- LOG.warn("MAC address resolution failed for gateway IP {}", externalSubnet.getGatewayIP());
+ LOG.info("Resolved MAC address for gateway IP {} is {}", externalSubnet.getGatewayIP(),result.getValue());
}
- }
-
- @Override
- public void onFailure(Throwable t) {
+ }else{
LOG.warn("MAC address resolution failed for gateway IP {}", externalSubnet.getGatewayIP());
}
- }, gatewayMacResolverPool);
- }
- }else{
- LOG.warn("No gateway IP address found for external subnet {}", externalSubnet);
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ LOG.warn("MAC address resolution failed for gateway IP {}", externalSubnet.getGatewayIP());
+ }
+ }, gatewayMacResolverPool);
}
- }else{
- LOG.warn("Neutron subnet not found for external network {}", externalNetwork);
+ } else {
+ LOG.warn("No gateway IP address found for external network {}", externalNetwork);
}
}
}else{
LOG.error("getDHCPServerPort: No fixed ip is assigned");
return null;
}
- String subnetUUID = fixedIps.iterator().next().getSubnetUUID();
- NeutronSubnet neutronSubnet = neutronSubnetCache.getSubnet(subnetUUID);
- List<NeutronPort> ports = neutronSubnet.getPortsInSubnet();
- for (NeutronPort port : ports) {
- if (port.getDeviceOwner().contains("dhcp")) {
+
+ String networkUUID = neutronPort.getNetworkUUID();
+ for (NeutronPort port : neutronPortCache.getAllPorts()) {
+ if (port.getNetworkUUID() == networkUUID && port.getDeviceOwner().contains("dhcp")) {
return port;
}
}
when(neutronLBPoolMember.getPoolMemberAdminStateIsUp()).thenReturn(true);
when(neutronLBPoolMember.getPoolMemberSubnetID()).thenReturn("subnetID");
- when(neutronLBPoolMember.getPoolMemberID()).thenReturn("pool_memberID");
+ when(neutronLBPoolMember.getID()).thenReturn("pool_memberID");
when(neutronLBPoolMember.getPoolMemberAddress()).thenReturn("pool_member_address");
when(neutronLBPoolMember.getPoolMemberProtoPort()).thenReturn(1);
members.add(neutronLBPoolMember);
NeutronLoadBalancerPoolMember neutronLBPoolMember = mock(NeutronLoadBalancerPoolMember.class);
when(neutronLBPoolMember.getPoolMemberAdminStateIsUp()).thenReturn(true);
when(neutronLBPoolMember.getPoolMemberSubnetID()).thenReturn("subnetID");
- when(neutronLBPoolMember.getPoolMemberID()).thenReturn("pool_memberID");
+ when(neutronLBPoolMember.getID()).thenReturn("pool_memberID");
when(neutronLBPoolMember.getPoolMemberAddress()).thenReturn("pool_member_address");
when(neutronLBPoolMember.getPoolMemberProtoPort()).thenReturn(1);
members.add(neutronLBPoolMember);
@Before
public void setUp() {
neutronLBMember = mock(NeutronLoadBalancerPoolMember.class);
- when(neutronLBMember.getPoolMemberID()).thenReturn("pool_memberID");
+ when(neutronLBMember.getID()).thenReturn("pool_memberID");
when(neutronLBMember.getPoolMemberAddress()).thenReturn("pool_member_address");
when(neutronLBMember.getPoolMemberSubnetID()).thenReturn("pool_member_subnetID");
when(neutronLBMember.getPoolMemberProtoPort()).thenReturn(1);
NeutronLoadBalancerPoolMember neutronLBPoolMember = mock(NeutronLoadBalancerPoolMember.class);
when(neutronLBPoolMember.getPoolMemberAdminStateIsUp()).thenReturn(true);
when(neutronLBPoolMember.getPoolMemberSubnetID()).thenReturn("subnetID");
- when(neutronLBPoolMember.getPoolMemberID()).thenReturn("pool_memberID1");
+ when(neutronLBPoolMember.getID()).thenReturn("pool_memberID1");
when(neutronLBPoolMember.getPoolMemberProtoPort()).thenReturn(1);
members.add(neutronLBPoolMember);
NeutronFloatingIP neutronFloatingIP = mock(NeutronFloatingIP.class);
when(neutronFloatingIP.getFixedIPAddress()).thenReturn(FIXED_IP_ADDRESS);
when(neutronFloatingIP.getFloatingIPAddress()).thenReturn(FLOATING_IP_ADDRESS);
- when(neutronFloatingIP.getFloatingIPUUID()).thenReturn(UUID);
+ when(neutronFloatingIP.getID()).thenReturn(UUID);
// Suppress the called to these functions
MemberModifier.suppress(MemberMatcher.method(NeutronL3Adapter.class, "programFlowsForFloatingIPArpAdd", NeutronFloatingIP.class));