Remove redundant names in paths
[netvirt.git] / elanmanager / impl / src / main / java / org / opendaylight / netvirt / elan / evpn / utils / ElanEvpnFlowUtils.java
1 /*
2  * Copyright © 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.elan.evpn.utils;
10
11 import com.google.common.util.concurrent.ListenableFuture;
12 import java.math.BigInteger;
13 import java.util.ArrayList;
14 import java.util.Collections;
15 import java.util.List;
16 import javax.inject.Inject;
17 import javax.inject.Singleton;
18 import org.opendaylight.genius.mdsalutil.MDSALUtil;
19 import org.opendaylight.genius.mdsalutil.MatchInfo;
20 import org.opendaylight.genius.mdsalutil.NwConstants;
21 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
22 import org.opendaylight.netvirt.elan.utils.ElanConstants;
23 import org.opendaylight.netvirt.elan.utils.ElanEtreeUtils;
24 import org.opendaylight.netvirt.elan.utils.ElanItmUtils;
25 import org.opendaylight.netvirt.elan.utils.ElanUtils;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeLeafTagName;
32
33
34 @Singleton
35 public class ElanEvpnFlowUtils {
36     private final IMdsalApiManager mdsalManager;
37     private final ElanItmUtils elanItmUtils;
38     private final ElanEtreeUtils elanEtreeUtils;
39
40     @Inject
41     public ElanEvpnFlowUtils(final IMdsalApiManager mdsalManager, final ElanItmUtils elanItmUtils,
42             final ElanEtreeUtils elanEtreeUtils) {
43         this.mdsalManager = mdsalManager;
44         this.elanItmUtils = elanItmUtils;
45         this.elanEtreeUtils = elanEtreeUtils;
46     }
47
48     public Flow evpnBuildDmacFlowForExternalRemoteMac(EvpnDmacFlow evpnDmacFlow) {
49         List<MatchInfo> mkMatches = ElanUtils.buildMatchesForElanTagShFlagAndDstMac(evpnDmacFlow.getElanTag(), false,
50                 evpnDmacFlow.getDstMacAddress());
51         List<Instruction> mkInstructions = new ArrayList<>();
52         List<Action> actions = elanItmUtils.getExternalTunnelItmEgressAction(evpnDmacFlow.getDpId(),
53                 evpnDmacFlow.getNexthopIP(), evpnDmacFlow.getVni());
54         mkInstructions.add(MDSALUtil.buildApplyActionsInstruction(actions));
55         Flow flow = MDSALUtil.buildFlowNew(NwConstants.ELAN_DMAC_TABLE,
56                 ElanUtils.getKnownDynamicmacFlowRef(NwConstants.ELAN_DMAC_TABLE, evpnDmacFlow.getDpId(),
57                         evpnDmacFlow.getNexthopIP(), evpnDmacFlow.getDstMacAddress(), evpnDmacFlow.getElanTag(), false),
58                 20, evpnDmacFlow.getElanName(), 0, 0,
59                 ElanConstants.COOKIE_ELAN_KNOWN_DMAC.add(BigInteger.valueOf(evpnDmacFlow.getElanTag())), mkMatches,
60                 mkInstructions);
61
62         return flow;
63     }
64
65     public List<ListenableFuture<Void>> evpnDeleteDmacFlowsToExternalMac(EvpnDmacFlow evpnDmacFlow) {
66         List<ListenableFuture<Void>> futures = new ArrayList<>();
67         synchronized (ElanUtils.getElanMacDPNKey(evpnDmacFlow.getElanTag(), evpnDmacFlow.getDstMacAddress(),
68                 evpnDmacFlow.getDpId())) {
69             futures.addAll(
70                     evpnRemoveFlowThatSendsThePacketOnAnExternalTunnel(evpnDmacFlow.getElanTag(), evpnDmacFlow.dpId,
71                             evpnDmacFlow.getNexthopIP(), evpnDmacFlow.getDstMacAddress()));
72             futures.addAll(evpnDeleteEtreeDmacFlowsToExternalMac(evpnDmacFlow.getElanTag(), evpnDmacFlow.getDpId(),
73                     evpnDmacFlow.getNexthopIP(), evpnDmacFlow.getDstMacAddress()));
74         }
75         return futures;
76     }
77
78     private List<ListenableFuture<Void>> evpnDeleteEtreeDmacFlowsToExternalMac(long elanTag, BigInteger dpId,
79             String nexthopIp, String macToRemove) {
80         List<ListenableFuture<Void>> futures = new ArrayList<>();
81         EtreeLeafTagName etreeLeafTag = elanEtreeUtils.getEtreeLeafTagByElanTag(elanTag);
82         if (etreeLeafTag != null) {
83             futures.addAll(
84                     evpnRemoveFlowThatSendsThePacketOnAnExternalTunnel(etreeLeafTag.getEtreeLeafTag().getValue(), dpId,
85                             nexthopIp, macToRemove));
86             futures.addAll(
87                     evpnRemoveTheDropFlow(etreeLeafTag.getEtreeLeafTag().getValue(), dpId, nexthopIp, macToRemove));
88         }
89         return futures;
90     }
91
92     static String evpnGetKnownDynamicmacFlowRef(short elanDmacTable, BigInteger dpId, String nexthopIp,
93                                                 String dstMacAddress, long elanTag, boolean shFlag) {
94         return String.valueOf(elanDmacTable) + elanTag + dpId + nexthopIp + dstMacAddress + shFlag;
95     }
96
97     private List<ListenableFuture<Void>> evpnRemoveTheDropFlow(long elanTag, BigInteger dpId, String nexthopIp,
98             String macToRemove) {
99         String flowId = ElanEvpnFlowUtils.evpnGetKnownDynamicmacFlowRef(NwConstants.ELAN_DMAC_TABLE, dpId, nexthopIp,
100                 macToRemove, elanTag, true);
101         Flow flowToRemove = new FlowBuilder().setId(new FlowId(flowId)).setTableId(NwConstants.ELAN_DMAC_TABLE).build();
102         return Collections.singletonList(mdsalManager.removeFlow(dpId, flowToRemove));
103     }
104
105     private List<ListenableFuture<Void>> evpnRemoveFlowThatSendsThePacketOnAnExternalTunnel(long elanTag,
106             BigInteger dpId, String nexthopIp, String macToRemove) {
107         String flowId = ElanEvpnFlowUtils.evpnGetKnownDynamicmacFlowRef(NwConstants.ELAN_DMAC_TABLE, dpId, nexthopIp,
108                 macToRemove, elanTag, false);
109         Flow flowToRemove = new FlowBuilder().setId(new FlowId(flowId)).setTableId(NwConstants.ELAN_DMAC_TABLE).build();
110         return Collections.singletonList(mdsalManager.removeFlow(dpId, flowToRemove));
111     }
112
113     public static class EvpnDmacFlowBuilder {
114         private BigInteger dpId;
115         private String nexthopIP;
116         private long elanTag;
117         private Long vni;
118         private String dstMacAddress;
119         private String elanName;
120
121         public EvpnDmacFlowBuilder() {
122         }
123
124         public EvpnDmacFlowBuilder setDpId(BigInteger dpId) {
125             this.dpId = dpId;
126             return this;
127         }
128
129         public EvpnDmacFlowBuilder setNexthopIP(String nexthopIP) {
130             this.nexthopIP = nexthopIP;
131             return this;
132         }
133
134         public EvpnDmacFlowBuilder setElanTag(long elanTag) {
135             this.elanTag = elanTag;
136             return this;
137         }
138
139         public EvpnDmacFlowBuilder setVni(Long vni) {
140             this.vni = vni;
141             return this;
142         }
143
144         public EvpnDmacFlowBuilder setDstMacAddress(String dstMacAddress) {
145             this.dstMacAddress = dstMacAddress;
146             return this;
147         }
148
149         public EvpnDmacFlowBuilder setElanName(String elanName) {
150             this.elanName = elanName;
151             return this;
152         }
153
154         public EvpnDmacFlow build() {
155             return new EvpnDmacFlow(dpId, nexthopIP, elanTag, vni, dstMacAddress, elanName);
156         }
157     }
158
159     static class EvpnDmacFlow {
160         private BigInteger dpId;
161         private String nexthopIP;
162         private long elanTag;
163         private Long vni;
164         private String dstMacAddress;
165         private String elanName;
166
167         EvpnDmacFlow(BigInteger dpId, String nexthopIP, long elanTag, Long vni, String dstMacAddress,
168                             String elanName) {
169             this.dpId = dpId;
170             this.nexthopIP = nexthopIP;
171             this.elanTag = elanTag;
172             this.vni = vni;
173             this.dstMacAddress = dstMacAddress;
174             this.elanName = elanName;
175         }
176
177         public BigInteger getDpId() {
178             return dpId;
179         }
180
181         public String getNexthopIP() {
182             return nexthopIP;
183         }
184
185         public long getElanTag() {
186             return elanTag;
187         }
188
189         public Long getVni() {
190             return vni;
191         }
192
193         public String getDstMacAddress() {
194             return dstMacAddress;
195         }
196
197         public String getElanName() {
198             return elanName;
199         }
200     }
201 }