a197b618d97cc8f88175381a72c3c0cd4db0c749
[netvirt.git] / natservice / impl / src / main / java / org / opendaylight / netvirt / natservice / internal / EvpnNaptSwitchHA.java
1 /*
2  * Copyright (c) 2017 Ericsson India Global Services Pvt Ltd. 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.util.concurrent.ExecutionException;
12 import javax.inject.Inject;
13 import javax.inject.Singleton;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.genius.infra.Datastore.Configuration;
16 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
17 import org.opendaylight.genius.mdsalutil.FlowEntity;
18 import org.opendaylight.genius.mdsalutil.NwConstants;
19 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
21 import org.opendaylight.yangtools.yang.common.Uint32;
22 import org.opendaylight.yangtools.yang.common.Uint64;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 @Singleton
27 public class EvpnNaptSwitchHA {
28
29     private static final Logger LOG = LoggerFactory.getLogger(EvpnNaptSwitchHA.class);
30     private final DataBroker dataBroker;
31     private final IMdsalApiManager mdsalManager;
32     private final IdManagerService idManager;
33     private final EvpnSnatFlowProgrammer evpnSnatFlowProgrammer;
34     private final NatOverVxlanUtil natOverVxlanUtil;
35
36     @Inject
37     public EvpnNaptSwitchHA(final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
38                         final EvpnSnatFlowProgrammer evpnSnatFlowProgrammer,
39                         final IdManagerService idManager, final NatOverVxlanUtil natOverVxlanUtil) {
40         this.dataBroker = dataBroker;
41         this.mdsalManager = mdsalManager;
42         this.evpnSnatFlowProgrammer = evpnSnatFlowProgrammer;
43         this.idManager = idManager;
44         this.natOverVxlanUtil = natOverVxlanUtil;
45     }
46
47     public void evpnRemoveSnatFlowsInOldNaptSwitch(String routerName, Uint32 routerId, String vpnName,
48                                                    Uint64 naptSwitch, TypedReadWriteTransaction<Configuration> confTx)
49             throws ExecutionException, InterruptedException {
50         //Handling VXLAN Provider type flow removal from old NAPT switch
51         Uint32 vpnId = NatUtil.getNetworkVpnIdFromRouterId(dataBroker, routerId);
52         if (vpnId == NatConstants.INVALID_ID) {
53             LOG.error("evpnRemoveSnatFlowsInOldNaptSwitch : Unable to retrieved vpnId for routerId {}", routerId);
54             return;
55         }
56         String rd = NatUtil.getVpnRd(dataBroker, vpnName);
57         if (rd == null) {
58             LOG.error("evpnRemoveSnatFlowsInOldNaptSwitch : Could not retrieve RD value from VPN Name {} ", vpnName);
59             return;
60         }
61         Uint32 l3Vni = NatEvpnUtil.getL3Vni(dataBroker, rd);
62         if (l3Vni == NatConstants.DEFAULT_L3VNI_VALUE) {
63             LOG.debug("evpnRemoveSnatFlowsInOldNaptSwitch : L3VNI value is not configured in Internet VPN {} and RD {} "
64                     + "Carve-out L3VNI value from OpenDaylight VXLAN VNI Pool and continue to installing "
65                     + "NAT flows", vpnName, rd);
66             l3Vni = natOverVxlanUtil.getInternetVpnVni(vpnName, routerId);
67         }
68         String gwMacAddress = NatUtil.getExtGwMacAddFromRouterName(dataBroker, routerName);
69         if (gwMacAddress == null) {
70             LOG.error("evpnRemoveSnatFlowsInOldNaptSwitch : Unable to Get External Gateway MAC address for "
71                     + "External Router ID {} ", routerId);
72             return;
73         }
74         //Remove the L3_GW_MAC_TABLE which forwards the packet to Inbound NAPT Table (table19->44)
75         NatEvpnUtil.removeL3GwMacTableEntry(naptSwitch, vpnId, gwMacAddress, mdsalManager, confTx);
76
77         //Remove the PDNAT_TABLE which forwards the packet to Inbound NAPT Table (table25->44)
78         NatUtil.removePreDnatToSnatTableEntry(confTx, mdsalManager, naptSwitch);
79
80         //Remove the PSNAT_TABLE which forwards the packet to Outbound NAPT Table (table26->46)
81         String flowRef = getFlowRefSnat(naptSwitch, NwConstants.PSNAT_TABLE, routerName);
82         FlowEntity flowEntity = NatUtil.buildFlowEntity(naptSwitch, NwConstants.PSNAT_TABLE, flowRef);
83         LOG.info("evpnRemoveSnatFlowsInOldNaptSwitch: Remove the flow (table26->46) in table {} "
84                 + "for the old napt switch with the DPN ID {} and router ID {}",
85                 NwConstants.PSNAT_TABLE, naptSwitch, routerId);
86         mdsalManager.removeFlow(confTx, flowEntity);
87
88         //Remove the Terminating Service table entry which forwards the packet to Inbound NAPT Table (table36->44)
89         LOG.info("evpnRemoveSnatFlowsInOldNaptSwitch : Remove the flow (table36->44) in table {} "
90                 + "for the old napt switch with the DPN ID {} and router ID {}",
91                 NwConstants.INTERNAL_TUNNEL_TABLE, naptSwitch, routerId);
92         evpnSnatFlowProgrammer.removeTunnelTableEntry(naptSwitch, l3Vni, confTx);
93
94         //Remove the INTERNAL_TUNNEL_TABLE entry which forwards the packet to Outbound NAPT Table (table36->46)
95         Uint64 tunnelId = NatEvpnUtil.getTunnelIdForRouter(idManager, dataBroker, routerName, routerId);
96
97         String tsFlowRef = getFlowRefTs(naptSwitch, NwConstants.INTERNAL_TUNNEL_TABLE, tunnelId);
98         FlowEntity tsNatFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NwConstants.INTERNAL_TUNNEL_TABLE, tsFlowRef);
99         LOG.info("evpnRemoveSnatFlowsInOldNaptSwitch : Remove the flow in the {} for the active switch "
100                 + "with the DPN ID {} and router ID {}", NwConstants.INTERNAL_TUNNEL_TABLE, naptSwitch, routerId);
101         mdsalManager.removeFlow(confTx, tsNatFlowEntity);
102     }
103
104     private String getFlowRefTs(Uint64 dpnId, short tableId, Uint64 routerID) {
105         return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
106                 .FLOWID_SEPARATOR + routerID;
107     }
108
109     private String getFlowRefSnat(Uint64 dpnId, short tableId, String routerID) {
110         return NatConstants.SNAT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
111                 .FLOWID_SEPARATOR + routerID;
112     }
113 }