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.genius.itm.confighelpers;
10 import java.math.BigInteger;
11 import java.util.ArrayList;
12 import java.util.List;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.genius.itm.globals.ITMConstants;
18 import org.opendaylight.genius.itm.impl.ItmUtils;
19 import org.opendaylight.genius.mdsalutil.MDSALUtil;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.*;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.tepsnothostedintransportzone.UnknownVteps;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.tepsnothostedintransportzone.UnknownVtepsBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.tepsnothostedintransportzone.UnknownVtepsKey;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Subnets;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.SubnetsBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.SubnetsKey;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.Vteps;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.VtepsBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.VtepsKey;
33 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
37 public class OvsdbTepAddConfigHelper {
39 private static final Logger LOG = LoggerFactory.getLogger(OvsdbTepAddConfigHelper.class);
42 * Adds the TEP into ITM configuration Datastore in one of the following cases:
43 * 1) default transport zone
44 * 2) Configured transport zone
45 * 3) Unhosted transport zone
47 * @param tepIp TEP-IP address in string
48 * @param strDpid bridge datapath ID in string
49 * @param tzName transport zone name in string
50 * @param ofTunnel boolean flag for TEP to enable/disable of-tunnel feature on it
51 * @param dataBroker data broker handle to perform operations on config datastore
52 * @param wrTx WriteTransaction object
54 public static void addTepReceivedFromOvsdb(String tepIp, String strDpid, String tzName,
55 boolean ofTunnel, DataBroker dataBroker, WriteTransaction wrTx) {
56 BigInteger dpid = BigInteger.valueOf(0);
58 if (strDpid != null && !strDpid.isEmpty()) {
59 dpid = MDSALUtil.getDpnId(strDpid);
63 IpAddress tepIpAddress = new IpAddress(tepIp.toCharArray());
64 TransportZone tZone = null;
66 // Case: TZ name is not given with CSS TEP.
68 tzName = ITMConstants.DEFAULT_TRANSPORT_ZONE;
69 // add TEP into default-TZ
70 tZone = ItmUtils.getTransportZoneFromConfigDS(tzName, dataBroker);
72 LOG.error("Error: default-transport-zone is not yet created.");
75 LOG.trace("Add TEP into default-transport-zone.");
77 // Case: Add TEP into corresponding TZ created from Northbound.
78 tZone = ItmUtils.getTransportZoneFromConfigDS(tzName, dataBroker);
80 // Case: TZ is not configured from Northbound, then add TEP into "teps-not-hosted-in-transport-zone"
81 LOG.trace("Adding TEP with unknown TZ into teps-not-hosted-in-transport-zone.");
82 addUnknownTzTepIntoTepsNotHosted(tzName, tepIpAddress, dpid, ofTunnel,
86 LOG.trace("Add TEP into transport-zone already configured by Northbound.");
90 // Get subnet list of corresponding TZ created from Northbound.
91 List<Subnets> subnetList = tZone.getSubnets();
92 String portName = ITMConstants.DUMMY_PORT;
94 IpPrefix subnetMaskObj = ItmUtils.getDummySubnet();
96 if (subnetList == null || subnetList.isEmpty()) {
97 if (subnetList == null) {
98 subnetList = new ArrayList<Subnets>();
100 List<Vteps> vtepList = new ArrayList<Vteps>();
101 LOG.trace("Add TEP in transport-zone when no subnet-list.");
102 addVtepInITMConfigDS(subnetList, subnetMaskObj, vtepList, tepIpAddress, tzName, dpid,
103 portName, ofTunnel, wrTx);
105 List<Vteps> vtepList = null;
107 // subnet list already exists case; check for dummy-subnet
108 for (Subnets subnet : subnetList) {
109 if (subnet.getKey().getPrefix().equals(subnetMaskObj)) {
110 LOG.trace("Subnet exists in the subnet list of transport-zone {}.", tzName);
111 // get vtep list of existing subnet
112 vtepList = subnet.getVteps();
117 if (vtepList == null || vtepList.isEmpty()) {
118 // case: vtep list does not exist or it has no elements
119 if (vtepList == null) {
120 vtepList = new ArrayList<Vteps>();
122 LOG.trace("Add TEP in transport-zone when no vtep-list for specific subnet.");
123 addVtepInITMConfigDS(subnetList, subnetMaskObj, vtepList, tepIpAddress, tzName,
124 dpid, portName, ofTunnel, wrTx);
126 // case: vtep list has elements
127 boolean vtepFound = false;
128 Vteps oldVtep = null;
130 for (Vteps vtep : vtepList) {
131 if (vtep.getDpnId().equals(dpid)) {
134 // get portName of existing vtep
135 portName = vtep.getPortname();
140 addVtepInITMConfigDS(subnetList, subnetMaskObj, vtepList, tepIpAddress, tzName,
141 dpid, portName, ofTunnel, wrTx);
143 // vtep is found, update it with tep-ip
144 vtepList.remove(oldVtep);
145 addVtepInITMConfigDS(subnetList, subnetMaskObj, vtepList, tepIpAddress, tzName,
146 dpid, portName, ofTunnel, wrTx);
153 * Adds the TEP into Vtep list in the subnet list in the transport zone list
154 * from ITM configuration Datastore by merge operation with write transaction.
156 * @param subnetList subnets list object
157 * @param subnetMaskObj subnet mask in IpPrefix object
158 * @param updatedVtepList updated Vteps list object which will have new TEP for addition
159 * @param tepIpAddress TEP IP address in IpAddress object
160 * @param tzName transport zone name in string
161 * @param dpid bridge datapath ID in BigInteger
162 * @param portName port name as a part of VtepsKey
163 * @param ofTunnel boolean flag for TEP to enable/disable of-tunnel feature on it
164 * @param wrTx WriteTransaction object
166 public static void addVtepInITMConfigDS(List<Subnets> subnetList, IpPrefix subnetMaskObj,
167 List<Vteps> updatedVtepList, IpAddress tepIpAddress, String tzName, BigInteger dpid,
168 String portName, boolean ofTunnel, WriteTransaction wrTx) {
169 //Create TZ node path
170 InstanceIdentifier<TransportZone> tZonepath =
171 InstanceIdentifier.builder(TransportZones.class)
172 .child(TransportZone.class, new TransportZoneKey(tzName)).build();
174 // this check is needed to reuse same function from TransportZoneListener
175 // when VTEP is moved from TepsNotHosted list to TZ configured from Northbound.
176 if (dpid.compareTo(BigInteger.ZERO) > 0) {
178 VtepsKey vtepkey = new VtepsKey(dpid, portName);
180 new VtepsBuilder().setDpnId(dpid).setIpAddress(tepIpAddress).setKey(vtepkey).
181 setPortname(portName).setOptionOfTunnel(ofTunnel).build();
183 // Add vtep obtained from bridge into list
184 updatedVtepList.add(vtepObj);
186 LOG.trace("Adding TEP (TZ: {} Subnet: {} TEP IP: {} DPID: {}, of-tunnel: {})"
187 + "in ITM Config DS.", tzName, subnetMaskObj.getValue().toString(), tepIpAddress,
190 // this is case when this function is called while TEPs movement from tepsNotHosted list when
191 // corresponding TZ is configured from northbound.
192 for (Vteps vtep: updatedVtepList) {
193 LOG.trace("Moving TEP (TEP IP: {} DPID: {}, of-tunnel: {})"
194 + "from tepNotHosted list into transport-zone {} in ITM Config DS.",
195 vtep.getIpAddress().getValue().toString(), vtep.getDpnId(), ofTunnel, tzName);
199 // Create subnet object
200 SubnetsKey subKey = new SubnetsKey(subnetMaskObj);
201 IpAddress gatewayIP = new IpAddress(ITMConstants.DUMMY_GATEWAY_IP.toCharArray());
202 int vlanID = ITMConstants.DUMMY_VLANID;
205 new SubnetsBuilder().setGatewayIp(gatewayIP)
206 .setKey(subKey).setPrefix(subnetMaskObj)
207 .setVlanId(vlanID).setVteps(updatedVtepList).build();
209 // add subnet into subnet list
210 subnetList.add(subnet);
212 // create TZ node with updated subnet having new vtep
213 TransportZone updatedTzone =
214 new TransportZoneBuilder().setKey(new TransportZoneKey(tzName)).setSubnets(subnetList)
215 .setZoneName(tzName).build();
217 // Update TZ in Config DS to add vtep in TZ
218 wrTx.merge(LogicalDatastoreType.CONFIGURATION, tZonepath, updatedTzone, true);
222 * Adds the TEP into Vtep list in the subnet list in the transport zone list
223 * from ITM configuration Datastore by merge operation with write transaction.
225 * @param tzName transport zone name in string
226 * @param tepIpAddress TEP IP address in IpAddress object
227 * @param dpid bridge datapath ID in BigInteger
228 * @param ofTunnel boolean flag for TEP to enable/disable of-tunnel feature on it
229 * @param dataBroker data broker handle to perform operations on config datastore
230 * @param wrTx WriteTransaction object
232 protected static void addUnknownTzTepIntoTepsNotHosted(String tzName, IpAddress tepIpAddress,
233 BigInteger dpid, boolean ofTunnel, DataBroker dataBroker, WriteTransaction wrTx) {
234 List<UnknownVteps> vtepList = null;
236 TepsNotHostedInTransportZone unknownTz =
237 ItmUtils.getUnknownTransportZoneFromITMConfigDS(tzName, dataBroker);
238 if (unknownTz == null) {
239 LOG.trace("Unhosted TransportZone does not exist.");
240 vtepList = new ArrayList<UnknownVteps>();
241 addVtepIntoTepsNotHosted(vtepList, tepIpAddress, tzName, dpid, ofTunnel, wrTx);
243 vtepList = unknownTz.getUnknownVteps();
244 if (vtepList == null || vtepList.isEmpty()) {
245 // case: vtep list does not exist or it has no elements
246 if (vtepList == null) {
247 vtepList = new ArrayList<UnknownVteps>();
249 LOG.trace("Add TEP in unhosted TZ ({}) when no vtep-list in the TZ.", tzName);
250 addVtepIntoTepsNotHosted(vtepList, tepIpAddress, tzName, dpid, ofTunnel, wrTx);
252 // case: vtep list has elements
253 boolean vtepFound = false;
254 UnknownVteps oldVtep = null;
256 for (UnknownVteps vtep : vtepList) {
257 if (vtep.getDpnId().equals(dpid)) {
264 addVtepIntoTepsNotHosted(vtepList, tepIpAddress, tzName, dpid,
267 // vtep is found, update it with tep-ip
268 vtepList.remove(oldVtep);
269 addVtepIntoTepsNotHosted(vtepList, tepIpAddress, tzName, dpid,
277 * Adds the TEP into Unknown Vtep list under the transport zone in the TepsNotHosted list
278 * from ITM configuration Datastore by merge operation with write transaction.
280 * @param updatedVtepList updated UnknownVteps list object which will have new TEP for addition
282 * @param tepIpAddress TEP IP address in IpAddress object
283 * @param tzName transport zone name in string
284 * @param dpid bridge datapath ID in BigInteger
285 * @param ofTunnel boolean flag for TEP to enable/disable of-tunnel feature on it
286 * @param wrTx WriteTransaction object
288 protected static void addVtepIntoTepsNotHosted(List<UnknownVteps> updatedVtepList,
289 IpAddress tepIpAddress, String tzName, BigInteger dpid, boolean ofTunnel,
290 WriteTransaction wrTx) {
291 //Create TZ node path
292 InstanceIdentifier<TepsNotHostedInTransportZone> tZonepath =
293 InstanceIdentifier.builder(TransportZones.class)
294 .child(TepsNotHostedInTransportZone.class,
295 new TepsNotHostedInTransportZoneKey(tzName)).build();
298 UnknownVtepsKey vtepkey = new UnknownVtepsKey(dpid);
299 UnknownVteps vtepObj =
300 new UnknownVtepsBuilder().setDpnId(dpid).setIpAddress(tepIpAddress).setKey(vtepkey)
301 .setOfTunnel(ofTunnel).build();
303 // Add vtep obtained into unknown TZ tep list
304 updatedVtepList.add(vtepObj);
306 // create unknown TZ node with updated vtep list
307 TepsNotHostedInTransportZone updatedTzone = new TepsNotHostedInTransportZoneBuilder()
308 .setKey(new TepsNotHostedInTransportZoneKey(tzName)).setZoneName(tzName)
309 .setUnknownVteps(updatedVtepList).build();
311 LOG.trace("Adding TEP into unhosted (TZ: {}, DPID: {}, TEP IP: {}, of-tunnel: {})"
312 + "in ITM Config DS.", tzName, dpid, tepIpAddress, ofTunnel);
314 // Update TZ in Config DS.
315 wrTx.merge(LogicalDatastoreType.CONFIGURATION, tZonepath, updatedTzone, true);