blob: 1a0ed09e4e59c87815e0e017b71feea12ef3294e [file] [log] [blame]
Jian Li77d6e752017-01-29 23:24:18 +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.provider.lisp.mapping.util;
17
Jian Lib8436bb2017-02-23 03:39:08 +090018import com.google.common.collect.Lists;
19import org.onlab.packet.IpAddress;
20import org.onlab.packet.IpPrefix;
21import org.onlab.packet.MacAddress;
22import org.onosproject.lisp.msg.protocols.LispLocator;
23import org.onosproject.lisp.msg.protocols.LispMapRecord;
24import org.onosproject.lisp.msg.types.LispAfiAddress;
25import org.onosproject.lisp.msg.types.LispAsAddress;
26import org.onosproject.lisp.msg.types.LispDistinguishedNameAddress;
27import org.onosproject.lisp.msg.types.LispIpv4Address;
28import org.onosproject.lisp.msg.types.LispIpv6Address;
29import org.onosproject.lisp.msg.types.LispMacAddress;
Jian Li0f0d7482017-03-20 15:16:13 +090030import org.onosproject.lisp.msg.types.lcaf.LispLcafAddress;
Jian Lib8436bb2017-02-23 03:39:08 +090031import org.onosproject.mapping.DefaultMapping;
32import org.onosproject.mapping.DefaultMappingEntry;
33import org.onosproject.mapping.DefaultMappingKey;
34import org.onosproject.mapping.DefaultMappingTreatment;
35import org.onosproject.mapping.DefaultMappingValue;
36import org.onosproject.mapping.Mapping;
Jian Li77d6e752017-01-29 23:24:18 +090037import org.onosproject.mapping.MappingEntry;
Jian Lib8436bb2017-02-23 03:39:08 +090038import org.onosproject.mapping.MappingEntry.MappingEntryState;
39import org.onosproject.mapping.MappingKey;
40import org.onosproject.mapping.MappingTreatment;
41import org.onosproject.mapping.MappingValue;
42import org.onosproject.mapping.actions.MappingAction;
43import org.onosproject.mapping.actions.MappingActions;
44import org.onosproject.mapping.addresses.MappingAddress;
45import org.onosproject.mapping.addresses.MappingAddresses;
Jian Li77d6e752017-01-29 23:24:18 +090046import org.onosproject.net.DeviceId;
47import org.slf4j.Logger;
48import org.slf4j.LoggerFactory;
49
Jian Lib8436bb2017-02-23 03:39:08 +090050import java.util.List;
51import java.util.UUID;
52
Jian Li77d6e752017-01-29 23:24:18 +090053/**
54 * Mapping entry builder class.
55 */
56public class MappingEntryBuilder {
Jian Lib8436bb2017-02-23 03:39:08 +090057 private static final Logger log =
58 LoggerFactory.getLogger(MappingEntryBuilder.class);
59
60 private static final int IPV4_PREFIX_LENGTH = 32;
61 private static final int IPV6_PREFIX_LENGTH = 128;
Jian Li77d6e752017-01-29 23:24:18 +090062
63 private final DeviceId deviceId;
Jian Lib8436bb2017-02-23 03:39:08 +090064
65 private final MappingAddress address;
66 private final MappingAction action;
67 private final List<MappingTreatment> treatments;
Jian Li77d6e752017-01-29 23:24:18 +090068
69 /**
70 * Default constructor for MappingEntryBuilder.
71 *
72 * @param deviceId device identifier
Jian Lib8436bb2017-02-23 03:39:08 +090073 * @param record LISP map record
Jian Li77d6e752017-01-29 23:24:18 +090074 */
Jian Lib8436bb2017-02-23 03:39:08 +090075 public MappingEntryBuilder(DeviceId deviceId, LispMapRecord record) {
Jian Li77d6e752017-01-29 23:24:18 +090076 this.deviceId = deviceId;
Jian Lib8436bb2017-02-23 03:39:08 +090077 this.address = buildAddress(record);
78 this.action = buildAction(record);
79 this.treatments = buildTreatments(record);
Jian Li77d6e752017-01-29 23:24:18 +090080 }
81
82 /**
Jian Lib8436bb2017-02-23 03:39:08 +090083 * Builds mapping entry from a specific LISP control message.
Jian Li77d6e752017-01-29 23:24:18 +090084 *
Jian Lib8436bb2017-02-23 03:39:08 +090085 * @return mapping entry
Jian Li77d6e752017-01-29 23:24:18 +090086 */
Jian Lib8436bb2017-02-23 03:39:08 +090087 public MappingEntry build() {
88 Mapping.Builder builder;
89
90 // we assign leastSignificantBits of UUID as the mapping identifier for now
91 // id generation scheme can be changed later
92 UUID uuid = UUID.randomUUID();
93
94 builder = DefaultMapping.builder()
95 .withId(uuid.getLeastSignificantBits())
96 .forDevice(deviceId)
97 .withKey(buildKey())
98 .withValue(buildValue());
99
100 // TODO: we assume that the mapping entry will be always
101 // stored in routers without failure for now, which means
102 // the mapping entry state will always be ADDED rather than
103 // PENDING_ADD
104 // we will revisit this part when LISP driver is finished
105 return new DefaultMappingEntry(builder.build(), MappingEntryState.ADDED);
Jian Li77d6e752017-01-29 23:24:18 +0900106 }
107
Jian Lib8436bb2017-02-23 03:39:08 +0900108 /**
109 * Builds mapping key.
110 *
111 * @return mapping key
112 */
113 private MappingKey buildKey() {
114
115 MappingKey.Builder builder = DefaultMappingKey.builder();
116
117 builder.withAddress(address);
118
119 return builder.build();
120 }
121
122 /**
123 * Builds mapping value.
124 *
125 * @return mapping value
126 */
127 private MappingValue buildValue() {
128
129 MappingValue.Builder builder = DefaultMappingValue.builder();
130 builder.withAction(action);
131
132 treatments.forEach(builder::add);
133
134 return builder.build();
135 }
136
137 /**
138 * Builds mapping action.
139 *
140 * @param record LISP map record
141 * @return mapping action
142 */
143 private MappingAction buildAction(LispMapRecord record) {
144
145 if (record == null) {
146 return MappingActions.noAction();
147 }
148
149 switch (record.getAction()) {
150 case NoAction:
151 return MappingActions.noAction();
152 case SendMapRequest:
153 return MappingActions.forward();
154 case NativelyForward:
155 return MappingActions.nativeForward();
156 case Drop:
157 return MappingActions.drop();
158 default:
159 log.warn("Unsupported action type {}", record.getAction());
160 return MappingActions.noAction();
161 }
162 }
163
164 /**
165 * Builds mapping address.
166 *
167 * @param record LISP map record
168 * @return mapping address
169 */
170 private MappingAddress buildAddress(LispMapRecord record) {
171
172 return record == null ? null :
Jian Li0f0d7482017-03-20 15:16:13 +0900173 getAddress(record.getEidPrefixAfi());
Jian Lib8436bb2017-02-23 03:39:08 +0900174 }
175
176 /**
177 * Converts LispAfiAddress into abstracted mapping address.
178 *
179 * @param address LispAfiAddress
Jian Lib8436bb2017-02-23 03:39:08 +0900180 * @return abstracted mapping address
181 */
Jian Li0f0d7482017-03-20 15:16:13 +0900182 private MappingAddress getAddress(LispAfiAddress address) {
Jian Lib8436bb2017-02-23 03:39:08 +0900183
184 if (address == null) {
185 log.warn("Address is not specified.");
186 return null;
187 }
188
189 switch (address.getAfi()) {
190 case IP4:
Jian Li0f0d7482017-03-20 15:16:13 +0900191 return afi2MappingAddress(address);
Jian Lib8436bb2017-02-23 03:39:08 +0900192 case IP6:
Jian Li0f0d7482017-03-20 15:16:13 +0900193 return afi2MappingAddress(address);
Jian Lib8436bb2017-02-23 03:39:08 +0900194 case AS:
195 int asNum = ((LispAsAddress) address).getASNum();
196 return MappingAddresses.asMappingAddress(String.valueOf(asNum));
197 case DISTINGUISHED_NAME:
198 String dn = ((LispDistinguishedNameAddress)
199 address).getDistinguishedName();
200 return MappingAddresses.dnMappingAddress(dn);
201 case MAC:
202 MacAddress macAddress = ((LispMacAddress) address).getAddress();
203 return MappingAddresses.ethMappingAddress(macAddress);
204 case LCAF:
Jian Li0f0d7482017-03-20 15:16:13 +0900205 LispLcafAddress lcafAddress = (LispLcafAddress) address;
206 return lcaf2Extension(lcafAddress);
Jian Lib8436bb2017-02-23 03:39:08 +0900207 default:
208 log.warn("Unsupported address type {}", address.getAfi());
209 break;
210 }
211
Jian Li77d6e752017-01-29 23:24:18 +0900212 return null;
213 }
Jian Lib8436bb2017-02-23 03:39:08 +0900214
215 /**
Jian Li0f0d7482017-03-20 15:16:13 +0900216 * Converts LCAF address to extension mapping address.
217 *
218 * @param lcaf LCAF address
219 * @return extension mapping address
220 */
221 private MappingAddress lcaf2Extension(LispLcafAddress lcaf) {
222
Jian Lib6995cb2017-03-30 23:30:52 +0900223 // TODO: move LCAF to extension mapping to LISP Extension Interpreter
224 return null;
Jian Li0f0d7482017-03-20 15:16:13 +0900225 }
226
227 /**
228 * Converts AFI address to generalized mapping address.
229 *
230 * @param afiAddress IP typed AFI address
231 * @return generalized mapping address
232 */
233 private MappingAddress afi2MappingAddress(LispAfiAddress afiAddress) {
234 switch (afiAddress.getAfi()) {
235 case IP4:
236 IpAddress ipv4Address = ((LispIpv4Address) afiAddress).getAddress();
237 IpPrefix ipv4Prefix = IpPrefix.valueOf(ipv4Address, IPV4_PREFIX_LENGTH);
238 return MappingAddresses.ipv4MappingAddress(ipv4Prefix);
239 case IP6:
240 IpAddress ipv6Address = ((LispIpv6Address) afiAddress).getAddress();
241 IpPrefix ipv6Prefix = IpPrefix.valueOf(ipv6Address, IPV6_PREFIX_LENGTH);
242 return MappingAddresses.ipv6MappingAddress(ipv6Prefix);
243 default:
244 log.warn("Only support to convert IP address type");
245 break;
246 }
247 return null;
248 }
249
250 /**
Jian Lib8436bb2017-02-23 03:39:08 +0900251 * Builds a collection of mapping treatments.
252 *
253 * @param record LISP map record
254 * @return a collection of mapping treatments
255 */
256 private List<MappingTreatment> buildTreatments(LispMapRecord record) {
257
258 List<LispLocator> locators = record.getLocators();
259 List<MappingTreatment> treatments = Lists.newArrayList();
260 for (LispLocator locator : locators) {
261 MappingTreatment.Builder builder = DefaultMappingTreatment.builder();
262 LispAfiAddress address = locator.getLocatorAfi();
Jian Lib8436bb2017-02-23 03:39:08 +0900263
Jian Li0f0d7482017-03-20 15:16:13 +0900264 final MappingAddress mappingAddress = getAddress(address);
Jian Lib8436bb2017-02-23 03:39:08 +0900265 if (mappingAddress != null) {
266 builder.withAddress(mappingAddress);
267 }
268
269 builder.setUnicastWeight(locator.getWeight())
270 .setUnicastPriority(locator.getPriority())
271 .setMulticastWeight(locator.getMulticastWeight())
272 .setMulticastPriority(locator.getMulticastPriority());
273
274 // TODO: need to convert specific properties to
275 // abstracted extension properties
276
277 treatments.add(builder.build());
278 }
279
280 return treatments;
281 }
Jian Li77d6e752017-01-29 23:24:18 +0900282}