Merge "Add service names for priority configuration"
[netvirt.git] / vpnservice / vpnmanager / vpnmanager-impl / src / main / java / org / opendaylight / netvirt / vpnmanager / intervpnlink / InterVpnLinkUtil.java
1 /*
2  * Copyright (c) 2016 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 package org.opendaylight.netvirt.vpnmanager.intervpnlink;
9
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;
33
34 import java.math.BigInteger;
35 import java.util.ArrayList;
36 import java.util.Arrays;
37 import java.util.List;
38
39 /**
40  * This class contains methods to be used as utilities related with inter-vpn-link.
41  *
42  */
43 public class InterVpnLinkUtil {
44     private static final Logger LOG = LoggerFactory.getLogger(InterVpnLinkUtil.class);
45
46     /**
47      * Updates VpnToDpn map by adding a fake VpnInterface related to an
48      * InterVpnLink in the corresponding DPNs
49      *
50      * @param broker dataBroker service reference
51      * @param dpnList List of DPNs where the fake InterVpnLink interface must
52      *     be added
53      * @param vpnUuid UUID of the VPN to which the fake interfaces belong
54      */
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));
64             }
65         }
66     }
67
68
69     /**
70      * Retrieves the InterVpnLink object searching by its name
71      *
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
76      */
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);
82     }
83
84     /**
85      * Updates inter-VPN link state
86      *
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
94      */
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),
104                            newVpnLinkState);
105     }
106
107     /**
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
111      *
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
118      *     InterVpnLink
119      * @param lPortTagOfOtherEndpoint Dataplane identifier of the other
120      *     endpoint of the InterVpnLink
121      */
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);
130         }
131     }
132
133    /**
134     * Builds a Flow to be installed into LPortDispatcher table, that matches on
135     * SI=2 + vpnLinkEndpointPseudoPortTag and sends to FIB
136     *
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
141     */
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,
145                                                               new BigInteger[] {
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;
155    }
156
157    /**
158    * Builds a flowRef to be assigned to the flow to be installed into
159    * LPortDispatcher table
160    *
161    * @param interVpnLinkName The name of the InterVpnLink
162    * @param lportTag Dataplane identifier of the LogicalPort
163    * @return the flow reference string
164    */
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)
171                      .toString();
172        return flowRef;
173    }
174
175
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,
181                                                                     ++instructionKey));
182        instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(NwConstants.L3_FIB_TABLE, ++instructionKey));
183
184        return instructions;
185    }
186
187    /**
188     * Retrieves the States of all InterVpnLinks
189     *
190     * @param broker dataBroker service reference
191     * @return the list of objects that holds the InterVpnLink state information
192     */
193    public static List<InterVpnLinkState> getAllInterVpnLinkState(DataBroker broker) {
194        InstanceIdentifier<InterVpnLinkStates> interVpnLinkStateIid = InstanceIdentifier.builder(InterVpnLinkStates.class).build();
195
196        Optional<InterVpnLinkStates> interVpnLinkStateOpData = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION,
197                interVpnLinkStateIid);
198
199        return (interVpnLinkStateOpData.isPresent()) ? interVpnLinkStateOpData.get().getInterVpnLinkState()
200                : new ArrayList<InterVpnLinkState>();
201    }
202
203
204 }