| /* |
| * Copyright 2017-present Open Networking Foundation |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.onosproject.drivers.lisp.extensions; |
| |
| import com.fasterxml.jackson.databind.JsonNode; |
| import com.fasterxml.jackson.databind.node.ObjectNode; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.Lists; |
| import org.onlab.packet.IpAddress; |
| import org.onlab.packet.IpPrefix; |
| import org.onlab.packet.MacAddress; |
| import org.onosproject.codec.CodecContext; |
| import org.onosproject.lisp.ctl.ExtensionMappingAddressInterpreter; |
| import org.onosproject.lisp.msg.types.LispAfiAddress; |
| import org.onosproject.lisp.msg.types.LispDistinguishedNameAddress; |
| import org.onosproject.lisp.msg.types.LispIpv4Address; |
| import org.onosproject.lisp.msg.types.LispIpv6Address; |
| import org.onosproject.lisp.msg.types.LispMacAddress; |
| import org.onosproject.lisp.msg.types.lcaf.LispAppDataLcafAddress; |
| import org.onosproject.lisp.msg.types.lcaf.LispAsLcafAddress; |
| import org.onosproject.lisp.msg.types.lcaf.LispGeoCoordinateLcafAddress; |
| import org.onosproject.lisp.msg.types.lcaf.LispLcafAddress; |
| import org.onosproject.lisp.msg.types.lcaf.LispListLcafAddress; |
| import org.onosproject.lisp.msg.types.lcaf.LispMulticastLcafAddress; |
| import org.onosproject.lisp.msg.types.lcaf.LispNatLcafAddress; |
| import org.onosproject.lisp.msg.types.lcaf.LispNonceLcafAddress; |
| import org.onosproject.lisp.msg.types.lcaf.LispSegmentLcafAddress; |
| import org.onosproject.lisp.msg.types.lcaf.LispSourceDestLcafAddress; |
| import org.onosproject.lisp.msg.types.lcaf.LispTeLcafAddress; |
| import org.onosproject.lisp.msg.types.lcaf.LispTeRecord; |
| import org.onosproject.mapping.addresses.ExtensionMappingAddress; |
| import org.onosproject.mapping.addresses.ExtensionMappingAddressResolver; |
| import org.onosproject.mapping.addresses.ExtensionMappingAddressType; |
| import org.onosproject.mapping.addresses.IPMappingAddress; |
| import org.onosproject.mapping.addresses.MappingAddress; |
| import org.onosproject.mapping.addresses.MappingAddresses; |
| import org.onosproject.net.driver.AbstractHandlerBehaviour; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.util.List; |
| |
| import static com.google.common.base.Preconditions.checkNotNull; |
| import static org.onlab.util.Tools.nullIsIllegal; |
| import static org.onosproject.mapping.addresses.ExtensionMappingAddressType.ExtensionMappingAddressTypes.*; |
| /** |
| * Interpreter for mapping address extension. |
| */ |
| public class LispExtensionMappingAddressInterpreter extends AbstractHandlerBehaviour |
| implements ExtensionMappingAddressInterpreter, ExtensionMappingAddressResolver { |
| |
| private static final Logger log = LoggerFactory.getLogger( |
| LispExtensionMappingAddressInterpreter.class); |
| |
| private static final int IPV4_PREFIX_LENGTH = 32; |
| private static final int IPV6_PREFIX_LENGTH = 128; |
| |
| protected static final String LISP_LIST_ADDRESS = "listAddress"; |
| protected static final String LISP_SEGMENT_ADDRESS = "segmentAddress"; |
| protected static final String LISP_AS_ADDRESS = "asAddress"; |
| protected static final String LISP_APPLICATION_DATA_ADDRESS = "applicationDataAddress"; |
| protected static final String LISP_GEO_COORDINATE_ADDRESS = "geoCoordinateAddress"; |
| protected static final String LISP_NAT_ADDRESS = "natAddress"; |
| protected static final String LISP_NONCE_ADDRESS = "nonceAddress"; |
| protected static final String LISP_MULTICAST_ADDRESS = "multicastAddress"; |
| protected static final String LISP_TRAFFIC_ENGINEERING_ADDRESS = "trafficEngineeringAddress"; |
| protected static final String LISP_SOURCE_DEST_ADDRESS = "sourceDestAddress"; |
| |
| private static final String TYPE = "type"; |
| |
| private static final String MISSING_MEMBER_MESSAGE = |
| " member is required in LispExtensionMappingAddressInterpreter"; |
| |
| @Override |
| public boolean supported(ExtensionMappingAddressType type) { |
| |
| if (type.equals(LIST_ADDRESS.type())) { |
| return true; |
| } |
| if (type.equals(SEGMENT_ADDRESS.type())) { |
| return true; |
| } |
| if (type.equals(AS_ADDRESS.type())) { |
| return true; |
| } |
| if (type.equals(APPLICATION_DATA_ADDRESS.type())) { |
| return true; |
| } |
| if (type.equals(GEO_COORDINATE_ADDRESS.type())) { |
| return true; |
| } |
| if (type.equals(NAT_ADDRESS.type())) { |
| return true; |
| } |
| if (type.equals(NONCE_ADDRESS.type())) { |
| return true; |
| } |
| if (type.equals(MULTICAST_ADDRESS.type())) { |
| return true; |
| } |
| if (type.equals(TRAFFIC_ENGINEERING_ADDRESS.type())) { |
| return true; |
| } |
| if (type.equals(SOURCE_DEST_ADDRESS.type())) { |
| return true; |
| } |
| |
| return false; |
| } |
| |
| @Override |
| public LispLcafAddress mapMappingAddress(ExtensionMappingAddress mappingAddress) { |
| ExtensionMappingAddressType type = mappingAddress.type(); |
| |
| if (type.equals(LIST_ADDRESS.type())) { |
| |
| LispListAddress listAddress = (LispListAddress) mappingAddress; |
| LispAfiAddress ipv4 = mapping2afi(listAddress.getIpv4()); |
| LispAfiAddress ipv6 = mapping2afi(listAddress.getIpv6()); |
| |
| if (ipv4 != null && ipv6 != null) { |
| return new LispListLcafAddress(ImmutableList.of(ipv4, ipv6)); |
| } else { |
| return new LispListLcafAddress(ImmutableList.of()); |
| } |
| } |
| |
| if (type.equals(SEGMENT_ADDRESS.type())) { |
| |
| LispSegmentAddress segmentAddress = (LispSegmentAddress) mappingAddress; |
| |
| return new LispSegmentLcafAddress.SegmentAddressBuilder() |
| .withInstanceId(segmentAddress.getInstanceId()) |
| .withAddress(getAfiAddress(segmentAddress.getAddress())) |
| .build(); |
| } |
| |
| if (type.equals(AS_ADDRESS.type())) { |
| |
| LispAsAddress asAddress = (LispAsAddress) mappingAddress; |
| |
| return new LispAsLcafAddress.AsAddressBuilder() |
| .withAsNumber(asAddress.getAsNumber()) |
| .withAddress(getAfiAddress(asAddress.getAddress())) |
| .build(); |
| } |
| |
| if (type.equals(APPLICATION_DATA_ADDRESS.type())) { |
| |
| LispAppDataAddress appDataAddress = (LispAppDataAddress) mappingAddress; |
| |
| return new LispAppDataLcafAddress.AppDataAddressBuilder() |
| .withProtocol(appDataAddress.getProtocol()) |
| .withIpTos(appDataAddress.getIpTos()) |
| .withLocalPortLow(appDataAddress.getLocalPortLow()) |
| .withLocalPortHigh(appDataAddress.getLocalPortHigh()) |
| .withRemotePortLow(appDataAddress.getRemotePortLow()) |
| .withRemotePortHigh(appDataAddress.getRemotePortHigh()) |
| .withAddress(getAfiAddress(appDataAddress.getAddress())) |
| .build(); |
| } |
| |
| if (type.equals(GEO_COORDINATE_ADDRESS.type())) { |
| |
| LispGcAddress gcAddress = (LispGcAddress) mappingAddress; |
| |
| return new LispGeoCoordinateLcafAddress.GeoCoordinateAddressBuilder() |
| .withIsNorth(gcAddress.isNorth()) |
| .withLatitudeDegree(gcAddress.getLatitudeDegree()) |
| .withLatitudeMinute(gcAddress.getLatitudeMinute()) |
| .withLatitudeSecond(gcAddress.getLatitudeSecond()) |
| .withIsEast(gcAddress.isEast()) |
| .withLongitudeDegree(gcAddress.getLongitudeDegree()) |
| .withLongitudeMinute(gcAddress.getLongitudeMinute()) |
| .withLongitudeSecond(gcAddress.getLongitudeSecond()) |
| .withAltitude(gcAddress.getAltitude()) |
| .withAddress(getAfiAddress(gcAddress.getAddress())) |
| .build(); |
| } |
| |
| if (type.equals(NAT_ADDRESS.type())) { |
| |
| LispNatAddress natAddress = (LispNatAddress) mappingAddress; |
| |
| List<LispAfiAddress> aas = Lists.newArrayList(); |
| |
| natAddress.getRtrRlocAddresses() |
| .forEach(rtr -> aas.add(getAfiAddress(rtr))); |
| |
| return new LispNatLcafAddress.NatAddressBuilder() |
| .withMsUdpPortNumber(natAddress.getMsUdpPortNumber()) |
| .withEtrUdpPortNumber(natAddress.getEtrUdpPortNumber()) |
| .withMsRlocAddress(getAfiAddress(natAddress.getMsRlocAddress())) |
| .withGlobalEtrRlocAddress( |
| getAfiAddress(natAddress.getGlobalEtrRlocAddress())) |
| .withPrivateEtrRlocAddress( |
| getAfiAddress(natAddress.getPrivateEtrRlocAddress())) |
| .withRtrRlocAddresses(aas) |
| .build(); |
| } |
| |
| if (type.equals(NONCE_ADDRESS.type())) { |
| |
| LispNonceAddress nonceAddress = (LispNonceAddress) mappingAddress; |
| |
| return new LispNonceLcafAddress.NonceAddressBuilder() |
| .withNonce(nonceAddress.getNonce()) |
| .withAddress(getAfiAddress(nonceAddress.getAddress())) |
| .build(); |
| } |
| |
| if (type.equals(MULTICAST_ADDRESS.type())) { |
| |
| LispMulticastAddress multicastAddress = (LispMulticastAddress) mappingAddress; |
| |
| return new LispMulticastLcafAddress.MulticastAddressBuilder() |
| .withInstanceId(multicastAddress.getInstanceId()) |
| .withSrcAddress(getAfiAddress(multicastAddress.getSrcAddress())) |
| .withSrcMaskLength(multicastAddress.getSrcMaskLength()) |
| .withGrpAddress(getAfiAddress(multicastAddress.getGrpAddress())) |
| .withGrpMaskLength(multicastAddress.getGrpMaskLength()) |
| .build(); |
| } |
| |
| if (type.equals(TRAFFIC_ENGINEERING_ADDRESS.type())) { |
| |
| LispTeAddress teAddress = (LispTeAddress) mappingAddress; |
| |
| List<LispTeRecord> records = Lists.newArrayList(); |
| |
| teAddress.getTeRecords().forEach(record -> { |
| LispTeRecord teRecord = |
| new LispTeRecord.TeRecordBuilder() |
| .withIsLookup(record.isLookup()) |
| .withIsRlocProbe(record.isRlocProbe()) |
| .withIsStrict(record.isStrict()) |
| .withRtrRlocAddress(getAfiAddress( |
| record.getAddress())) |
| .build(); |
| records.add(teRecord); |
| }); |
| |
| return new LispTeLcafAddress.TeAddressBuilder() |
| .withTeRecords(records) |
| .build(); |
| } |
| |
| if (type.equals(SOURCE_DEST_ADDRESS.type())) { |
| |
| LispSrcDstAddress srcDstAddress = (LispSrcDstAddress) mappingAddress; |
| |
| return new LispSourceDestLcafAddress.SourceDestAddressBuilder() |
| .withSrcPrefix(getAfiAddress(srcDstAddress.getSrcPrefix())) |
| .withSrcMaskLength(srcDstAddress.getSrcMaskLength()) |
| .withDstPrefix(getAfiAddress(srcDstAddress.getDstPrefix())) |
| .withDstMaskLength(srcDstAddress.getDstMaskLength()) |
| .build(); |
| } |
| |
| log.error("Unsupported extension mapping address type {}", mappingAddress.type()); |
| |
| return null; |
| } |
| |
| @Override |
| public ExtensionMappingAddress mapLcafAddress(LispLcafAddress lcafAddress) { |
| |
| switch (lcafAddress.getType()) { |
| case LIST: |
| LispListLcafAddress lcafListAddress = (LispListLcafAddress) lcafAddress; |
| MappingAddress ipv4Ma = |
| afi2mapping(lcafListAddress.getAddresses().get(0)); |
| MappingAddress ipv6Ma = |
| afi2mapping(lcafListAddress.getAddresses().get(1)); |
| |
| return new LispListAddress.Builder() |
| .withIpv4(ipv4Ma) |
| .withIpv6(ipv6Ma) |
| .build(); |
| |
| case SEGMENT: |
| LispSegmentLcafAddress segmentLcafAddress = |
| (LispSegmentLcafAddress) lcafAddress; |
| |
| return new LispSegmentAddress.Builder() |
| .withInstanceId(segmentLcafAddress.getInstanceId()) |
| .withAddress(getMappingAddress(segmentLcafAddress.getAddress())) |
| .build(); |
| |
| case AS: |
| LispAsLcafAddress asLcafAddress = (LispAsLcafAddress) lcafAddress; |
| |
| return new org.onosproject.drivers.lisp.extensions.LispAsAddress.Builder() |
| .withAsNumber(asLcafAddress.getAsNumber()) |
| .withAddress(getMappingAddress(asLcafAddress.getAddress())) |
| .build(); |
| |
| case APPLICATION_DATA: |
| |
| LispAppDataLcafAddress appLcafAddress = (LispAppDataLcafAddress) lcafAddress; |
| |
| return new LispAppDataAddress.Builder() |
| .withProtocol(appLcafAddress.getProtocol()) |
| .withIpTos(appLcafAddress.getIpTos()) |
| .withLocalPortLow(appLcafAddress.getLocalPortLow()) |
| .withLocalPortHigh(appLcafAddress.getLocalPortHigh()) |
| .withRemotePortLow(appLcafAddress.getRemotePortLow()) |
| .withRemotePortHigh(appLcafAddress.getRemotePortHigh()) |
| .withAddress(getMappingAddress(appLcafAddress.getAddress())) |
| .build(); |
| |
| case GEO_COORDINATE: |
| |
| LispGeoCoordinateLcafAddress gcLcafAddress = |
| (LispGeoCoordinateLcafAddress) lcafAddress; |
| |
| return new LispGcAddress.Builder() |
| .withIsNorth(gcLcafAddress.isNorth()) |
| .withLatitudeDegree(gcLcafAddress.getLatitudeDegree()) |
| .withLatitudeMinute(gcLcafAddress.getLatitudeMinute()) |
| .withLatitudeSecond(gcLcafAddress.getLatitudeSecond()) |
| .withIsEast(gcLcafAddress.isEast()) |
| .withLongitudeDegree(gcLcafAddress.getLongitudeDegree()) |
| .withLongitudeMinute(gcLcafAddress.getLongitudeMinute()) |
| .withLongitudeSecond(gcLcafAddress.getLongitudeSecond()) |
| .withAltitude(gcLcafAddress.getAltitude()) |
| .withAddress(getMappingAddress(gcLcafAddress.getAddress())) |
| .build(); |
| |
| case NAT: |
| |
| LispNatLcafAddress natLcafAddress = (LispNatLcafAddress) lcafAddress; |
| |
| List<MappingAddress> mas = Lists.newArrayList(); |
| |
| natLcafAddress.getRtrRlocAddresses() |
| .forEach(rtr -> mas.add(getMappingAddress(rtr))); |
| |
| return new LispNatAddress.Builder() |
| .withMsUdpPortNumber(natLcafAddress.getMsUdpPortNumber()) |
| .withEtrUdpPortNumber(natLcafAddress.getEtrUdpPortNumber()) |
| .withMsRlocAddress(getMappingAddress(natLcafAddress.getMsRlocAddress())) |
| .withGlobalEtrRlocAddress( |
| getMappingAddress(natLcafAddress.getGlobalEtrRlocAddress())) |
| .withPrivateEtrRlocAddress( |
| getMappingAddress(natLcafAddress.getPrivateEtrRlocAddress())) |
| .withRtrRlocAddresses(mas) |
| .build(); |
| |
| case NONCE: |
| |
| LispNonceLcafAddress nonceLcafAddress = (LispNonceLcafAddress) lcafAddress; |
| |
| return new LispNonceAddress.Builder() |
| .withNonce(nonceLcafAddress.getNonce()) |
| .withAddress(getMappingAddress(nonceLcafAddress.getAddress())) |
| .build(); |
| |
| case MULTICAST: |
| |
| LispMulticastLcafAddress multiLcafAddress = |
| (LispMulticastLcafAddress) lcafAddress; |
| |
| return new LispMulticastAddress.Builder() |
| .withInstanceId(multiLcafAddress.getInstanceId()) |
| .withSrcAddress(getMappingAddress(multiLcafAddress.getSrcAddress())) |
| .withSrcMaskLength(multiLcafAddress.getSrcMaskLength()) |
| .withGrpAddress(getMappingAddress(multiLcafAddress.getGrpAddress())) |
| .withGrpMaskLength(multiLcafAddress.getGrpMaskLength()) |
| .build(); |
| |
| case TRAFFIC_ENGINEERING: |
| |
| LispTeLcafAddress teLcafAddress = (LispTeLcafAddress) lcafAddress; |
| |
| List<LispTeAddress.TeRecord> records = Lists.newArrayList(); |
| |
| teLcafAddress.getTeRecords().forEach(record -> { |
| LispTeAddress.TeRecord teRecord = |
| new LispTeAddress.TeRecord.Builder() |
| .withIsLookup(record.isLookup()) |
| .withIsRlocProbe(record.isRlocProbe()) |
| .withIsStrict(record.isStrict()) |
| .withRtrRlocAddress(getMappingAddress( |
| record.getRtrRlocAddress())) |
| .build(); |
| records.add(teRecord); |
| }); |
| |
| return new LispTeAddress.Builder() |
| .withTeRecords(records) |
| .build(); |
| |
| case SECURITY: |
| |
| // TODO: need to implement security type later |
| log.warn("security type will be implemented later"); |
| |
| return null; |
| |
| case SOURCE_DEST: |
| |
| LispSourceDestLcafAddress srcDstLcafAddress = |
| (LispSourceDestLcafAddress) lcafAddress; |
| |
| |
| return new LispSrcDstAddress.Builder() |
| .withSrcPrefix(getMappingAddress(srcDstLcafAddress.getSrcPrefix())) |
| .withSrcMaskLength(srcDstLcafAddress.getSrcMaskLength()) |
| .withDstPrefix(getMappingAddress(srcDstLcafAddress.getDstPrefix())) |
| .withDstMaskLength(srcDstLcafAddress.getDstMaskLength()) |
| .build(); |
| |
| case UNSPECIFIED: |
| case UNKNOWN: |
| default: |
| log.error("Unsupported LCAF type {}", lcafAddress.getType()); |
| return null; |
| } |
| } |
| |
| @Override |
| public ExtensionMappingAddress getExtensionMappingAddress( |
| ExtensionMappingAddressType type) { |
| |
| if (type.equals(LIST_ADDRESS.type())) { |
| return new LispListAddress(); |
| } |
| if (type.equals(SEGMENT_ADDRESS.type())) { |
| return new LispSegmentAddress(); |
| } |
| if (type.equals(AS_ADDRESS.type())) { |
| return new LispAsAddress(); |
| } |
| if (type.equals(APPLICATION_DATA_ADDRESS.type())) { |
| return new LispAppDataAddress(); |
| } |
| if (type.equals(GEO_COORDINATE_ADDRESS.type())) { |
| return new LispGcAddress(); |
| } |
| if (type.equals(NAT_ADDRESS.type())) { |
| return new LispNatAddress(); |
| } |
| if (type.equals(NONCE_ADDRESS.type())) { |
| return new LispNonceAddress(); |
| } |
| if (type.equals(MULTICAST_ADDRESS.type())) { |
| return new LispMulticastAddress(); |
| } |
| if (type.equals(TRAFFIC_ENGINEERING_ADDRESS.type())) { |
| return new LispTeAddress(); |
| } |
| if (type.equals(SOURCE_DEST_ADDRESS.type())) { |
| return new LispSrcDstAddress(); |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Converts AFI address to generalized mapping address. |
| * |
| * @param afi IP typed AFI address |
| * @return generalized mapping address |
| */ |
| private MappingAddress afi2mapping(LispAfiAddress afi) { |
| switch (afi.getAfi()) { |
| case IP4: |
| IpAddress ipv4Address = ((LispIpv4Address) afi).getAddress(); |
| IpPrefix ipv4Prefix = IpPrefix.valueOf(ipv4Address, IPV4_PREFIX_LENGTH); |
| return MappingAddresses.ipv4MappingAddress(ipv4Prefix); |
| case IP6: |
| IpAddress ipv6Address = ((LispIpv6Address) afi).getAddress(); |
| IpPrefix ipv6Prefix = IpPrefix.valueOf(ipv6Address, IPV6_PREFIX_LENGTH); |
| return MappingAddresses.ipv6MappingAddress(ipv6Prefix); |
| default: |
| log.warn("Only support to convert IP address type"); |
| break; |
| } |
| return null; |
| } |
| |
| /** |
| * Converts mapping address to AFI address. |
| * |
| * @param address generalized mapping address |
| * @return IP typed AFI address |
| */ |
| private LispAfiAddress mapping2afi(MappingAddress address) { |
| switch (address.type()) { |
| case IPV4: |
| IpPrefix ipv4Prefix = ((IPMappingAddress) address).ip(); |
| return new LispIpv4Address(ipv4Prefix.address()); |
| case IPV6: |
| IpPrefix ipv6Prefix = ((IPMappingAddress) address).ip(); |
| return new LispIpv6Address(ipv6Prefix.address()); |
| default: |
| log.warn("Only support to convert IP address type"); |
| break; |
| } |
| return null; |
| } |
| |
| /** |
| * Converts LispAfiAddress into abstracted mapping address. |
| * |
| * @param address LispAfiAddress |
| * @return abstracted mapping address |
| */ |
| private MappingAddress getMappingAddress(LispAfiAddress address) { |
| |
| if (address == null) { |
| log.warn("Address is not specified."); |
| return null; |
| } |
| |
| switch (address.getAfi()) { |
| case IP4: |
| return afi2mapping(address); |
| case IP6: |
| return afi2mapping(address); |
| case AS: |
| int asNum = ((org.onosproject.lisp.msg.types.LispAsAddress) address).getASNum(); |
| return MappingAddresses.asMappingAddress(String.valueOf(asNum)); |
| case DISTINGUISHED_NAME: |
| String dn = ((LispDistinguishedNameAddress) |
| address).getDistinguishedName(); |
| return MappingAddresses.dnMappingAddress(dn); |
| case MAC: |
| MacAddress macAddress = ((LispMacAddress) address).getAddress(); |
| return MappingAddresses.ethMappingAddress(macAddress); |
| case LCAF: |
| LispLcafAddress lcafAddress = (LispLcafAddress) address; |
| return MappingAddresses.extensionMappingAddressWrapper(mapLcafAddress(lcafAddress)); |
| default: |
| log.warn("Unsupported address AFI type {}", address.getAfi()); |
| break; |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Converts mapping address into afi address. |
| * |
| * @param address mapping address |
| * @return afi address |
| */ |
| private LispAfiAddress getAfiAddress(MappingAddress address) { |
| |
| if (address == null) { |
| log.warn("Address is not specified."); |
| return null; |
| } |
| |
| switch (address.type()) { |
| case IPV4: |
| return mapping2afi(address); |
| case IPV6: |
| return mapping2afi(address); |
| case AS: |
| int asNum = ((org.onosproject.lisp.msg.types.LispAsAddress) address).getASNum(); |
| return new org.onosproject.lisp.msg.types.LispAsAddress(asNum); |
| case DN: |
| String dn = ((LispDistinguishedNameAddress) address).getDistinguishedName(); |
| return new LispDistinguishedNameAddress(dn); |
| case ETH: |
| MacAddress macAddress = ((LispMacAddress) address).getAddress(); |
| return new LispMacAddress(macAddress); |
| case EXTENSION: |
| ExtensionMappingAddress extAddress = (ExtensionMappingAddress) address; |
| return mapMappingAddress(extAddress); |
| default: |
| log.warn("Unsupported address type {}", address.type()); |
| break; |
| } |
| |
| return null; |
| } |
| |
| @Override |
| public ObjectNode encode(ExtensionMappingAddress mappingAddress, CodecContext context) { |
| checkNotNull(mappingAddress, "Extension mapping address cannot be null"); |
| ExtensionMappingAddressType type = mappingAddress.type(); |
| ObjectNode root = context.mapper().createObjectNode(); |
| |
| if (type.equals(LIST_ADDRESS.type())) { |
| LispListAddress listAddress = (LispListAddress) mappingAddress; |
| root.set(LISP_LIST_ADDRESS, |
| context.codec(LispListAddress.class).encode(listAddress, context)); |
| } |
| if (type.equals(SEGMENT_ADDRESS.type())) { |
| LispSegmentAddress segmentAddress = (LispSegmentAddress) mappingAddress; |
| root.set(LISP_SEGMENT_ADDRESS, |
| context.codec(LispSegmentAddress.class).encode(segmentAddress, context)); |
| } |
| if (type.equals(AS_ADDRESS.type())) { |
| LispAsAddress asAddress = (LispAsAddress) mappingAddress; |
| root.set(LISP_AS_ADDRESS, |
| context.codec(LispAsAddress.class).encode(asAddress, context)); |
| } |
| if (type.equals(APPLICATION_DATA_ADDRESS.type())) { |
| LispAppDataAddress appDataAddress = (LispAppDataAddress) mappingAddress; |
| root.set(LISP_APPLICATION_DATA_ADDRESS, |
| context.codec(LispAppDataAddress.class).encode(appDataAddress, context)); |
| } |
| if (type.equals(GEO_COORDINATE_ADDRESS.type())) { |
| LispGcAddress gcAddress = (LispGcAddress) mappingAddress; |
| root.set(LISP_GEO_COORDINATE_ADDRESS, |
| context.codec(LispGcAddress.class).encode(gcAddress, context)); |
| } |
| if (type.equals(NAT_ADDRESS.type())) { |
| LispNatAddress natAddress = (LispNatAddress) mappingAddress; |
| root.set(LISP_NAT_ADDRESS, |
| context.codec(LispNatAddress.class).encode(natAddress, context)); |
| } |
| if (type.equals(NONCE_ADDRESS.type())) { |
| LispNonceAddress nonceAddress = (LispNonceAddress) mappingAddress; |
| root.set(LISP_NONCE_ADDRESS, context.codec(LispNonceAddress.class).encode(nonceAddress, context)); |
| } |
| if (type.equals(MULTICAST_ADDRESS.type())) { |
| LispMulticastAddress multicastAddress = (LispMulticastAddress) mappingAddress; |
| root.set(LISP_MULTICAST_ADDRESS, |
| context.codec(LispMulticastAddress.class).encode(multicastAddress, context)); |
| } |
| if (type.equals(TRAFFIC_ENGINEERING_ADDRESS.type())) { |
| LispTeAddress teAddress = (LispTeAddress) mappingAddress; |
| root.set(LISP_TRAFFIC_ENGINEERING_ADDRESS, |
| context.codec(LispTeAddress.class).encode(teAddress, context)); |
| } |
| if (type.equals(SOURCE_DEST_ADDRESS.type())) { |
| LispSrcDstAddress srcDstAddress = (LispSrcDstAddress) mappingAddress; |
| root.set(LISP_SOURCE_DEST_ADDRESS, |
| context.codec(LispSrcDstAddress.class).encode(srcDstAddress, context)); |
| } |
| |
| return root; |
| } |
| |
| @Override |
| public ExtensionMappingAddress decode(ObjectNode json, CodecContext context) { |
| if (json == null || !json.isObject()) { |
| return null; |
| } |
| |
| // parse extension type |
| String typeString = nullIsIllegal(json.get(TYPE), |
| TYPE + MISSING_MEMBER_MESSAGE).asText(); |
| |
| if (typeString.equals(LIST_ADDRESS.name())) { |
| return context.codec(LispListAddress.class) |
| .decode(get(json, LISP_LIST_ADDRESS), context); |
| } |
| if (typeString.equals(SEGMENT_ADDRESS.name())) { |
| return context.codec(LispSegmentAddress.class) |
| .decode(get(json, LISP_SEGMENT_ADDRESS), context); |
| } |
| if (typeString.equals(AS_ADDRESS.name())) { |
| return context.codec(LispAsAddress.class) |
| .decode(get(json, LISP_AS_ADDRESS), context); |
| } |
| if (typeString.equals(APPLICATION_DATA_ADDRESS.name())) { |
| return context.codec(LispAppDataAddress.class) |
| .decode(get(json, LISP_APPLICATION_DATA_ADDRESS), context); |
| } |
| if (typeString.equals(GEO_COORDINATE_ADDRESS.name())) { |
| return context.codec(LispGcAddress.class) |
| .decode(get(json, LISP_GEO_COORDINATE_ADDRESS), context); |
| } |
| if (typeString.equals(NAT_ADDRESS.name())) { |
| return context.codec(LispNatAddress.class) |
| .decode(get(json, LISP_NAT_ADDRESS), context); |
| } |
| if (typeString.equals(NONCE_ADDRESS.name())) { |
| return context.codec(LispNonceAddress.class) |
| .decode(get(json, LISP_NONCE_ADDRESS), context); |
| } |
| if (typeString.equals(MULTICAST_ADDRESS.name())) { |
| return context.codec(LispMulticastAddress.class) |
| .decode(get(json, LISP_MULTICAST_ADDRESS), context); |
| } |
| if (typeString.equals(TRAFFIC_ENGINEERING_ADDRESS.name())) { |
| return context.codec(LispTeAddress.class) |
| .decode(get(json, LISP_TRAFFIC_ENGINEERING_ADDRESS), context); |
| } |
| if (typeString.equals(SOURCE_DEST_ADDRESS.name())) { |
| return context.codec(LispSrcDstAddress.class) |
| .decode(get(json, LISP_SOURCE_DEST_ADDRESS), context); |
| } |
| |
| throw new UnsupportedOperationException( |
| "Driver does not support extension type " + typeString); |
| } |
| |
| /** |
| * Gets a child Object Node from a parent by name. If the child is not found |
| * or does nor represent an object, null is returned. |
| * |
| * @param parent parent object |
| * @param childName name of child to query |
| * @return child object if found, null if not found or if not an object |
| */ |
| private static ObjectNode get(ObjectNode parent, String childName) { |
| JsonNode node = parent.path(childName); |
| return node.isObject() && !node.isNull() ? (ObjectNode) node : null; |
| } |
| } |