2 * Copyright (c) 2016 Cisco Systems, Inc. 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.lispflowmapping.implementation.util;
10 import java.util.ArrayList;
11 import java.util.Date;
12 import java.util.HashMap;
13 import java.util.List;
16 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.SimpleAddress;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.Address;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.source.dest.key.SourceDestKey;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.source.dest.key.SourceDestKeyBuilder;
23 import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
24 import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
25 import org.opendaylight.lispflowmapping.lisp.util.SourceDestKeyHelper;
26 import org.opendaylight.lispflowmapping.implementation.config.ConfigIni;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecord;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecordBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecord;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecordBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.rloc.container.Rloc;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
35 import com.google.common.base.Preconditions;
38 * Utility class to implement merging of locator sets
40 * @author Lorand Jakab
43 public final class MappingMergeUtil {
44 protected static final Logger LOG = LoggerFactory.getLogger(MappingMergeUtil.class);
46 // Utility class, should not be instantiated
47 private MappingMergeUtil() {
50 public static boolean mappingIsExpired(MappingRecord mapping) {
51 Preconditions.checkNotNull(mapping, "mapping should not be null!");
52 if (mapping.getTimestamp() != null) {
53 return timestampIsExpired(mapping.getTimestamp());
58 public static boolean timestampIsExpired(Date timestamp) {
59 Preconditions.checkNotNull(timestamp, "timestamp should not be null!");
60 return timestampIsExpired(timestamp.getTime());
63 public static boolean timestampIsExpired(Long timestamp) {
64 Preconditions.checkNotNull(timestamp, "timestamp should not be null!");
65 if ((System.currentTimeMillis() - timestamp) > ConfigIni.getInstance().getRegistrationValiditySb() ) {
71 public static Object computeNbSbIntersection(MappingRecord nbMapping, MappingRecord sbMapping) {
72 // returns a MappingRecord which has the more specific EID, and intersection of locator records.
73 // If locators intersection is empty, original NB mapping is returned.
74 // The intersection is only computed for mappings with maskable EIDs.
75 // Supports both maskable and non-maskable EIDs
77 MappingRecordBuilder mrb = new MappingRecordBuilder(nbMapping);
79 if (MaskUtil.isMaskable(sbMapping.getEid().getAddress())
80 && MaskUtil.isMaskable(nbMapping.getEid().getAddress())) {
82 short sbMask = MaskUtil.getMaskForAddress(sbMapping.getEid().getAddress());
83 short nbMask = MaskUtil.getMaskForAddress(nbMapping.getEid().getAddress());
85 if (nbMapping.getEid().getAddress() instanceof org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
86 .ietf.lisp.address.types.rev151105.lisp.address.address.SourceDestKey) {
87 nbMask = SourceDestKeyHelper.getDstMask(nbMapping.getEid());
88 if ( nbMask < sbMask) {
89 // We have to create a new SourceDest EID, where the source is same as the
90 // one in NB record, and dest EID is the more specific from SB mapping record.
92 SourceDestKey srcDstKey = ((org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp
93 .address.types.rev151105.lisp.address.address.SourceDestKey) nbMapping.getEid()
94 .getAddress()).getSourceDestKey();
95 SourceDestKeyBuilder sdb = new SourceDestKeyBuilder(srcDstKey);
96 sdb.setDest(new SimpleAddress(getIpPrefix(sbMapping.getEid().getAddress())));
97 mrb.setEid(LispAddressUtil.asSrcDstEid(sdb.build(), nbMapping.getEid().getVirtualNetworkId()));
99 } else if (nbMask < sbMask) {
100 // Both EIDs are IP prefixes. SB mapping is a subprefix so we have to update EID intersection
101 mrb.setEid(sbMapping.getEid());
104 // find and update locators intersection if not empty
105 List<LocatorRecord> commonLocators = getCommonLocatorRecords(nbMapping, sbMapping);
106 if (commonLocators != null && !commonLocators.isEmpty()) {
107 mrb.setLocatorRecord(commonLocators);
113 private static List<LocatorRecord> getCommonLocatorRecords(MappingRecord nbMapping, MappingRecord sbMapping) {
114 // This method updates the MappingRecord builder with the intersection of the locator records
115 // from the two mappings. NB mapping records fields have precedence, only Priority is updated
116 // from SB mapping if p is 255.
118 // Return null when NB is a negative mapping
119 if (nbMapping.getLocatorRecord() == null || nbMapping.getLocatorRecord().isEmpty()) {
123 List<LocatorRecord> sbLocators = sbMapping.getLocatorRecord();
125 // We assume locators are unique and don't show up several times (with different or identical p/w/mp/mw),
126 // so we create a HashMap of the locators from the SB mapping record, keyed by the Rloc
127 Map<Rloc, LocatorRecord> sbLocatorMap = new HashMap<Rloc, LocatorRecord>();
128 for (LocatorRecord locator : sbLocators) {
129 sbLocatorMap.put(locator.getRloc(), locator);
132 // Gradually building final list of common locators, in order that they appear in NB Mapping
133 List<LocatorRecord> commonLocators = new ArrayList<LocatorRecord>();
135 for (LocatorRecord nbLocator : nbMapping.getLocatorRecord()) {
136 Rloc nbRloc = nbLocator.getRloc();
137 if (sbLocatorMap.containsKey(nbRloc)) {
138 // common locator found. use the NB record as the common locator.
140 if (sbLocatorMap.get(nbRloc).getPriority() == (short) 255) {
141 // if SB locator has p == 255 then common locator takes all NB fields except for p
142 // which must be set to 255
143 LocatorRecordBuilder lrb = new LocatorRecordBuilder(nbLocator);
144 lrb.setPriority((short) 255);
145 commonLocators.add(lrb.build());
147 commonLocators.add(nbLocator);
151 return commonLocators;
154 private static IpPrefix getIpPrefix(Address address) {
155 IpPrefix ipPrefix = null;
157 if (address instanceof org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns
158 .yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4Prefix) {
159 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp
160 .address.address.Ipv4Prefix lispPrefix = (org.opendaylight.yang.gen.v1.urn.ietf.params
161 .xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4Prefix) address;
163 Ipv4Prefix inetPrefix = new Ipv4Prefix(lispPrefix.getIpv4Prefix());
164 ipPrefix = new IpPrefix(inetPrefix);
165 } else if (address instanceof org.opendaylight.yang.gen.v1.urn.ietf.params
166 .xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv6Prefix) {
167 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp
168 .address.address.Ipv6Prefix lispPrefix = (org.opendaylight.yang.gen.v1.urn.ietf.params
169 .xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv6Prefix) address;
171 Ipv6Prefix inetPrefix = new Ipv6Prefix(lispPrefix.getIpv6Prefix());
172 ipPrefix = new IpPrefix(inetPrefix);
174 LOG.warn("Southbound mapping address is not an IpPrefix");