NETVIRT-1630 migrate to md-sal APIs
[netvirt.git] / natservice / impl / src / main / java / org / opendaylight / netvirt / natservice / internal / SubnetGwMacChangeListener.java
1 /*
2  * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.netvirt.natservice.internal;
10
11 import java.net.Inet6Address;
12 import java.net.InetAddress;
13 import java.net.UnknownHostException;
14 import javax.annotation.PreDestroy;
15 import javax.inject.Inject;
16 import javax.inject.Singleton;
17 import org.opendaylight.infrautils.utils.concurrent.Executors;
18 import org.opendaylight.mdsal.binding.api.DataBroker;
19 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
20 import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager;
21 import org.opendaylight.serviceutils.tools.listener.AbstractAsyncDataTreeChangeListener;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
27 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 @Singleton
32 public class SubnetGwMacChangeListener extends AbstractAsyncDataTreeChangeListener<LearntVpnVipToPort> {
33     private static final Logger LOG = LoggerFactory.getLogger(SubnetGwMacChangeListener.class);
34
35     private final DataBroker broker;
36     private final INeutronVpnManager nvpnManager;
37     private final ExternalNetworkGroupInstaller extNetworkInstaller;
38
39     @Inject
40     public SubnetGwMacChangeListener(final DataBroker broker, final INeutronVpnManager nvpnManager,
41                                      final ExternalNetworkGroupInstaller extNetworkInstaller) {
42         super(broker, LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(LearntVpnVipToPortData.class)
43                 .child(LearntVpnVipToPort.class),
44                 Executors.newListeningSingleThreadExecutor("SubnetGwMacChangeListener", LOG));
45         this.broker = broker;
46         this.nvpnManager = nvpnManager;
47         this.extNetworkInstaller = extNetworkInstaller;
48     }
49
50     public void init() {
51         LOG.info("{} init", getClass().getSimpleName());
52     }
53
54     @Override
55     @PreDestroy
56     public void close() {
57         super.close();
58         Executors.shutdownAndAwaitTermination(getExecutorService());
59     }
60
61     @Override
62     public void remove(InstanceIdentifier<LearntVpnVipToPort> key, LearntVpnVipToPort learntVpnVipToPort) {
63     }
64
65     @Override
66     public void update(InstanceIdentifier<LearntVpnVipToPort> key, LearntVpnVipToPort origLearntVpnVipToPort,
67                           LearntVpnVipToPort updatedLearntVpnVipToPort) {
68         handleSubnetGwIpChange(updatedLearntVpnVipToPort);
69     }
70
71     @Override
72     public void add(InstanceIdentifier<LearntVpnVipToPort> key, LearntVpnVipToPort learntVpnVipToPort) {
73         handleSubnetGwIpChange(learntVpnVipToPort);
74     }
75
76     private void handleSubnetGwIpChange(LearntVpnVipToPort learntVpnVipToPort) {
77         String macAddress = learntVpnVipToPort.getMacAddress();
78         if (macAddress == null) {
79             LOG.error("handleSubnetGwIpChange : Mac address is null for LearntVpnVipToPort for vpn {} prefix {}",
80                 learntVpnVipToPort.getVpnName(), learntVpnVipToPort.getPortFixedip());
81             return;
82         }
83
84         String fixedIp = learntVpnVipToPort.getPortFixedip();
85         if (fixedIp == null) {
86             LOG.error("handleSubnetGwIpChange : Fixed ip is null for LearntVpnVipToPort for vpn {}",
87                 learntVpnVipToPort.getVpnName());
88             return;
89         }
90
91         try {
92             InetAddress address = InetAddress.getByName(fixedIp);
93             if (address instanceof Inet6Address) {
94                 // TODO: Revisit when IPv6 North-South communication support is added.
95                 LOG.debug("handleSubnetGwIpChange : Skipping ipv6 address {}.", address);
96                 return;
97             }
98         } catch (UnknownHostException e) {
99             LOG.warn("handleSubnetGwIpChange : Invalid ip address {}", fixedIp, e);
100             return;
101         }
102
103         for (Uuid subnetId : nvpnManager.getSubnetIdsForGatewayIp(new IpAddress(new Ipv4Address(fixedIp)))) {
104             LOG.trace("handleSubnetGwIpChange : Updating MAC resolution on vpn {} for GW ip {} to {}",
105                     learntVpnVipToPort.getVpnName(), fixedIp, macAddress);
106             extNetworkInstaller.installExtNetGroupEntries(subnetId, macAddress);
107         }
108     }
109 }