e0f3c7f71eeb7c859e17d9afd485315328eac530
[netvirt.git] /
1 /*
2  * Copyright (c) 2017 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.policyservice.listeners;
10
11 import java.math.BigInteger;
12
13 import javax.annotation.PostConstruct;
14 import javax.inject.Inject;
15 import javax.inject.Singleton;
16
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.policyservice.util.PolicyServiceUtil;
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.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepInfoAttributes;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelsState;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay.network.DpnToInterface;
27 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 /**
32  * Listen on operational {@link StateTunnelList} changes and update
33  * {@link DpnToInterface} accordingly for tunnel interfaces of type VxLAN.
34  *
35  */
36 @Singleton
37 public class TunnelStateChangeListener
38         extends AsyncDataTreeChangeListenerBase<StateTunnelList, TunnelStateChangeListener> {
39     private static final Logger LOG = LoggerFactory.getLogger(TunnelStateChangeListener.class);
40
41     private final DataBroker dataBroker;
42     private final PolicyServiceUtil policyServiceUtil;
43
44     @Inject
45     public TunnelStateChangeListener(DataBroker dataBroker, final PolicyServiceUtil policyServiceUtil) {
46         this.dataBroker = dataBroker;
47         this.policyServiceUtil = policyServiceUtil;
48     }
49
50     @Override
51     @PostConstruct
52     public void init() {
53         LOG.info("init");
54         registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
55     }
56
57     @Override
58     protected InstanceIdentifier<StateTunnelList> getWildCardPath() {
59         return InstanceIdentifier.create(TunnelsState.class).child(StateTunnelList.class);
60     }
61
62     @Override
63     protected TunnelStateChangeListener getDataTreeChangeListener() {
64         return this;
65     }
66
67     @Override
68     protected void remove(InstanceIdentifier<StateTunnelList> key, StateTunnelList tunnelState) {
69         LOG.debug("Tunnel state {} removed", tunnelState);
70         handleTunnelUpdate(tunnelState, false);
71     }
72
73     @Override
74     protected void update(InstanceIdentifier<StateTunnelList> key, StateTunnelList origTunnelState,
75             StateTunnelList updtedTunnelState) {
76     }
77
78     @Override
79     protected void add(InstanceIdentifier<StateTunnelList> key, StateTunnelList tunnelState) {
80         LOG.debug("Tunnel state {} added", tunnelState);
81         handleTunnelUpdate(tunnelState, true);
82     }
83
84     private void handleTunnelUpdate(StateTunnelList tunnelState, boolean isAdded) {
85         if (!isVxlanTunnel(tunnelState)) {
86             return;
87         }
88
89         BigInteger srcDpId = getTepDpnId(tunnelState.getSrcInfo());
90         BigInteger dstDpId = getTepDpnId(tunnelState.getDstInfo());
91         String tunnelInterfaceName = tunnelState.getTunnelInterfaceName();
92         if (BigInteger.ZERO.equals(srcDpId) || BigInteger.ZERO.equals(dstDpId)) {
93             LOG.warn("No valid DPN found for tunnel {}", tunnelInterfaceName);
94             return;
95         }
96
97         IpAddress tunnelIp = getTunnelIp(tunnelState);
98         if (tunnelIp == null) {
99             LOG.warn("No tunnel ip found for tunnel {} DPN {}", tunnelInterfaceName, srcDpId);
100             return;
101         }
102
103         String underlayNetwork = policyServiceUtil.getTunnelUnderlayNetwork(srcDpId, tunnelIp);
104         if (underlayNetwork == null) {
105             LOG.debug("No underlay networks defined for tunnel {} DPN {}", tunnelInterfaceName, srcDpId);
106             return;
107         }
108
109         LOG.info("Handle tunnel state update for interface {} on DPN {} underlay network", tunnelInterfaceName, srcDpId,
110                 underlayNetwork);
111         policyServiceUtil.updateTunnelInterfaceForUnderlayNetwork(underlayNetwork, srcDpId, dstDpId,
112                 tunnelInterfaceName, isAdded);
113     }
114
115     private static boolean isVxlanTunnel(StateTunnelList tunnelState) {
116         return tunnelState.getTransportType() != null
117                 && tunnelState.getTransportType().isAssignableFrom(TunnelTypeVxlan.class);
118     }
119
120     private static BigInteger getTepDpnId(TepInfoAttributes tepInfoAttributes) {
121         if (tepInfoAttributes != null && tepInfoAttributes.getTepDeviceId() != null) {
122             return new BigInteger(tepInfoAttributes.getTepDeviceId());
123         }
124
125         return BigInteger.ZERO;
126     }
127
128     private static IpAddress getTunnelIp(StateTunnelList tunnelState) {
129         return tunnelState.getSrcInfo() != null ? tunnelState.getSrcInfo().getTepIp() : null;
130     }
131 }