2 * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.netvirt.dhcpservice.jobs;
10 import com.google.common.util.concurrent.ListenableFuture;
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.List;
15 import java.util.concurrent.Callable;
16 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
17 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
18 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
19 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
20 import org.opendaylight.genius.mdsalutil.NwConstants;
21 import org.opendaylight.netvirt.dhcpservice.DhcpExternalTunnelManager;
22 import org.opendaylight.netvirt.dhcpservice.DhcpManager;
23 import org.opendaylight.netvirt.dhcpservice.DhcpServiceUtils;
24 import org.opendaylight.netvirt.dhcpservice.api.DhcpMConstants;
25 import org.opendaylight.netvirt.elan.arp.responder.ArpResponderInput.ArpReponderInputBuilder;
26 import org.opendaylight.netvirt.elan.arp.responder.ArpResponderUtil;
27 import org.opendaylight.netvirt.elanmanager.api.IElanService;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.dhcpservice.api.rev150710.subnet.dhcp.port.data.SubnetToDhcpPort;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
38 public class DhcpInterfaceAddJob implements Callable<List<ListenableFuture<Void>>> {
40 private static final Logger LOG = LoggerFactory.getLogger(DhcpInterfaceAddJob.class);
42 private final DhcpManager dhcpManager;
43 private final DhcpExternalTunnelManager dhcpExternalTunnelManager;
44 private final DataBroker dataBroker;
45 private final ManagedNewTransactionRunner txRunner;
46 private final Interface interfaceAdd;
47 private final BigInteger dpnId;
48 private final IInterfaceManager interfaceManager;
49 private final IElanService elanService;
50 private final ItmRpcService itmRpcService;
52 public DhcpInterfaceAddJob(DhcpManager dhcpManager, DhcpExternalTunnelManager dhcpExternalTunnelManager,
53 DataBroker dataBroker, Interface interfaceAdd, BigInteger dpnId,
54 IInterfaceManager interfaceManager, IElanService elanService,
55 ItmRpcService itmRpcService) {
56 this.dhcpManager = dhcpManager;
57 this.dhcpExternalTunnelManager = dhcpExternalTunnelManager;
58 this.dataBroker = dataBroker;
59 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
60 this.interfaceAdd = interfaceAdd;
62 this.interfaceManager = interfaceManager;
63 this.elanService = elanService;
64 this.itmRpcService = itmRpcService;
68 public List<ListenableFuture<Void>> call() {
69 String interfaceName = interfaceAdd.getName();
70 LOG.trace("Received add DCN for interface {}, dpid {}", interfaceName, dpnId);
71 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
72 interfaceManager.getInterfaceInfoFromConfigDataStore(interfaceName);
74 IfTunnel tunnelInterface = iface.augmentation(IfTunnel.class);
75 if (tunnelInterface != null && !tunnelInterface.isInternal()) {
76 IpAddress tunnelIp = tunnelInterface.getTunnelDestination();
77 List<BigInteger> dpns = DhcpServiceUtils.getListOfDpns(dataBroker);
78 if (dpns.contains(dpnId)) {
79 return dhcpExternalTunnelManager.handleTunnelStateUp(tunnelIp, dpnId);
81 return Collections.emptyList();
84 if (!dpnId.equals(DhcpMConstants.INVALID_DPID)) {
85 Port port = dhcpManager.getNeutronPort(interfaceName);
86 Subnet subnet = dhcpManager.getNeutronSubnet(port);
87 if (null == subnet || !subnet.isEnableDhcp()) {
88 LOG.debug("DHCP is not enabled for port {}", port.getName());
89 return Collections.emptyList();
91 List<ListenableFuture<Void>> futures = new ArrayList<>();
92 // Support for VM migration use cases.
93 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
94 tx -> DhcpServiceUtils.bindDhcpService(interfaceName, NwConstants.DHCP_TABLE, tx)));
95 LOG.info("DhcpInterfaceEventListener add isEnableDhcp:{}", subnet.isEnableDhcp());
96 futures.addAll(installDhcpEntries(interfaceAdd.getName(), dpnId));
97 LOG.trace("Checking ElanDpnInterface {} for dpn {} ", interfaceName, dpnId);
98 String subnetId = subnet.getUuid().getValue();
99 java.util.Optional<SubnetToDhcpPort> subnetToDhcp = DhcpServiceUtils
100 .getSubnetDhcpPortData(dataBroker, subnetId);
101 if (!subnetToDhcp.isPresent()) {
102 return Collections.emptyList();
104 LOG.trace("Installing the Arp responder for interface {} with DHCP MAC {} & IP {}.", interfaceName,
105 subnetToDhcp.get().getPortMacaddress(), subnetToDhcp.get().getPortFixedip());
106 ArpReponderInputBuilder builder = new ArpReponderInputBuilder();
107 builder.setDpId(dpnId).setInterfaceName(interfaceName).setSpa(subnetToDhcp.get().getPortFixedip())
108 .setSha(subnetToDhcp.get().getPortMacaddress()).setLportTag(interfaceAdd.getIfIndex());
109 builder.setInstructions(ArpResponderUtil.getInterfaceInstructions(interfaceManager, interfaceName,
110 subnetToDhcp.get().getPortFixedip(), subnetToDhcp.get().getPortMacaddress(), itmRpcService));
111 elanService.addArpResponderFlow(builder.buildForInstallFlow());
114 return Collections.emptyList();
117 private List<ListenableFuture<Void>> installDhcpEntries(String interfaceName, BigInteger dpId) {
118 return Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(
119 tx -> dhcpManager.installDhcpEntries(dpId,
120 DhcpServiceUtils.getAndUpdateVmMacAddress(tx, interfaceName, dhcpManager), tx)));