import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
-import javax.annotation.Nullable;
-
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import org.opendaylight.openflowplugin.api.OFConstants;
import org.opendaylight.ovsdb.openstack.netvirt.api.GatewayMacResolver;
+import org.opendaylight.ovsdb.openstack.netvirt.api.GatewayMacResolverListener;
import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface;
import org.opendaylight.ovsdb.openstack.netvirt.providers.NetvirtProvidersProvider;
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
implements ConfigInterface, GatewayMacResolver,PacketProcessingListener {
private static final Logger LOG = LoggerFactory.getLogger(GatewayMacResolverService.class);
- private static final short TABEL_FOR_ARP_FLOW = 0;
+ private static final short TABLE_FOR_ARP_FLOW = 0;
private static final String ARP_REPLY_TO_CONTROLLER_FLOW_NAME = "GatewayArpReplyRouter";
private static final int ARP_REPLY_TO_CONTROLLER_FLOW_PRIORITY = 10000;
private static final Instruction SEND_TO_CONTROLLER_INSTRUCTION;
private SalFlowService flowService;
private final AtomicLong flowCookie = new AtomicLong();
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;
+ new ConcurrentHashMap<>();
+ private static final int ARP_WATCH_BROTHERS = 10;
+ private static final int WAIT_CYCLES = 3;
+ private static final int PER_CYCLE_WAIT_DURATION = 1000;
+ private static 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();
}
LOG.debug("Refresh Gateway Mac for gateway {} using source ip {} and mac {} for ARP request",
- gatewayIp.getValue(),gatewayMetaData.getArpRequestSourceIp().getValue(),gatewayMetaData.getArpRequestMacAddress().getValue());
+ gatewayIp.getValue(),gatewayMetaData.getArpRequestSourceIp().getValue(),gatewayMetaData.getArpRequestSourceMacAddress().getValue());
- sendGatewayArpRequest(externalNetworkBridge,gatewayIp,gatewayMetaData.getArpRequestSourceIp(), gatewayMetaData.getArpRequestMacAddress());
+ sendGatewayArpRequest(externalNetworkBridge,gatewayIp,gatewayMetaData.getArpRequestSourceIp(), gatewayMetaData.getArpRequestSourceMacAddress());
}
}, 1, TimeUnit.SECONDS);
}
* @param sourceMacAddress Source Mac address for the ARP request packet
* @param periodicRefresh Enable/Disable periodic refresh of the Gateway Mac address
* NOTE:Periodic refresh is not supported yet.
- * @param gatewayIp Resolve MAC address of this Gateway Ip
* @return Future object
*/
@Override
- public ListenableFuture<MacAddress> resolveMacAddress( final Long externalNetworkBridgeDpid, final Ipv4Address gatewayIp,
- final Ipv4Address sourceIpAddress, final MacAddress sourceMacAddress, final Boolean periodicRefresh){
+ public ListenableFuture<MacAddress> resolveMacAddress(
+ final GatewayMacResolverListener gatewayMacResolverListener, final Long externalNetworkBridgeDpid,
+ final Ipv4Address gatewayIp, final Ipv4Address sourceIpAddress, final MacAddress sourceMacAddress,
+ final Boolean periodicRefresh){
Preconditions.checkNotNull(sourceIpAddress);
Preconditions.checkNotNull(sourceMacAddress);
Preconditions.checkNotNull(gatewayIp);
});
}
}else{
- gatewayToArpMetadataMap.put(gatewayIp,new ArpResolverMetadata(
+ gatewayToArpMetadataMap.put(gatewayIp,new ArpResolverMetadata(gatewayMacResolverListener,
externalNetworkBridgeDpid, gatewayIp,sourceIpAddress,sourceMacAddress,periodicRefresh));
}
}
LOG.debug("Flow to route ARP Reply to Controller installed successfully : {}", flowIid);
+ ArpResolverMetadata gatewayArpMetadata = gatewayToArpMetadataMap.get(gatewayIp);
+ if (gatewayArpMetadata == null) {
+ LOG.warn("No metadata found for gatewayIp: {}", gatewayIp);
+ return;
+ }
+
//cache metadata
- gatewayToArpMetadataMap.get(gatewayIp).setFlowToRemove(
- new RemoveFlowInputBuilder(arpReplyToControllerFlow).setNode(nodeRef).build());
+ gatewayArpMetadata.setFlowToRemove(new RemoveFlowInputBuilder(arpReplyToControllerFlow).setNode(nodeRef).build());
+
+ //get MAC DA for ARP packets
+ MacAddress arpRequestDestMacAddress = gatewayArpMetadata.getArpRequestDestMacAddress();
- //Broadcast ARP request packets
+ //Send ARP request packets
for (NodeConnector egressNc : externalNetworkBridge.getNodeConnector()) {
KeyedInstanceIdentifier<NodeConnector, NodeConnectorKey> egressNcIid = nodeIid.child(
NodeConnector.class, new NodeConnectorKey(egressNc.getId()));
ListenableFuture<RpcResult<Void>> futureSendArpResult = arpSender.sendArp(
- senderAddress, gatewayIp, egressNcIid);
+ senderAddress, gatewayIp, arpRequestDestMacAddress, egressNcIid);
Futures.addCallback(futureSendArpResult, logResult(gatewayIp, egressNcIid));
}
}
});
}
- private static @Nullable Ipv4Address getIPv4Addresses(IpAddress ipAddress) {
- if (ipAddress.getIpv4Address() == null) {
- return null;
- }
- return ipAddress.getIpv4Address();
- }
-
private Flow createArpReplyToControllerFlow(final ArpMessageAddress senderAddress, final Ipv4Address ipForRequestedMac) {
checkNotNull(senderAddress);
checkNotNull(ipForRequestedMac);
- FlowBuilder arpFlow = new FlowBuilder().setTableId(TABEL_FOR_ARP_FLOW)
+ FlowBuilder arpFlow = new FlowBuilder().setTableId(TABLE_FOR_ARP_FLOW)
.setFlowName(ARP_REPLY_TO_CONTROLLER_FLOW_NAME)
.setPriority(ARP_REPLY_TO_CONTROLLER_FLOW_PRIORITY)
.setBufferId(OFConstants.OFP_NO_BUFFER)
arpFlow.setMatch(match);
arpFlow.setInstructions(new InstructionsBuilder().setInstruction(
ImmutableList.of(SEND_TO_CONTROLLER_INSTRUCTION)).build());
- arpFlow.setId(createFlowId(senderAddress, ipForRequestedMac));
+ arpFlow.setId(createFlowId(ipForRequestedMac));
return arpFlow.build();
}
- private FlowId createFlowId(ArpMessageAddress senderAddress, Ipv4Address ipForRequestedMac) {
+ private FlowId createFlowId(Ipv4Address ipForRequestedMac) {
String flowId = ARP_REPLY_TO_CONTROLLER_FLOW_NAME + "|" + ipForRequestedMac.getValue();
return new FlowId(flowId);
}