blob: c4040a7f3bf44b072480f39756d4fb14ca6c0753 [file] [log] [blame]
Jian Lifc90a082017-03-31 23:36:14 +09001/*
2 * Copyright 2017-present 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 */
16package org.onosproject.drivers.lisp.extensions;
17
18import com.google.common.collect.ImmutableList;
19import com.google.common.collect.Lists;
20import org.onlab.packet.IpAddress;
21import org.onlab.packet.IpPrefix;
22import org.onlab.packet.MacAddress;
23import org.onosproject.lisp.ctl.ExtensionMappingAddressInterpreter;
24import org.onosproject.lisp.msg.types.LispAfiAddress;
25import org.onosproject.lisp.msg.types.LispDistinguishedNameAddress;
26import org.onosproject.lisp.msg.types.LispIpv4Address;
27import org.onosproject.lisp.msg.types.LispIpv6Address;
28import org.onosproject.lisp.msg.types.LispMacAddress;
29import org.onosproject.lisp.msg.types.lcaf.LispAppDataLcafAddress;
30import org.onosproject.lisp.msg.types.lcaf.LispAsLcafAddress;
31import org.onosproject.lisp.msg.types.lcaf.LispGeoCoordinateLcafAddress;
32import org.onosproject.lisp.msg.types.lcaf.LispLcafAddress;
33import org.onosproject.lisp.msg.types.lcaf.LispListLcafAddress;
34import org.onosproject.lisp.msg.types.lcaf.LispMulticastLcafAddress;
35import org.onosproject.lisp.msg.types.lcaf.LispNatLcafAddress;
36import org.onosproject.lisp.msg.types.lcaf.LispNonceLcafAddress;
37import org.onosproject.lisp.msg.types.lcaf.LispSegmentLcafAddress;
38import org.onosproject.lisp.msg.types.lcaf.LispSourceDestLcafAddress;
39import org.onosproject.lisp.msg.types.lcaf.LispTeLcafAddress;
40import org.onosproject.lisp.msg.types.lcaf.LispTeRecord;
41import org.onosproject.mapping.addresses.ExtensionMappingAddress;
42import org.onosproject.mapping.addresses.ExtensionMappingAddressResolver;
43import org.onosproject.mapping.addresses.ExtensionMappingAddressType;
44import org.onosproject.mapping.addresses.IPMappingAddress;
45import org.onosproject.mapping.addresses.MappingAddress;
46import org.onosproject.mapping.addresses.MappingAddresses;
47import org.onosproject.net.driver.AbstractHandlerBehaviour;
48import org.slf4j.Logger;
49import org.slf4j.LoggerFactory;
50
51import java.util.List;
52
53import static org.onosproject.mapping.addresses.ExtensionMappingAddressType.ExtensionMappingAddressTypes.*;
54/**
55 * Interpreter for mapping address extension.
56 */
57public class LispExtensionMappingAddressInterpreter extends AbstractHandlerBehaviour
58 implements ExtensionMappingAddressInterpreter, ExtensionMappingAddressResolver {
59
60 private static final Logger log = LoggerFactory.getLogger(
61 LispExtensionMappingAddressInterpreter.class);
62
63 private static final int IPV4_PREFIX_LENGTH = 32;
64 private static final int IPV6_PREFIX_LENGTH = 128;
65
66 @Override
67 public boolean supported(ExtensionMappingAddressType type) {
68
69 if (type.equals(LIST_ADDRESS.type())) {
70 return true;
71 }
72 if (type.equals(SEGMENT_ADDRESS.type())) {
73 return true;
74 }
75 if (type.equals(AS_ADDRESS.type())) {
76 return true;
77 }
78 if (type.equals(APPLICATION_DATA_ADDRESS.type())) {
79 return true;
80 }
81 if (type.equals(GEO_COORDINATE_ADDRESS.type())) {
82 return true;
83 }
84 if (type.equals(NAT_ADDRESS.type())) {
85 return true;
86 }
87 if (type.equals(NONCE_ADDRESS.type())) {
88 return true;
89 }
90 if (type.equals(MULTICAST_ADDRESS.type())) {
91 return true;
92 }
93 if (type.equals(TRAFFIC_ENGINEERING_ADDRESS.type())) {
94 return true;
95 }
96 if (type.equals(SOURCE_DEST_ADDRESS.type())) {
97 return true;
98 }
99
100 return false;
101 }
102
103 @Override
104 public LispLcafAddress mapMappingAddress(ExtensionMappingAddress mappingAddress) {
105 ExtensionMappingAddressType type = mappingAddress.type();
106
107 if (type.equals(LIST_ADDRESS.type())) {
108
109 LispListAddress listAddress = (LispListAddress) mappingAddress;
110 LispAfiAddress ipv4 = mapping2afi(listAddress.getIpv4());
111 LispAfiAddress ipv6 = mapping2afi(listAddress.getIpv6());
112
Jian Lie5aa5df2017-04-02 22:40:56 +0900113 if (ipv4 != null && ipv6 != null) {
114 return new LispListLcafAddress(ImmutableList.of(ipv4, ipv6));
115 } else {
116 return new LispListLcafAddress(ImmutableList.of());
117 }
Jian Lifc90a082017-03-31 23:36:14 +0900118 }
119
120 if (type.equals(SEGMENT_ADDRESS.type())) {
121
122 LispSegmentAddress segmentAddress = (LispSegmentAddress) mappingAddress;
123
124 return new LispSegmentLcafAddress.SegmentAddressBuilder()
125 .withInstanceId(segmentAddress.getInstanceId())
126 .withAddress(getAfiAddress(segmentAddress.getAddress()))
127 .build();
128 }
129
130 if (type.equals(AS_ADDRESS.type())) {
131
132 LispAsAddress asAddress = (LispAsAddress) mappingAddress;
133
134 return new LispAsLcafAddress.AsAddressBuilder()
135 .withAsNumber(asAddress.getAsNumber())
136 .withAddress(getAfiAddress(asAddress.getAddress()))
137 .build();
138 }
139
140 if (type.equals(APPLICATION_DATA_ADDRESS.type())) {
141
142 LispAppDataAddress appDataAddress = (LispAppDataAddress) mappingAddress;
143
144 return new LispAppDataLcafAddress.AppDataAddressBuilder()
145 .withProtocol(appDataAddress.getProtocol())
146 .withIpTos(appDataAddress.getIpTos())
147 .withLocalPortLow(appDataAddress.getLocalPortLow())
148 .withLocalPortHigh(appDataAddress.getLocalPortHigh())
149 .withRemotePortLow(appDataAddress.getRemotePortLow())
150 .withRemotePortHigh(appDataAddress.getRemotePortHigh())
151 .withAddress(getAfiAddress(appDataAddress.getAddress()))
152 .build();
153 }
154
155 if (type.equals(GEO_COORDINATE_ADDRESS.type())) {
156
157 LispGcAddress gcAddress = (LispGcAddress) mappingAddress;
158
159 return new LispGeoCoordinateLcafAddress.GeoCoordinateAddressBuilder()
160 .withIsNorth(gcAddress.isNorth())
161 .withLatitudeDegree(gcAddress.getLatitudeDegree())
162 .withLatitudeMinute(gcAddress.getLatitudeMinute())
163 .withLatitudeSecond(gcAddress.getLatitudeSecond())
164 .withIsEast(gcAddress.isEast())
165 .withLongitudeDegree(gcAddress.getLongitudeDegree())
166 .withLongitudeMinute(gcAddress.getLongitudeMinute())
167 .withLongitudeSecond(gcAddress.getLongitudeSecond())
168 .withAltitude(gcAddress.getAltitude())
169 .withAddress(getAfiAddress(gcAddress.getAddress()))
170 .build();
171 }
172
173 if (type.equals(NAT_ADDRESS.type())) {
174
175 LispNatAddress natAddress = (LispNatAddress) mappingAddress;
176
177 List<LispAfiAddress> aas = Lists.newArrayList();
178
179 natAddress.getRtrRlocAddresses()
180 .forEach(rtr -> aas.add(getAfiAddress(rtr)));
181
182 return new LispNatLcafAddress.NatAddressBuilder()
183 .withMsUdpPortNumber(natAddress.getMsUdpPortNumber())
184 .withEtrUdpPortNumber(natAddress.getEtrUdpPortNumber())
185 .withMsRlocAddress(getAfiAddress(natAddress.getMsRlocAddress()))
186 .withGlobalEtrRlocAddress(
187 getAfiAddress(natAddress.getGlobalEtrRlocAddress()))
188 .withPrivateEtrRlocAddress(
189 getAfiAddress(natAddress.getPrivateEtrRlocAddress()))
190 .withRtrRlocAddresses(aas)
191 .build();
192 }
193
194 if (type.equals(NONCE_ADDRESS.type())) {
195
196 LispNonceAddress nonceAddress = (LispNonceAddress) mappingAddress;
197
198 return new LispNonceLcafAddress.NonceAddressBuilder()
199 .withNonce(nonceAddress.getNonce())
200 .withAddress(getAfiAddress(nonceAddress.getAddress()))
201 .build();
202 }
203
204 if (type.equals(MULTICAST_ADDRESS.type())) {
205
206 LispMulticastAddress multicastAddress = (LispMulticastAddress) mappingAddress;
207
208 return new LispMulticastLcafAddress.MulticastAddressBuilder()
209 .withInstanceId(multicastAddress.getInstanceId())
210 .withSrcAddress(getAfiAddress(multicastAddress.getSrcAddress()))
211 .withSrcMaskLength(multicastAddress.getSrcMaskLength())
212 .withGrpAddress(getAfiAddress(multicastAddress.getGrpAddress()))
213 .withGrpMaskLength(multicastAddress.getGrpMaskLength())
214 .build();
215 }
216
217 if (type.equals(TRAFFIC_ENGINEERING_ADDRESS.type())) {
218
219 LispTeAddress teAddress = (LispTeAddress) mappingAddress;
220
221 List<LispTeRecord> records = Lists.newArrayList();
222
223 teAddress.getTeRecords().forEach(record -> {
224 LispTeRecord teRecord =
225 new LispTeRecord.TeRecordBuilder()
226 .withIsLookup(record.isLookup())
227 .withIsRlocProbe(record.isRlocProbe())
228 .withIsStrict(record.isStrict())
229 .withRtrRlocAddress(getAfiAddress(
230 record.getAddress()))
231 .build();
232 records.add(teRecord);
233 });
234
235 return new LispTeLcafAddress.TeAddressBuilder()
236 .withTeRecords(records)
237 .build();
238 }
239
240 if (type.equals(SOURCE_DEST_ADDRESS.type())) {
241
242 LispSrcDstAddress srcDstAddress = (LispSrcDstAddress) mappingAddress;
243
244 return new LispSourceDestLcafAddress.SourceDestAddressBuilder()
245 .withSrcPrefix(getAfiAddress(srcDstAddress.getSrcPrefix()))
246 .withSrcMaskLength(srcDstAddress.getSrcMaskLength())
247 .withDstPrefix(getAfiAddress(srcDstAddress.getDstPrefix()))
248 .withDstMaskLength(srcDstAddress.getDstMaskLength())
249 .build();
250 }
251
252 log.error("Unsupported extension mapping address type {}", mappingAddress.type());
253
254 return null;
255 }
256
257 @Override
258 public ExtensionMappingAddress mapLcafAddress(LispLcafAddress lcafAddress) {
259
260 switch (lcafAddress.getType()) {
261 case LIST:
262 LispListLcafAddress lcafListAddress = (LispListLcafAddress) lcafAddress;
263 MappingAddress ipv4Ma =
264 afi2mapping(lcafListAddress.getAddresses().get(0));
265 MappingAddress ipv6Ma =
266 afi2mapping(lcafListAddress.getAddresses().get(1));
267
268 return new LispListAddress.Builder()
269 .withIpv4(ipv4Ma)
270 .withIpv6(ipv6Ma)
271 .build();
272
273 case SEGMENT:
274 LispSegmentLcafAddress segmentLcafAddress =
275 (LispSegmentLcafAddress) lcafAddress;
276
277 return new LispSegmentAddress.Builder()
278 .withInstanceId(segmentLcafAddress.getInstanceId())
279 .withAddress(getMappingAddress(segmentLcafAddress.getAddress()))
280 .build();
281
282 case AS:
283 LispAsLcafAddress asLcafAddress = (LispAsLcafAddress) lcafAddress;
284
285 return new org.onosproject.drivers.lisp.extensions.LispAsAddress.Builder()
286 .withAsNumber(asLcafAddress.getAsNumber())
287 .withAddress(getMappingAddress(asLcafAddress.getAddress()))
288 .build();
289
290 case APPLICATION_DATA:
291
292 LispAppDataLcafAddress appLcafAddress = (LispAppDataLcafAddress) lcafAddress;
293
294 return new LispAppDataAddress.Builder()
295 .withProtocol(appLcafAddress.getProtocol())
296 .withIpTos(appLcafAddress.getIpTos())
297 .withLocalPortLow(appLcafAddress.getLocalPortLow())
298 .withLocalPortHigh(appLcafAddress.getLocalPortHigh())
299 .withRemotePortLow(appLcafAddress.getRemotePortLow())
300 .withRemotePortHigh(appLcafAddress.getRemotePortHigh())
301 .withAddress(getMappingAddress(appLcafAddress.getAddress()))
302 .build();
303
304 case GEO_COORDINATE:
305
306 LispGeoCoordinateLcafAddress gcLcafAddress =
307 (LispGeoCoordinateLcafAddress) lcafAddress;
308
309 return new LispGcAddress.Builder()
310 .withIsNorth(gcLcafAddress.isNorth())
311 .withLatitudeDegree(gcLcafAddress.getLatitudeDegree())
312 .withLatitudeMinute(gcLcafAddress.getLatitudeMinute())
313 .withLatitudeSecond(gcLcafAddress.getLatitudeSecond())
314 .withIsEast(gcLcafAddress.isEast())
315 .withLongitudeDegree(gcLcafAddress.getLongitudeDegree())
316 .withLongitudeMinute(gcLcafAddress.getLongitudeMinute())
317 .withLongitudeSecond(gcLcafAddress.getLongitudeSecond())
318 .withAltitude(gcLcafAddress.getAltitude())
319 .withAddress(getMappingAddress(gcLcafAddress.getAddress()))
320 .build();
321
322 case NAT:
323
324 LispNatLcafAddress natLcafAddress = (LispNatLcafAddress) lcafAddress;
325
326 List<MappingAddress> mas = Lists.newArrayList();
327
328 natLcafAddress.getRtrRlocAddresses()
329 .forEach(rtr -> mas.add(getMappingAddress(rtr)));
330
331 return new LispNatAddress.Builder()
332 .withMsUdpPortNumber(natLcafAddress.getMsUdpPortNumber())
333 .withEtrUdpPortNumber(natLcafAddress.getEtrUdpPortNumber())
334 .withMsRlocAddress(getMappingAddress(natLcafAddress.getMsRlocAddress()))
335 .withGlobalEtrRlocAddress(
336 getMappingAddress(natLcafAddress.getGlobalEtrRlocAddress()))
337 .withPrivateEtrRlocAddress(
338 getMappingAddress(natLcafAddress.getPrivateEtrRlocAddress()))
339 .withRtrRlocAddresses(mas)
340 .build();
341
342 case NONCE:
343
344 LispNonceLcafAddress nonceLcafAddress = (LispNonceLcafAddress) lcafAddress;
345
346 return new LispNonceAddress.Builder()
347 .withNonce(nonceLcafAddress.getNonce())
348 .withAddress(getMappingAddress(nonceLcafAddress.getAddress()))
349 .build();
350
351 case MULTICAST:
352
353 LispMulticastLcafAddress multiLcafAddress =
354 (LispMulticastLcafAddress) lcafAddress;
355
356 return new LispMulticastAddress.Builder()
357 .withInstanceId(multiLcafAddress.getInstanceId())
358 .withSrcAddress(getMappingAddress(multiLcafAddress.getSrcAddress()))
359 .withSrcMaskLength(multiLcafAddress.getSrcMaskLength())
360 .withGrpAddress(getMappingAddress(multiLcafAddress.getGrpAddress()))
361 .withGrpMaskLength(multiLcafAddress.getGrpMaskLength())
362 .build();
363
364 case TRAFFIC_ENGINEERING:
365
366 LispTeLcafAddress teLcafAddress = (LispTeLcafAddress) lcafAddress;
367
368 List<LispTeAddress.TeRecord> records = Lists.newArrayList();
369
370 teLcafAddress.getTeRecords().forEach(record -> {
371 LispTeAddress.TeRecord teRecord =
372 new LispTeAddress.TeRecord.Builder()
373 .withIsLookup(record.isLookup())
374 .withIsRlocProbe(record.isRlocProbe())
375 .withIsStrict(record.isStrict())
376 .withRtrRlocAddress(getMappingAddress(
377 record.getRtrRlocAddress()))
378 .build();
379 records.add(teRecord);
380 });
381
382 return new LispTeAddress.Builder()
383 .withTeRecords(records)
384 .build();
385
386 case SECURITY:
387
388 // TODO: need to implement security type later
389 log.warn("security type will be implemented later");
390
391 return null;
392
393 case SOURCE_DEST:
394
395 LispSourceDestLcafAddress srcDstLcafAddress =
396 (LispSourceDestLcafAddress) lcafAddress;
397
398
399 return new LispSrcDstAddress.Builder()
400 .withSrcPrefix(getMappingAddress(srcDstLcafAddress.getSrcPrefix()))
401 .withSrcMaskLength(srcDstLcafAddress.getSrcMaskLength())
402 .withDstPrefix(getMappingAddress(srcDstLcafAddress.getDstPrefix()))
403 .withDstMaskLength(srcDstLcafAddress.getDstMaskLength())
404 .build();
405
406 case UNSPECIFIED:
407 case UNKNOWN:
408 default:
409 log.error("Unsupported LCAF type {}", lcafAddress.getType());
410 return null;
411 }
412 }
413
414 @Override
415 public ExtensionMappingAddress getExtensionMappingAddress(
416 ExtensionMappingAddressType type) {
417
418 if (type.equals(LIST_ADDRESS.type())) {
419 return new LispListAddress();
420 }
421 if (type.equals(SEGMENT_ADDRESS.type())) {
422 return new LispSegmentAddress();
423 }
424 if (type.equals(AS_ADDRESS.type())) {
425 return new LispAsAddress();
426 }
427 if (type.equals(APPLICATION_DATA_ADDRESS.type())) {
428 return new LispAppDataAddress();
429 }
430 if (type.equals(GEO_COORDINATE_ADDRESS.type())) {
431 return new LispGcAddress();
432 }
433 if (type.equals(NAT_ADDRESS.type())) {
434 return new LispNatAddress();
435 }
436 if (type.equals(NONCE_ADDRESS.type())) {
437 return new LispNonceAddress();
438 }
439 if (type.equals(MULTICAST_ADDRESS.type())) {
440 return new LispMulticastAddress();
441 }
442 if (type.equals(TRAFFIC_ENGINEERING_ADDRESS.type())) {
443 return new LispTeAddress();
444 }
445 if (type.equals(SOURCE_DEST_ADDRESS.type())) {
446 return new LispSrcDstAddress();
447 }
448
449 return null;
450 }
451
452 /**
453 * Converts AFI address to generalized mapping address.
454 *
455 * @param afi IP typed AFI address
456 * @return generalized mapping address
457 */
458 private MappingAddress afi2mapping(LispAfiAddress afi) {
459 switch (afi.getAfi()) {
460 case IP4:
461 IpAddress ipv4Address = ((LispIpv4Address) afi).getAddress();
462 IpPrefix ipv4Prefix = IpPrefix.valueOf(ipv4Address, IPV4_PREFIX_LENGTH);
463 return MappingAddresses.ipv4MappingAddress(ipv4Prefix);
464 case IP6:
465 IpAddress ipv6Address = ((LispIpv6Address) afi).getAddress();
466 IpPrefix ipv6Prefix = IpPrefix.valueOf(ipv6Address, IPV6_PREFIX_LENGTH);
467 return MappingAddresses.ipv6MappingAddress(ipv6Prefix);
468 default:
469 log.warn("Only support to convert IP address type");
470 break;
471 }
472 return null;
473 }
474
475 /**
476 * Converts mapping address to AFI address.
477 *
478 * @param address generalized mapping address
479 * @return IP typed AFI address
480 */
481 private LispAfiAddress mapping2afi(MappingAddress address) {
482 switch (address.type()) {
483 case IPV4:
484 IpPrefix ipv4Prefix = ((IPMappingAddress) address).ip();
485 return new LispIpv4Address(ipv4Prefix.address());
486 case IPV6:
487 IpPrefix ipv6Prefix = ((IPMappingAddress) address).ip();
488 return new LispIpv6Address(ipv6Prefix.address());
489 default:
490 log.warn("Only support to convert IP address type");
491 break;
492 }
493 return null;
494 }
495
496 /**
497 * Converts LispAfiAddress into abstracted mapping address.
498 *
499 * @param address LispAfiAddress
500 * @return abstracted mapping address
501 */
502 private MappingAddress getMappingAddress(LispAfiAddress address) {
503
504 if (address == null) {
505 log.warn("Address is not specified.");
506 return null;
507 }
508
509 switch (address.getAfi()) {
510 case IP4:
511 return afi2mapping(address);
512 case IP6:
513 return afi2mapping(address);
514 case AS:
515 int asNum = ((org.onosproject.lisp.msg.types.LispAsAddress) address).getASNum();
516 return MappingAddresses.asMappingAddress(String.valueOf(asNum));
517 case DISTINGUISHED_NAME:
518 String dn = ((LispDistinguishedNameAddress)
519 address).getDistinguishedName();
520 return MappingAddresses.dnMappingAddress(dn);
521 case MAC:
522 MacAddress macAddress = ((LispMacAddress) address).getAddress();
523 return MappingAddresses.ethMappingAddress(macAddress);
524 case LCAF:
525 LispLcafAddress lcafAddress = (LispLcafAddress) address;
526 return MappingAddresses.extensionMappingAddressWrapper(mapLcafAddress(lcafAddress));
527 default:
528 log.warn("Unsupported address AFI type {}", address.getAfi());
529 break;
530 }
531
532 return null;
533 }
534
535 /**
536 * Converts mapping address into afi address.
537 *
538 * @param address mapping address
539 * @return afi address
540 */
541 private LispAfiAddress getAfiAddress(MappingAddress address) {
542
543 if (address == null) {
544 log.warn("Address is not specified.");
545 return null;
546 }
547
548 switch (address.type()) {
549 case IPV4:
550 return mapping2afi(address);
551 case IPV6:
552 return mapping2afi(address);
553 case AS:
554 int asNum = ((org.onosproject.lisp.msg.types.LispAsAddress) address).getASNum();
555 return new org.onosproject.lisp.msg.types.LispAsAddress(asNum);
556 case DN:
557 String dn = ((LispDistinguishedNameAddress) address).getDistinguishedName();
558 return new LispDistinguishedNameAddress(dn);
559 case ETH:
560 MacAddress macAddress = ((LispMacAddress) address).getAddress();
561 return new LispMacAddress(macAddress);
562 case EXTENSION:
563 ExtensionMappingAddress extAddress = (ExtensionMappingAddress) address;
564 return mapMappingAddress(extAddress);
565 default:
566 log.warn("Unsupported address type {}", address.type());
567 break;
568 }
569
570 return null;
571 }
572}