2 * Copyright (c) 2015 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.vpnmanager;
10 import java.math.BigInteger;
11 import java.net.InetAddress;
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
17 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
18 import org.opendaylight.genius.mdsalutil.NwConstants;
19 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
20 import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.AlivenessMonitorService;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.EtherTypes;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
28 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
32 import com.google.common.base.Optional;
34 public class ArpMonitoringHandler extends AsyncDataTreeChangeListenerBase<VpnPortipToPort, ArpMonitoringHandler> {
35 private static final Logger LOG = LoggerFactory.getLogger(ArpMonitoringHandler.class);
36 private final DataBroker dataBroker;
37 private final OdlInterfaceRpcService interfaceRpc;
38 private final IMdsalApiManager mdsalManager;
39 private final AlivenessMonitorService alivenessManager;
40 private final INeutronVpnManager neutronVpnService;
41 private Long arpMonitorProfileId = 0L;
43 public ArpMonitoringHandler(final DataBroker dataBroker, final OdlInterfaceRpcService interfaceRpc,
44 IMdsalApiManager mdsalManager, AlivenessMonitorService alivenessManager, INeutronVpnManager neutronVpnService) {
45 super(VpnPortipToPort.class, ArpMonitoringHandler.class);
46 this.dataBroker = dataBroker;
47 this.interfaceRpc = interfaceRpc;
48 this.mdsalManager = mdsalManager;
49 this.alivenessManager = alivenessManager;
50 this.neutronVpnService = neutronVpnService;
54 Optional <Long> profileIdOptional = AlivenessMonitorUtils.allocateProfile(alivenessManager,
55 ArpConstants.FAILURE_THRESHOLD, ArpConstants.ARP_CACHE_TIMEOUT_MILLIS, ArpConstants.MONITORING_WINDOW,
57 if(profileIdOptional.isPresent()) {
58 arpMonitorProfileId = profileIdOptional.get();
60 LOG.error("Error while allocating Profile Id", profileIdOptional);
62 registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
66 protected InstanceIdentifier<VpnPortipToPort> getWildCardPath() {
67 return InstanceIdentifier.create(NeutronVpnPortipPortData.class).child(VpnPortipToPort.class);
70 public static InstanceIdentifier<VpnPortipToPort> getVpnPortipToPortInstanceOpDataIdentifier(String ip, String vpnName) {
71 return InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
72 .child(VpnPortipToPort.class, new VpnPortipToPortKey(ip, vpnName)).build();
76 protected ArpMonitoringHandler getDataTreeChangeListener() {
81 protected void update(InstanceIdentifier<VpnPortipToPort> id, VpnPortipToPort value,
82 VpnPortipToPort dataObjectModificationAfter) {
84 Boolean islearnt = value.isLearnt();
85 if(value.getMacAddress() == null || dataObjectModificationAfter.getMacAddress() == null) {
86 LOG.warn("The Macaddress received is null for VpnPortipToPort {}, ignoring the DTCN", dataObjectModificationAfter);
91 add(id, dataObjectModificationAfter);
93 } catch (Exception e) {
94 LOG.error("Error in handling update to vpnPortIpToPort for vpnName {} and IP Address {}", value.getVpnName() , value.getPortFixedip());
100 protected void add(InstanceIdentifier<VpnPortipToPort> identifier, VpnPortipToPort value) {
102 InetAddress srcInetAddr = InetAddress.getByName(value.getPortFixedip());
103 String macAddress = value.getMacAddress();
104 if(value.getMacAddress() == null) {
105 LOG.warn("The Macaddress received is null for VpnPortipToPort {}, ignoring the DTCN", value);
108 MacAddress srcMacAddress = MacAddress.getDefaultInstance(value.getMacAddress());
109 String vpnName = value.getVpnName();
110 String interfaceName = value.getPortName();
111 Boolean islearnt = value.isLearnt();
113 MacEntry macEntry = new MacEntry(vpnName, srcMacAddress, srcInetAddr, interfaceName);
114 DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
115 coordinator.enqueueJob(buildJobKey(srcInetAddr.toString(), vpnName),
116 new ArpMonitorStartTask(macEntry, arpMonitorProfileId, dataBroker, alivenessManager,
117 interfaceRpc, neutronVpnService));
119 if (value.isSubnetIp()) {
120 WriteTransaction writeTx = dataBroker.newWriteOnlyTransaction();
121 VpnUtil.setupSubnetMacIntoVpnInstance(dataBroker, mdsalManager, vpnName,
122 macAddress, BigInteger.ZERO /* On all DPNs */, writeTx, NwConstants.ADD_FLOW);
125 } catch (Exception e) {
126 LOG.error("Error in deserializing packet {} with exception {}", value, e);
131 protected void remove(InstanceIdentifier<VpnPortipToPort> key, VpnPortipToPort value) {
133 InetAddress srcInetAddr = InetAddress.getByName(value.getPortFixedip());
134 String macAddress = value.getMacAddress();
135 if(value.getMacAddress() == null) {
136 LOG.warn("The Macaddress received is null for VpnPortipToPort {}, ignoring the DTCN", value);
139 MacAddress srcMacAddress = MacAddress.getDefaultInstance(value.getMacAddress());
140 String vpnName = value.getVpnName();
141 String interfaceName = value.getPortName();
142 Boolean islearnt = value.isLearnt();
144 MacEntry macEntry = new MacEntry(vpnName, srcMacAddress, srcInetAddr, interfaceName);
145 DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
146 coordinator.enqueueJob(buildJobKey(srcInetAddr.toString(), vpnName),
147 new ArpMonitorStopTask(macEntry, dataBroker, alivenessManager));
149 if (value.isSubnetIp()) {
150 WriteTransaction writeTx = dataBroker.newWriteOnlyTransaction();
151 VpnUtil.setupSubnetMacIntoVpnInstance(dataBroker, mdsalManager, vpnName,
152 macAddress, BigInteger.ZERO /* On all DPNs */, writeTx, NwConstants.DEL_FLOW);
155 } catch (Exception e) {
156 LOG.error("Error in deserializing packet {} with exception {}", value, e);
160 static String buildJobKey(String ip, String vpnName) {
161 return new StringBuilder(ArpConstants.ARPJOB).append(ip).append(vpnName).toString();