8c4435d3d444a164c10f07fe7f572113cf490c54
[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.PostConstruct;
15 import javax.inject.Inject;
16 import javax.inject.Singleton;
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
20 import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
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.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
26 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 @Singleton
31 public class SubnetGwMacChangeListener
32     extends AsyncDataTreeChangeListenerBase<LearntVpnVipToPort, SubnetGwMacChangeListener> {
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(LearntVpnVipToPort.class, SubnetGwMacChangeListener.class);
43         this.broker = broker;
44         this.nvpnManager = nvpnManager;
45         this.extNetworkInstaller = extNetworkInstaller;
46     }
47
48     @PostConstruct
49     public void init() {
50         registerListener(LogicalDatastoreType.OPERATIONAL, broker);
51     }
52
53     @Override
54     protected InstanceIdentifier<LearntVpnVipToPort> getWildCardPath() {
55         return InstanceIdentifier.builder(LearntVpnVipToPortData.class).child(LearntVpnVipToPort.class).build();
56     }
57
58     @Override
59     protected void remove(InstanceIdentifier<LearntVpnVipToPort> key, LearntVpnVipToPort learntVpnVipToPort) {
60     }
61
62     @Override
63     protected void update(InstanceIdentifier<LearntVpnVipToPort> key, LearntVpnVipToPort origLearntVpnVipToPort,
64                           LearntVpnVipToPort updatedLearntVpnVipToPort) {
65         handleSubnetGwIpChange(updatedLearntVpnVipToPort);
66     }
67
68     @Override
69     protected void add(InstanceIdentifier<LearntVpnVipToPort> key, LearntVpnVipToPort learntVpnVipToPort) {
70         handleSubnetGwIpChange(learntVpnVipToPort);
71     }
72
73     @Override
74     protected SubnetGwMacChangeListener getDataTreeChangeListener() {
75         return this;
76     }
77
78     private void handleSubnetGwIpChange(LearntVpnVipToPort learntVpnVipToPort) {
79         String macAddress = learntVpnVipToPort.getMacAddress();
80         if (macAddress == null) {
81             LOG.error("handleSubnetGwIpChange : Mac address is null for LearntVpnVipToPort for vpn {} prefix {}",
82                 learntVpnVipToPort.getVpnName(), learntVpnVipToPort.getPortFixedip());
83             return;
84         }
85
86         String fixedIp = learntVpnVipToPort.getPortFixedip();
87         if (fixedIp == null) {
88             LOG.error("handleSubnetGwIpChange : Fixed ip is null for LearntVpnVipToPort for vpn {}",
89                 learntVpnVipToPort.getVpnName());
90             return;
91         }
92
93         try {
94             InetAddress address = InetAddress.getByName(fixedIp);
95             if (address instanceof Inet6Address) {
96                 // TODO: Revisit when IPv6 North-South communication support is added.
97                 LOG.debug("handleSubnetGwIpChange : Skipping ipv6 address {}.", address);
98                 return;
99             }
100         } catch (UnknownHostException e) {
101             LOG.warn("handleSubnetGwIpChange : Invalid ip address {}", fixedIp, e);
102             return;
103         }
104
105         for (Uuid subnetId : nvpnManager.getSubnetIdsForGatewayIp(new IpAddress(new Ipv4Address(fixedIp)))) {
106             LOG.trace("handleSubnetGwIpChange : Updating MAC resolution on vpn {} for GW ip {} to {}",
107                     learntVpnVipToPort.getVpnName(), fixedIp, macAddress);
108             extNetworkInstaller.installExtNetGroupEntries(subnetId, macAddress);
109         }
110     }
111 }