2 * Copyright © 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
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
9 package org.opendaylight.netvirt.elan.evpn.utils;
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;
35 public class ElanEvpnFlowUtils {
36 private final IMdsalApiManager mdsalManager;
37 private final ElanItmUtils elanItmUtils;
38 private final ElanEtreeUtils elanEtreeUtils;
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;
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,
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())) {
70 evpnRemoveFlowThatSendsThePacketOnAnExternalTunnel(evpnDmacFlow.getElanTag(), evpnDmacFlow.dpId,
71 evpnDmacFlow.getNexthopIP(), evpnDmacFlow.getDstMacAddress()));
72 futures.addAll(evpnDeleteEtreeDmacFlowsToExternalMac(evpnDmacFlow.getElanTag(), evpnDmacFlow.getDpId(),
73 evpnDmacFlow.getNexthopIP(), evpnDmacFlow.getDstMacAddress()));
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) {
84 evpnRemoveFlowThatSendsThePacketOnAnExternalTunnel(etreeLeafTag.getEtreeLeafTag().getValue(), dpId,
85 nexthopIp, macToRemove));
87 evpnRemoveTheDropFlow(etreeLeafTag.getEtreeLeafTag().getValue(), dpId, nexthopIp, macToRemove));
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;
97 private List<ListenableFuture<Void>> evpnRemoveTheDropFlow(long elanTag, BigInteger dpId, String nexthopIp,
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));
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));
113 public static class EvpnDmacFlowBuilder {
114 private BigInteger dpId;
115 private String nexthopIP;
116 private long elanTag;
118 private String dstMacAddress;
119 private String elanName;
121 public EvpnDmacFlowBuilder() {
124 public EvpnDmacFlowBuilder setDpId(BigInteger dpId) {
129 public EvpnDmacFlowBuilder setNexthopIP(String nexthopIP) {
130 this.nexthopIP = nexthopIP;
134 public EvpnDmacFlowBuilder setElanTag(long elanTag) {
135 this.elanTag = elanTag;
139 public EvpnDmacFlowBuilder setVni(Long vni) {
144 public EvpnDmacFlowBuilder setDstMacAddress(String dstMacAddress) {
145 this.dstMacAddress = dstMacAddress;
149 public EvpnDmacFlowBuilder setElanName(String elanName) {
150 this.elanName = elanName;
154 public EvpnDmacFlow build() {
155 return new EvpnDmacFlow(dpId, nexthopIP, elanTag, vni, dstMacAddress, elanName);
159 static class EvpnDmacFlow {
160 private BigInteger dpId;
161 private String nexthopIP;
162 private long elanTag;
164 private String dstMacAddress;
165 private String elanName;
167 EvpnDmacFlow(BigInteger dpId, String nexthopIP, long elanTag, Long vni, String dstMacAddress,
170 this.nexthopIP = nexthopIP;
171 this.elanTag = elanTag;
173 this.dstMacAddress = dstMacAddress;
174 this.elanName = elanName;
177 public BigInteger getDpId() {
181 public String getNexthopIP() {
185 public long getElanTag() {
189 public Long getVni() {
193 public String getDstMacAddress() {
194 return dstMacAddress;
197 public String getElanName() {