2 * Copyright (c) 2016 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
8 package org.opendaylight.netvirt.vpnmanager.intervpnlink;
10 import com.google.common.base.Optional;
11 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
12 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
13 import org.opendaylight.genius.mdsalutil.*;
14 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
15 import org.opendaylight.genius.utils.ServiceIndex;
16 import org.opendaylight.netvirt.vpnmanager.VpnConstants;
17 import org.opendaylight.netvirt.vpnmanager.VpnUtil;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinkStates;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinks;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.InterVpnLinkState;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.InterVpnLinkStateBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.inter.vpn.link.state.FirstEndpointState;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.inter.vpn.link.state.SecondEndpointState;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLink;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLinkKey;
30 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
34 import java.math.BigInteger;
35 import java.util.ArrayList;
36 import java.util.Arrays;
37 import java.util.List;
40 * This class contains methods to be used as utilities related with inter-vpn-link.
43 public class InterVpnLinkUtil {
44 private static final Logger LOG = LoggerFactory.getLogger(InterVpnLinkUtil.class);
47 * Updates VpnToDpn map by adding a fake VpnInterface related to an
48 * InterVpnLink in the corresponding DPNs
50 * @param broker dataBroker service reference
51 * @param dpnList List of DPNs where the fake InterVpnLink interface must
53 * @param vpnUuid UUID of the VPN to which the fake interfaces belong
55 public static void updateVpnToDpnMap(DataBroker broker, List<BigInteger> dpnList, Uuid vpnUuid) {
56 String rd = VpnUtil.getVpnRd(broker, vpnUuid.getValue());
57 InstanceIdentifier<VpnInstanceOpDataEntry> id = VpnUtil.getVpnInstanceOpDataIdentifier(rd);
58 Optional<VpnInstanceOpDataEntry> vpnInstOpData = MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id);
59 if ( vpnInstOpData.isPresent() ) {
60 for (BigInteger dpnId : dpnList) {
61 String linkIfaceName = String.format("InterVpnLink.%s.%s", vpnUuid.getValue(), dpnId.toString());
62 VpnUtil.mergeDpnInVpnToDpnMap(broker, vpnInstOpData.get(), dpnId,
63 Arrays.asList(linkIfaceName));
70 * Retrieves the InterVpnLink object searching by its name
72 * @param broker dataBroker service reference
73 * @param vpnLinkName Name of the InterVpnLink
74 * @return the InterVpnLink or Optional.absent() if there is no
75 * InterVpnLink with the specified name
77 public static Optional<InterVpnLink> getInterVpnLinkByName(DataBroker broker, String vpnLinkName) {
78 InstanceIdentifier<InterVpnLink> interVpnLinksIid =
79 InstanceIdentifier.builder(InterVpnLinks.class)
80 .child(InterVpnLink.class, new InterVpnLinkKey(vpnLinkName)).build();
81 return VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, interVpnLinksIid);
85 * Updates inter-VPN link state
87 * @param broker dataBroker service reference
88 * @param vpnLinkName The name of the InterVpnLink
89 * @param state Sets the state of the InterVpnLink to Active or Error
90 * @param newFirstEndpointState Updates the lportTag and/or DPNs of the 1st
91 * endpoint of the InterVpnLink
92 * @param newSecondEndpointState Updates the lportTag and/or DPNs of the
93 * 2nd endpoint of the InterVpnLink
95 public static void updateInterVpnLinkState(DataBroker broker, String vpnLinkName, InterVpnLinkState.State state,
96 FirstEndpointState newFirstEndpointState,
97 SecondEndpointState newSecondEndpointState) {
98 InterVpnLinkState oldVpnLinkState = VpnUtil.getInterVpnLinkState(broker, vpnLinkName);
99 InterVpnLinkState newVpnLinkState =
100 new InterVpnLinkStateBuilder(oldVpnLinkState).setState(state)
101 .setFirstEndpointState(newFirstEndpointState)
102 .setSecondEndpointState(newSecondEndpointState).build();
103 VpnUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, VpnUtil.getInterVpnLinkStateIid(vpnLinkName),
108 * Installs a Flow in LPortDispatcher table that matches on SI=2 and
109 * the lportTag of one InterVpnLink's endpoint and sets the vrfTag of the
110 * other endpoint and sends to FIB table
112 * @param broker dataBroker service reference
113 * @param mdsalManager MDSAL API accessor
114 * @param interVpnLink Object that holds the needed information about both
115 * endpoints of the InterVpnLink.
116 * @param dpnList The list of DPNs where this flow must be installed
117 * @param vpnUuidOtherEndpoint UUID of the other endpoint of the
119 * @param lPortTagOfOtherEndpoint Dataplane identifier of the other
120 * endpoint of the InterVpnLink
122 public static void installLPortDispatcherTableFlow(DataBroker broker, IMdsalApiManager mdsalManager,
123 InterVpnLink interVpnLink, List<BigInteger> dpnList,
124 Uuid vpnUuidOtherEndpoint, Integer lPortTagOfOtherEndpoint) {
125 long vpnId = VpnUtil.getVpnId(broker, vpnUuidOtherEndpoint.getValue());
126 for ( BigInteger dpnId : dpnList ) {
127 // insert into LPortDispatcher table
128 Flow lPortDispatcherFlow = buildLPortDispatcherFlow(interVpnLink.getName(), vpnId, lPortTagOfOtherEndpoint);
129 mdsalManager.installFlow(dpnId, lPortDispatcherFlow);
134 * Builds a Flow to be installed into LPortDispatcher table, that matches on
135 * SI=2 + vpnLinkEndpointPseudoPortTag and sends to FIB
137 * @param interVpnLinkName The name of the InterVpnLink
138 * @param vpnId Dataplane identifier of the VPN, the Vrf Tag.
139 * @param lportTag DataPlane identifier of the LogicalPort.
140 * @return the Flow ready to be installed
142 public static Flow buildLPortDispatcherFlow(String interVpnLinkName, long vpnId, Integer lportTag) {
143 LOG.info("Inter-vpn-link : buildLPortDispatcherFlow. vpnId {} lportTag {} ", vpnId, lportTag);
144 List<MatchInfo> matches = Arrays.asList(new MatchInfo(MatchFieldType.metadata,
146 MetaDataUtil.getMetaDataForLPortDispatcher(lportTag,
147 ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, NwConstants.L3VPN_SERVICE_INDEX)),
148 MetaDataUtil.getMetaDataMaskForLPortDispatcher() }));
149 String flowRef = getLportDispatcherFlowRef(interVpnLinkName, lportTag);
150 Flow lPortDispatcherFlow = MDSALUtil.buildFlowNew(NwConstants.LPORT_DISPATCHER_TABLE, flowRef,
151 VpnConstants.DEFAULT_LPORT_DISPATCHER_FLOW_PRIORITY, flowRef,
152 0, 0, VpnUtil.getCookieL3((int) vpnId), matches,
153 buildLportDispatcherTableInstructions(vpnId));
154 return lPortDispatcherFlow;
158 * Builds a flowRef to be assigned to the flow to be installed into
159 * LPortDispatcher table
161 * @param interVpnLinkName The name of the InterVpnLink
162 * @param lportTag Dataplane identifier of the LogicalPort
163 * @return the flow reference string
165 public static String getLportDispatcherFlowRef(String interVpnLinkName, Integer lportTag) {
166 String flowRef = new StringBuffer().append(VpnConstants.FLOWID_PREFIX).append("INTERVPNLINK")
167 .append(NwConstants.FLOWID_SEPARATOR).append(interVpnLinkName)
168 .append(NwConstants.FLOWID_SEPARATOR).append(lportTag)
169 .append(NwConstants.FLOWID_SEPARATOR).append(ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, NwConstants.L3VPN_SERVICE_INDEX))
170 .append(NwConstants.FLOWID_SEPARATOR).append(VpnConstants.DEFAULT_LPORT_DISPATCHER_FLOW_PRIORITY)
176 public static List<Instruction> buildLportDispatcherTableInstructions (long vpnId) {
177 int instructionKey = 0;
178 List<Instruction> instructions = new ArrayList<Instruction>();
179 instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(MetaDataUtil.getVpnIdMetadata(vpnId),
180 MetaDataUtil.METADATA_MASK_VRFID,
182 instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(NwConstants.L3_FIB_TABLE, ++instructionKey));
188 * Retrieves the States of all InterVpnLinks
190 * @param broker dataBroker service reference
191 * @return the list of objects that holds the InterVpnLink state information
193 public static List<InterVpnLinkState> getAllInterVpnLinkState(DataBroker broker) {
194 InstanceIdentifier<InterVpnLinkStates> interVpnLinkStateIid = InstanceIdentifier.builder(InterVpnLinkStates.class).build();
196 Optional<InterVpnLinkStates> interVpnLinkStateOpData = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION,
197 interVpnLinkStateIid);
199 return (interVpnLinkStateOpData.isPresent()) ? interVpnLinkStateOpData.get().getInterVpnLinkState()
200 : new ArrayList<InterVpnLinkState>();