blob: 30d42b0d67b2f5a385f50ea344bcf927e5769078 [file] [log] [blame]
chengfan8ea6a562016-11-26 16:37:02 +08001/*
2 * Copyright 2016 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.teyang.utils.tunnel;
18
19import com.google.common.collect.Lists;
20import org.onosproject.tetopology.management.api.TeTopologyKey;
21import org.onosproject.tetopology.management.api.node.TeNodeKey;
22import org.onosproject.tetopology.management.api.node.TtpKey;
23import org.onosproject.tetunnel.api.tunnel.DefaultTeTunnel;
24import org.onosproject.tetunnel.api.tunnel.TeTunnel;
25import org.onosproject.tetunnel.api.tunnel.TeTunnelKey;
26import org.onosproject.tetunnel.api.tunnel.path.DefaultTePath;
27import org.onosproject.tetunnel.api.tunnel.path.DefaultTeRouteUnnumberedLink;
28import org.onosproject.tetunnel.api.tunnel.path.TePath;
29import org.onosproject.tetunnel.api.tunnel.path.TeRouteSubobject;
30import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.IetfTe;
31import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.IetfTeOpParam;
32import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.DefaultTe;
33import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.Te;
34import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.pathparamsconfig.Type;
35import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.pathparamsconfig.type.DefaultDynamic;
36import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.pathparamsconfig.type.DefaultExplicit;
37import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.pathparamsconfig.type.explicit.DefaultExplicitRouteObjects;
38import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.pathparamsconfig.type.explicit.ExplicitRouteObjects;
39import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelproperties.Config;
40import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelproperties.DefaultPrimaryPaths;
41import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelproperties.DefaultState;
42import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelproperties.PrimaryPaths;
43import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelproperties.State;
44import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelsgrouping.DefaultTunnels;
45import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelsgrouping.Tunnels;
46import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelsgrouping.tunnels.DefaultTunnel;
47import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.rev20160705.ietfte.tunnelsgrouping.tunnels.Tunnel;
48import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProt1Forn;
49import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtBidir1To1;
50import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtReroute;
51import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtRerouteExtra;
52import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtType;
53import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtUnidir1To1;
54import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.LspProtUnprotected;
55import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.PathSignalingRsvpte;
56import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.PathSignalingSr;
57import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.RouteIncludeEro;
58import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.StateDown;
59import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.StateUp;
60import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.TunnelP2Mp;
61import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.TunnelP2p;
62import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.TunnelType;
63import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.explicitroutesubobject.type.DefaultUnnumberedLink;
64import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.explicitroutesubobject.type.UnnumberedLink;
65import org.slf4j.Logger;
66
67import java.util.ArrayList;
68import java.util.List;
69
70import static org.onosproject.tetunnel.api.tunnel.TeTunnel.LspProtectionType;
71import static org.onosproject.tetunnel.api.tunnel.path.TeRouteSubobject.Type.UNNUMBERED_LINK;
72import static org.onosproject.teyang.utils.tunnel.BasicConverter.bytesToLong;
73import static org.onosproject.teyang.utils.tunnel.BasicConverter.ipToLong;
74import static org.onosproject.teyang.utils.tunnel.BasicConverter.longToByte;
75import static org.onosproject.teyang.utils.tunnel.BasicConverter.longToIp;
76import static org.slf4j.LoggerFactory.getLogger;
77
78
79/**
80 * Tunnel convert utils.
81 */
82public final class TunnelConverter {
83
84 private static final Logger log = getLogger(TunnelConverter.class);
85 private static final String DEFAULT_PATH_NAME = "ietfPath";
86 private static final String DEFAULT_PATH_CONSTRAINT = "ietfPath";
87 private static final int DEFAULT_PATH_PREFERENCE = 1;
88 private static final boolean DEFAULT_CSPF_STATE = true;
89 private static final boolean DEFAULT_LOCKDOWN_STATE = true;
90
91 // no instantiation
92 private TunnelConverter() {
93 }
94
95 /**
96 * Build a general IETF TE object with a giving tunnel list. for there are
97 * many kind of attributes in IETF TE, now we only care about the tunnel
98 * attributes.
99 *
100 * @param tunnels tunnels in the TE network
101 * @return IETF te info in the TE network
102 */
103 public static IetfTe buildIetfTeWithTunnels(List<Tunnel> tunnels) {
104 Tunnels teTunnels = new DefaultTunnels
105 .TunnelsBuilder()
106 .tunnel(tunnels)
107 .build();
108 Te te = new DefaultTe
109 .TeBuilder()
110 .tunnels(teTunnels)
111 .build();
112 return new IetfTeOpParam
113 .IetfTeBuilder()
114 .te(te)
115 .yangIetfTeOpType(IetfTe.OnosYangOpType.NONE)
116 .build();
117 }
118
119 public static IetfTe buildIetfTe(TeTunnel teTunnel) {
120 Tunnel tunnel = te2YangTunnelConverter(teTunnel);
121 return buildIetfTeWithTunnels(Lists.newArrayList(tunnel));
122 }
123
124 /**
125 * Converts a specific te tunnel defined in the APP to the general te tunnel
126 * defined in YANG model.
127 *
128 * @param tunnel te tunnel defined in APP
129 * @return tunnel defined in YANG model
130 */
131 public static Tunnel te2YangTunnelConverter(TeTunnel tunnel) {
132 List<PrimaryPaths> pathsList = new ArrayList<>();
133 //TODO add path info after yang tool change to guava from google-collect
134 tunnel.primaryPaths()
135 .forEach(tePath -> pathsList.add(te2YangPrimaryPath(tePath)));
136
137 Tunnel.TunnelBuilder builder = new DefaultTunnel
138 .TunnelBuilder()
139 .type(te2YangTunnelType(tunnel.type()))
140 .name(tunnel.name())
141 .identifier(tunnel.teTunnelKey().teTunnelId())
142 .state(te2YangTunnelState(tunnel))
143 .primaryPaths(pathsList);
144
145 return builder.build();
146 }
147
148 private static State te2YangTunnelState(TeTunnel tunnel) {
149 State.StateBuilder stateBuilder = new DefaultState.StateBuilder();
150 stateBuilder.name(tunnel.name())
151 .identifier((int) tunnel.teTunnelKey().teTunnelId())
152 .source((longToIp(tunnel.srcNode().teNodeId())))
153 .destination((longToIp(tunnel.dstNode().teNodeId())))
154 .srcTpId(longToByte(tunnel.srcTp().ttpId()))
155 .dstTpId(longToByte(tunnel.dstTp().ttpId()))
156 .adminStatus(te2YangStateType(tunnel.adminStatus()))
157 .lspProtectionType(
158 te2YangProtectionType(tunnel.lspProtectionType()))
159 .type(te2YangTunnelType(tunnel.type()))
160 .build();
161 return stateBuilder.build();
162 }
163
164 private static PrimaryPaths te2YangPrimaryPath(TePath tePath) {
165 DefaultPrimaryPaths.PrimaryPathsBuilder builder = new DefaultPrimaryPaths
166 .PrimaryPathsBuilder()
167 .name(DEFAULT_PATH_NAME)
168 .preference(DEFAULT_PATH_PREFERENCE)
169 .state(te2YangPrimaryPathState(tePath))
170 .yangPrimaryPathsOpType(IetfTe.OnosYangOpType.NONE);
171 return builder.build();
172 }
173
174 private static org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
175 .te.rev20160705.ietfte.p2pprimarypathparams.State
176 te2YangPrimaryPathState(TePath tePath) {
177
178 List<TeRouteSubobject> teRouteSubobjects = tePath.explicitRoute();
179
180 List<ExplicitRouteObjects> routeObjects = new ArrayList<>();
181 teRouteSubobjects.forEach(teRouteSubobject -> {
182 routeObjects.add(te2YangRouteSubobject(teRouteSubobject));
183 });
184 DefaultExplicit.ExplicitBuilder explicitBuilder =
185 DefaultExplicit.builder().explicitRouteObjects(routeObjects);
186
187 return new org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.
188 te.rev20160705.ietfte.p2pprimarypathparams.DefaultState
189 .StateBuilder()
190 .type(explicitBuilder.build())
191 .pathNamedConstraint(DEFAULT_PATH_CONSTRAINT)
192 .noCspf(DEFAULT_CSPF_STATE)
193 .lockdown(DEFAULT_LOCKDOWN_STATE)
194 .build();
195 }
196
197 private static ExplicitRouteObjects
198 te2YangRouteSubobject(TeRouteSubobject routeSubobject) {
199
200 TeRouteSubobject.Type type = routeSubobject.type();
201 UnnumberedLink yanglink = null;
202 //TODO implement other kind of TeRouteSubobject type
203 if (type == UNNUMBERED_LINK) {
204 DefaultTeRouteUnnumberedLink unnumberedLink =
205 (DefaultTeRouteUnnumberedLink) routeSubobject;
206 TeNodeKey nodeKey = unnumberedLink.node();
207 TtpKey ttpKey = unnumberedLink.ttp();
208
209 yanglink = DefaultUnnumberedLink.builder()
210 .routerId(longToIp(nodeKey.teNodeId()))
211 .interfaceId(ttpKey.ttpId())
212 .build();
213
214 }
215
216 //TODO implement other kind of explicitRoute usage type
217 return DefaultExplicitRouteObjects.builder()
218 .type(yanglink)
219 .explicitRouteUsage(RouteIncludeEro.class)
220 .build();
221 }
222
223 /**
224 * Converts a YANG TE tunnel defined in the YANG model to a specific TE
225 * tunnel defined in the TE tunnel APP.
226 *
227 * @param tunnel yang tunnel object
228 * @return default Te tunnel defined in TE tunnel APP
229 */
230 public static DefaultTeTunnel yang2TeTunnel(org.onosproject.yang.gen.v1.
231 urn.ietf.params.xml.
232 ns.yang.ietf.te.
233 rev20160705.ietfte.
234 tunnelsgrouping.
235 tunnels.Tunnel
236 tunnel,
237 TeTopologyKey topologyKey) {
238 //get config info
239 Config config = tunnel.config();
240
241 //build basic attribute, node and ttp
242 TeNodeKey srcNodeKey = new TeNodeKey(topologyKey, ipToLong(config.source()));
243 TeNodeKey dstNodeKey = new TeNodeKey(topologyKey, ipToLong(config.destination()));
244
245 TtpKey srcTtpKey = new TtpKey(srcNodeKey, bytesToLong(config.srcTpId()));
246 TtpKey dstTtpKey = new TtpKey(srcNodeKey, bytesToLong(config.dstTpId()));
247
248 //check if paths have been set
249 List<PrimaryPaths> primaryPaths = tunnel.primaryPaths();
250 List<TePath> paths = new ArrayList<>();
251 primaryPaths.forEach(primaryPath -> paths.add(
252 yang2TePrimaryPaths(primaryPath, topologyKey)));
253
254 //build the te tunnel
255 DefaultTeTunnel.Builder builder = new DefaultTeTunnel.Builder();
256
257 return builder.teTunnelKey(new TeTunnelKey(topologyKey, config.identifier()))
258 .name(config.name())
259 .type(yang2TeTunnelType(config.type()))
260 .lspProtectionType(yang2TeProtectionType(config.lspProtectionType()))
261 .adminState(yang2TeStateType(config.adminStatus()))
262 .srcNode(srcNodeKey)
263 .dstNode(dstNodeKey)
264 .srcTp(srcTtpKey)
265 .dstTp(dstTtpKey)
266 .primaryPaths(paths).build();
267 }
268
269 private static TePath yang2TePrimaryPaths(PrimaryPaths primaryPath,
270 TeTopologyKey topologyKey) {
271 org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.
272 rev20160705.ietfte.p2pprimarypathparams.Config
273 pathConfig = primaryPath.config();
274
275 TePath tePath;
276 TePath.Type tePathType = null;
277 Type type = pathConfig.type();
278
279 if (type == null) {
280 return new DefaultTePath(TePath.Type.DYNAMIC,
281 Lists.newArrayList(),
282 Lists.newArrayList(),
283 Lists.newArrayList());
284 }
285
286 Class<? extends Type> typeClass = type.getClass();
287
288 List<TeRouteSubobject> routeSubobjects = new ArrayList<>();
289
290 if (typeClass.isAssignableFrom(DefaultExplicit.class)) {
291 DefaultExplicit explicitPath = (DefaultExplicit) type;
292 explicitPath
293 .explicitRouteObjects()
294 .forEach(o -> routeSubobjects.add(
295 yang2TeRouteSubobject(o, topologyKey)));
296 tePathType = TePath.Type.EXPLICIT;
297
298 } else if (typeClass.isAssignableFrom(DefaultDynamic.class)) {
299 tePathType = TePath.Type.DYNAMIC;
300 }
301
302 tePath = new DefaultTePath(tePathType,
303 Lists.newArrayList(),
304 routeSubobjects,
305 Lists.newArrayList());
306 return tePath;
307 }
308
309 private static TeRouteSubobject
310 yang2TeRouteSubobject(ExplicitRouteObjects routeObject,
311 TeTopologyKey topologyKey) {
312
313 //TODO implement other types of route type
314 DefaultUnnumberedLink type = (DefaultUnnumberedLink) routeObject.type();
315 TeNodeKey nodeKey = new TeNodeKey(topologyKey, ipToLong(type.routerId()));
316 TtpKey tpId = new TtpKey(nodeKey, type.interfaceId());
317 return new DefaultTeRouteUnnumberedLink(nodeKey, tpId);
318 }
319
320 private static TeTunnel.Type yang2TeTunnelType(Class type) {
321 TeTunnel.Type tunnelType = null;
322 if (type.isAssignableFrom(TunnelP2Mp.class)) {
323 tunnelType = TeTunnel.Type.P2MP;
324 } else if (type.isAssignableFrom(TunnelP2p.class)) {
325 tunnelType = TeTunnel.Type.P2P;
326 } else if (type.isAssignableFrom(PathSignalingRsvpte.class)) {
327 tunnelType = TeTunnel.Type.PATH_SIGNALING_RSVPTE;
328 } else if (type.isAssignableFrom(PathSignalingSr.class)) {
329 tunnelType = TeTunnel.Type.PATH_SIGNALING_SR;
330 }
331 return tunnelType;
332 }
333
334
335 private static Class<? extends TunnelType> te2YangTunnelType(TeTunnel.Type type) {
336 Class<? extends TunnelType> tunnelType = null;
337 switch (type) {
338
339 case P2P:
340 tunnelType = TunnelP2p.class;
341 break;
342 case P2MP:
343 tunnelType = TunnelP2Mp.class;
344 break;
345 case PATH_SIGNALING_RSVPTE:
346 tunnelType = PathSignalingRsvpte.class;
347
348 break;
349 case PATH_SIGNALING_SR:
350 tunnelType = PathSignalingSr.class;
351 break;
352 default:
353 log.error("Unknown te tunnel type {}", type.toString());
354 }
355 return tunnelType;
356 }
357
358 private static LspProtectionType
359 yang2TeProtectionType(Class<? extends LspProtType> protType) {
360 LspProtectionType type = null;
361 if (protType.isAssignableFrom(LspProt1Forn.class)) {
362 type = LspProtectionType.LSP_PROT_1_FOR_N;
363 } else if (protType.isAssignableFrom(LspProtBidir1To1.class)) {
364 type = LspProtectionType.LSP_PROT_BIDIR_1_TO_1;
365 } else if (protType.isAssignableFrom(LspProtReroute.class)) {
366 type = LspProtectionType.LSP_PROT_REROUTE;
367 } else if (protType.isAssignableFrom(LspProtRerouteExtra.class)) {
368 type = LspProtectionType.LSP_PROT_REROUTE_EXTRA;
369 } else if (protType.isAssignableFrom(LspProtUnidir1To1.class)) {
370 type = LspProtectionType.LSP_PROT_UNIDIR_1_TO_1;
371 } else if (protType.isAssignableFrom(LspProtUnprotected.class)) {
372 type = LspProtectionType.LSP_PROT_UNPROTECTED;
373 }
374 return type;
375 }
376
377 private static Class<? extends LspProtType>
378 te2YangProtectionType(LspProtectionType protType) {
379 Class<? extends LspProtType> type = null;
380 switch (protType) {
381
382 case LSP_PROT_UNPROTECTED:
383 type = LspProtUnprotected.class;
384 break;
385 case LSP_PROT_REROUTE:
386 type = LspProtReroute.class;
387 break;
388 case LSP_PROT_REROUTE_EXTRA:
389 type = LspProtRerouteExtra.class;
390 break;
391 case LSP_PROT_UNIDIR_1_TO_1:
392 type = LspProtUnidir1To1.class;
393 break;
394 case LSP_PROT_BIDIR_1_TO_1:
395 type = LspProtBidir1To1.class;
396 break;
397 case LSP_PROT_1_FOR_N:
398 type = LspProt1Forn.class;
399 break;
400 default:
401 log.error("Unknown te tunnel type {}", protType.toString());
402 }
403 return type;
404 }
405
406 private static TeTunnel.State
407 yang2TeStateType(Class<? extends org.onosproject.yang.gen.v1.urn.ietf.
408 params.xml.ns.yang.ietf.te.types.
409 rev20160705.ietftetypes.StateType> stateType) {
410 TeTunnel.State teStateType = null;
411 if (stateType.isAssignableFrom(StateUp.class)) {
412 teStateType = TeTunnel.State.UP;
413 } else if (stateType.isAssignableFrom(StateDown.class)) {
414 teStateType = TeTunnel.State.DOWN;
415 }
416 return teStateType;
417 }
418
419 private static Class<? extends org.onosproject.yang.gen.v1.urn.ietf.params.
420 xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.StateType>
421 te2YangStateType(TeTunnel.State stateType) {
422 Class<? extends org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.
423 ietf.te.types.rev20160705.ietftetypes.StateType> state = null;
424
425 switch (stateType) {
426
427 case DOWN:
428 state = StateDown.class;
429 break;
430 case UP:
431 state = StateUp.class;
432 break;
433 default:
434 log.error("Unknown te tunnel type {}", stateType.toString());
435
436 }
437 return state;
438 }
439}