import com.google.common.util.concurrent.JdkFutureAdapters;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
-import java.math.BigInteger;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
-import javax.annotation.Nullable;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Singleton;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.genius.arputil.api.ArpConstants;
+import org.opendaylight.genius.mdsalutil.NWUtil;
import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.netvirt.elanmanager.api.IElanService;
import org.opendaylight.netvirt.vpnmanager.api.ICentralizedSwitchProvider;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.SendArpRequestInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.interfaces.InterfaceAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.interfaces.InterfaceAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.ipv6.nd.util.rev170210.Ipv6NdUtilService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.ipv6.nd.util.rev170210.SendNeighborSolicitationInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.ipv6.nd.util.rev170210.SendNeighborSolicitationInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.ipv6.nd.util.rev170210.SendNeighborSolicitationOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router.ExternalGatewayInfo;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIpsKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.Uint64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger LOG = LoggerFactory.getLogger(NeutronSubnetGwMacResolver.class);
private static final long L3_INSTALL_DELAY_MILLIS = 5000;
- private final DataBroker broker;
private final OdlArputilService arpUtilService;
private final IElanService elanService;
private final ICentralizedSwitchProvider cswitchProvider;
private final NeutronvpnUtils neutronvpnUtils;
private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(
new ThreadFactoryBuilder().setNameFormat("Gw-Mac-Res").build());
+ private final Ipv6NdUtilService ipv6NdUtilService;
@Inject
- public NeutronSubnetGwMacResolver(final DataBroker broker,
- final OdlArputilService arputilService, final IElanService elanService,
- final ICentralizedSwitchProvider cswitchProvider, final NeutronvpnUtils neutronvpnUtils) {
- this.broker = broker;
+ public NeutronSubnetGwMacResolver(final OdlArputilService arputilService, final IElanService elanService,
+ final ICentralizedSwitchProvider cswitchProvider, final NeutronvpnUtils neutronvpnUtils,
+ final Ipv6NdUtilService ipv6NdUtilService) {
this.arpUtilService = arputilService;
this.elanService = elanService;
this.cswitchProvider = cswitchProvider;
this.neutronvpnUtils = neutronvpnUtils;
+ this.ipv6NdUtilService = ipv6NdUtilService;
}
// TODO Clean up the exception handling
return;
}
- List<FixedIps> fixedIps = extPort.getFixedIps();
- if (fixedIps == null || fixedIps.isEmpty()) {
+ Map<FixedIpsKey, FixedIps> keyFixedIpsMap = extPort.getFixedIps();
+ if (keyFixedIpsMap == null || keyFixedIpsMap.isEmpty()) {
LOG.trace("External GW port {} for router {} has no fixed IPs", extPort.getUuid().getValue(),
router.getUuid().getValue());
return;
return;
}
- for (FixedIps fixIp : fixedIps) {
+ for (FixedIps fixIp : keyFixedIpsMap.values()) {
Uuid subnetId = fixIp.getSubnetId();
IpAddress srcIpAddress = fixIp.getIpAddress();
IpAddress dstIpAddress = getExternalGwIpAddress(subnetId);
- sendArpRequest(srcIpAddress, dstIpAddress, macAddress, extInterface);
+ String srcIpAddressString = srcIpAddress.stringValue();
+ String dstIpAddressString = dstIpAddress.stringValue();
+ if (NWUtil.isIpv4Address(srcIpAddressString)) {
+ sendArpRequest(srcIpAddress, dstIpAddress, macAddress, extInterface);
+ } else {
+ sendNeighborSolication(new Ipv6Address(srcIpAddressString),macAddress,
+ new Ipv6Address(dstIpAddressString), extInterface);
+ }
}
}
}
}
+ private void sendNeighborSolication(Ipv6Address srcIpv6Address,
+ MacAddress srcMac, Ipv6Address dstIpv6Address, String interfaceName) {
+ List<org.opendaylight.yang.gen.v1.urn.opendaylight.genius.ipv6
+ .nd.util.rev170210.interfaces.InterfaceAddress> interfaceAddresses = new ArrayList<>();
+ interfaceAddresses.add(new org.opendaylight.yang.gen.v1.urn.opendaylight.genius.ipv6
+ .nd.util.rev170210.interfaces.InterfaceAddressBuilder()
+ .setInterface(interfaceName)
+ .setSrcIpAddress(srcIpv6Address)
+ .setSrcMacAddress(new PhysAddress(srcMac.getValue())).build());
+ SendNeighborSolicitationInput input = new SendNeighborSolicitationInputBuilder()
+ .setInterfaceAddress(interfaceAddresses).setTargetIpAddress(dstIpv6Address)
+ .build();
+ try {
+ Future<RpcResult<SendNeighborSolicitationOutput>> result = ipv6NdUtilService
+ .sendNeighborSolicitation(input);
+ RpcResult<SendNeighborSolicitationOutput> rpcResult = result.get();
+ if (!rpcResult.isSuccessful()) {
+ LOG.error("sendNeighborSolicitationToOfGroup: RPC Call failed for input={} and Errors={}", input,
+ rpcResult.getErrors());
+ }
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Failed to send NS packet to ELAN group, input={}", input, e);
+ }
+ }
+
@Nullable
private Port getRouterExtGatewayPort(Router router) {
if (router == null) {
return null;
}
- BigInteger primarySwitch = cswitchProvider.getPrimarySwitchForRouter(routerName);
- if (primarySwitch == null || BigInteger.ZERO.equals(primarySwitch)) {
+ Uint64 primarySwitch = cswitchProvider.getPrimarySwitchForRouter(routerName);
+ if (primarySwitch == null || Uint64.ZERO.equals(primarySwitch)) {
LOG.warn("Primary switch has not been allocated for router {}", routerName);
return null;
}