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
9 package org.opendaylight.netvirt.dhcpservice;
11 import com.google.common.base.Optional;
12 import org.opendaylight.controller.md.sal.binding.api.ClusteredDataChangeListener;
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
15 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
16 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
18 import org.opendaylight.genius.datastoreutils.AsyncClusteredDataChangeListenerBase;
19 import org.opendaylight.genius.mdsalutil.MDSALUtil;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
34 import org.opendaylight.yangtools.yang.binding.DataObject;
35 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
39 import java.math.BigInteger;
40 import java.util.Iterator;
41 import java.util.List;
44 public class DhcpSubnetListener extends AsyncClusteredDataChangeListenerBase<Subnet, DhcpSubnetListener>
45 implements AutoCloseable {
46 private DataBroker dataBroker;
47 private DhcpManager dhcpManager;
48 private DhcpExternalTunnelManager dhcpExternalTunnelManager;
49 private static final Logger LOG = LoggerFactory.getLogger(DhcpSubnetListener.class);
51 public DhcpSubnetListener(final DhcpManager dhcpManager, final DhcpExternalTunnelManager
52 dhcpExternalTunnelManager, final DataBroker
54 super(Subnet.class, DhcpSubnetListener.class);
55 this.dhcpManager = dhcpManager;
56 this.dataBroker = broker;
57 this.dhcpExternalTunnelManager = dhcpExternalTunnelManager;
61 protected void add(InstanceIdentifier<Subnet> identifier, Subnet add) {
66 protected void remove(InstanceIdentifier<Subnet> identifier, Subnet del) {
71 public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent) {
72 super.onDataChanged(changeEvent);
76 protected InstanceIdentifier<Subnet> getWildCardPath() {
77 return InstanceIdentifier.create(Neutron.class).child(Subnets.class).child(Subnet.class);
81 protected AsyncDataBroker.DataChangeScope getDataChangeScope() {
82 return AsyncDataBroker.DataChangeScope.SUBTREE;
86 protected ClusteredDataChangeListener getDataChangeListener() {
87 return DhcpSubnetListener.this;
91 protected void update(InstanceIdentifier<Subnet> identifier, Subnet original, Subnet update) {
92 if (LOG.isTraceEnabled()) {
93 LOG.trace("DhcpSubnetListener Update : Original dhcpstatus: " + original.isEnableDhcp() + ", " +
94 "Updated dhcpstatus" + update.isEnableDhcp());
97 if (original.isEnableDhcp() != update.isEnableDhcp()) {
98 // write api to get port list
99 SubnetmapBuilder subnetmapBuilder = getSubnetMapBuilder(dataBroker, update.getUuid());
100 List<Uuid> portList = subnetmapBuilder.getPortList();
101 List<Uuid> directPortList = subnetmapBuilder.getDirectPortList();
103 if (update.isEnableDhcp()) {
104 if (null != portList) {
105 //Install Entries for neutron ports
106 installNeutronPortEntries(portList);
108 if (null != directPortList) {
109 //install Entries for direct ports
110 installDirectPortEntries(directPortList);
113 if (null != portList) {
114 //UnInstall Entries for neutron ports
115 uninstallNeutronPortEntries(portList);
117 if (null != directPortList) {
118 //Uninstall Entries for direct ports
119 uninstallDirectPortEntries(directPortList);
125 private void installNeutronPortEntries(List<Uuid> portList) {
126 if (LOG.isTraceEnabled()) {
127 LOG.trace("DhcpSubnetListener installNeutronPortEntries : portList: " + portList);
130 for (Iterator<Uuid> portIter = portList.iterator(); portIter.hasNext(); ) {
131 portIntf = portIter.next();
132 NodeConnectorId nodeConnectorId = getNodeConnectorIdForPortIntf(portIntf);
133 BigInteger dpId = BigInteger.valueOf(MDSALUtil.getDpnIdFromPortName(nodeConnectorId));
134 Port port = dhcpManager.getNeutronPort(portIntf.getValue());
135 String vmMacAddress = port.getMacAddress().getValue();
136 //check whether any changes have happened
137 if (LOG.isTraceEnabled()) {
138 LOG.trace("DhcpSubnetListener installNeutronPortEntries dpId: " + dpId + "vmMacAddress :" +
141 //install the entriesd
142 dhcpManager.installDhcpEntries(dpId, vmMacAddress);
146 private void uninstallNeutronPortEntries(List<Uuid> portList) {
147 if (LOG.isTraceEnabled()) {
148 LOG.trace("DhcpSubnetListener uninstallNeutronPortEntries : portList: " + portList);
151 for (Iterator<Uuid> portIter = portList.iterator(); portIter.hasNext(); ) {
152 portIntf = portIter.next();
153 NodeConnectorId nodeConnectorId = getNodeConnectorIdForPortIntf(portIntf);
154 BigInteger dpId = BigInteger.valueOf(MDSALUtil.getDpnIdFromPortName(nodeConnectorId));
155 Port port = dhcpManager.getNeutronPort(portIntf.getValue());
156 String vmMacAddress = port.getMacAddress().getValue();
157 //check whether any changes have happened
158 if (LOG.isTraceEnabled()) {
159 LOG.trace("DhcpSubnetListener uninstallNeutronPortEntries dpId: " + dpId + "vmMacAddress :" +
162 //install the entries
163 dhcpManager.unInstallDhcpEntries(dpId, vmMacAddress);
167 private void installDirectPortEntries(List<Uuid> directPortList) {
168 if (LOG.isTraceEnabled()) {
169 LOG.trace("DhcpSubnetListener installDirectPortEntries : directPortList: " + directPortList);
172 for (Iterator<Uuid> directPortIter = directPortList.iterator(); directPortIter.hasNext(); ) {
173 portIntf = directPortIter.next();
174 Port port = dhcpManager.getNeutronPort(portIntf.getValue());
175 String vmMacAddress = port.getMacAddress().getValue();
176 Uuid networkId = port.getNetworkId();
177 //install the entries on designated dpnId
178 List<BigInteger> listOfDpns = DhcpServiceUtils.getListOfDpns(dataBroker);
179 IpAddress tunnelIp = dhcpExternalTunnelManager.getTunnelIpBasedOnElan(networkId.getValue(), vmMacAddress);
180 if (null == tunnelIp) {
181 LOG.warn("DhcpSubnetListener installDirectPortEntries tunnelIP is null for port {}", portIntf);
184 BigInteger designatedDpnId = dhcpExternalTunnelManager.readDesignatedSwitchesForExternalTunnel
185 (tunnelIp, networkId.getValue());
186 if (LOG.isTraceEnabled()) {
187 LOG.trace("CR-DHCP DhcpSubnetListener update Install DIRECT vmMacAddress:" + vmMacAddress + " " +
188 " tunnelIp: " + tunnelIp + " designatedDpnId :" + designatedDpnId + " ListOf Dpn:" +
189 listOfDpns.toString());
191 dhcpExternalTunnelManager.installDhcpFlowsForVms(tunnelIp, networkId.getValue(), listOfDpns,
192 designatedDpnId, vmMacAddress);
197 private void uninstallDirectPortEntries(List<Uuid> directPortList) {
198 if (LOG.isTraceEnabled()) {
199 LOG.trace("DhcpSubnetListener uninstallDirectPortEntries : directPortList: " + directPortList);
202 for (Iterator<Uuid> directPortIter = directPortList.iterator(); directPortIter.hasNext(); ) {
203 portIntf = directPortIter.next();
204 Port port = dhcpManager.getNeutronPort(portIntf.getValue());
205 String vmMacAddress = port.getMacAddress().getValue();
206 Uuid networkId = port.getNetworkId();
207 List<BigInteger> listOfDpns = DhcpServiceUtils.getListOfDpns(dataBroker);
208 if (LOG.isTraceEnabled()) {
209 LOG.trace("DhcpSubnetListener uninstallDirectPortEntries vmMacAddress:" + vmMacAddress + " " +
210 "networkId: " + networkId + " ListOf Dpn:" + listOfDpns.toString());
212 dhcpExternalTunnelManager.unInstallDhcpFlowsForVms(networkId.getValue(), listOfDpns, vmMacAddress);
217 private NodeConnectorId getNodeConnectorIdForPortIntf(Uuid interfaceName) {
218 if (LOG.isTraceEnabled()) {
219 LOG.trace("DhcpSubnetListener getNodeConnectorIdForPortIntf interfaceName: " + interfaceName);
221 NodeConnectorId nodeConnectorId = null;
222 InstanceIdentifier.InstanceIdentifierBuilder<Interface> idBuilder =
223 InstanceIdentifier.builder(InterfacesState.class)
224 .child(Interface.class,
225 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
226 .rev140508.interfaces.state.InterfaceKey(interfaceName.getValue()));
228 InstanceIdentifier<Interface> ifStateId = idBuilder.build();
230 Optional<Interface> ifStateOptional = MDSALUtil.read(LogicalDatastoreType.OPERATIONAL, ifStateId, dataBroker);
231 Interface interfaceState = null;
232 if (ifStateOptional.isPresent()) {
233 interfaceState = ifStateOptional.get();
235 if (interfaceState != null) {
236 List<String> ofportIds = interfaceState.getLowerLayerIf();
237 nodeConnectorId = new NodeConnectorId(ofportIds.get(0));
239 if (LOG.isTraceEnabled()) {
240 LOG.trace("DhcpSubnetListener getNodeConnectorIdForPortIntf returned nodeConnectorId :" + nodeConnectorId
242 "for the interface :" + interfaceName);
244 return nodeConnectorId;
247 private SubnetmapBuilder getSubnetMapBuilder(DataBroker broker, Uuid subnetId){
248 SubnetmapBuilder builder = null ;
249 InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).
250 child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
252 ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
254 Optional<Subnetmap> sn ;
256 sn = tx.read(LogicalDatastoreType.CONFIGURATION, id).get();
257 } catch (Exception e) {
258 throw new RuntimeException(e);
261 if (sn.isPresent()) {
262 builder = new SubnetmapBuilder(sn.get());
264 builder = new SubnetmapBuilder().setKey(new SubnetmapKey(subnetId)).setId(subnetId);
266 } catch (Exception e) {
267 LOG.error("Updation of subnetMap failed for node: {}", subnetId.getValue());
273 public void close() throws Exception {