blob: 90052c28ce22103460d3ab1378e1e7b352fa8305 [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;
30import org.onosproject.mapping.DefaultMapping;
31import org.onosproject.mapping.DefaultMappingEntry;
32import org.onosproject.mapping.DefaultMappingKey;
33import org.onosproject.mapping.DefaultMappingTreatment;
34import org.onosproject.mapping.DefaultMappingValue;
35import org.onosproject.mapping.Mapping;
Jian Li77d6e752017-01-29 23:24:18 +090036import org.onosproject.mapping.MappingEntry;
Jian Lib8436bb2017-02-23 03:39:08 +090037import org.onosproject.mapping.MappingEntry.MappingEntryState;
38import org.onosproject.mapping.MappingKey;
39import org.onosproject.mapping.MappingTreatment;
40import org.onosproject.mapping.MappingValue;
41import org.onosproject.mapping.actions.MappingAction;
42import org.onosproject.mapping.actions.MappingActions;
43import org.onosproject.mapping.addresses.MappingAddress;
44import org.onosproject.mapping.addresses.MappingAddresses;
Jian Li77d6e752017-01-29 23:24:18 +090045import org.onosproject.net.DeviceId;
46import org.slf4j.Logger;
47import org.slf4j.LoggerFactory;
48
Jian Lib8436bb2017-02-23 03:39:08 +090049import java.util.List;
50import java.util.UUID;
51
52import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.IP4;
53import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.IP6;
54
Jian Li77d6e752017-01-29 23:24:18 +090055/**
56 * Mapping entry builder class.
57 */
58public class MappingEntryBuilder {
Jian Lib8436bb2017-02-23 03:39:08 +090059 private static final Logger log =
60 LoggerFactory.getLogger(MappingEntryBuilder.class);
61
62 private static final int IPV4_PREFIX_LENGTH = 32;
63 private static final int IPV6_PREFIX_LENGTH = 128;
Jian Li77d6e752017-01-29 23:24:18 +090064
65 private final DeviceId deviceId;
Jian Lib8436bb2017-02-23 03:39:08 +090066
67 private final MappingAddress address;
68 private final MappingAction action;
69 private final List<MappingTreatment> treatments;
Jian Li77d6e752017-01-29 23:24:18 +090070
71 /**
72 * Default constructor for MappingEntryBuilder.
73 *
74 * @param deviceId device identifier
Jian Lib8436bb2017-02-23 03:39:08 +090075 * @param record LISP map record
Jian Li77d6e752017-01-29 23:24:18 +090076 */
Jian Lib8436bb2017-02-23 03:39:08 +090077 public MappingEntryBuilder(DeviceId deviceId, LispMapRecord record) {
Jian Li77d6e752017-01-29 23:24:18 +090078 this.deviceId = deviceId;
Jian Lib8436bb2017-02-23 03:39:08 +090079 this.address = buildAddress(record);
80 this.action = buildAction(record);
81 this.treatments = buildTreatments(record);
Jian Li77d6e752017-01-29 23:24:18 +090082 }
83
84 /**
Jian Lib8436bb2017-02-23 03:39:08 +090085 * Builds mapping entry from a specific LISP control message.
Jian Li77d6e752017-01-29 23:24:18 +090086 *
Jian Lib8436bb2017-02-23 03:39:08 +090087 * @return mapping entry
Jian Li77d6e752017-01-29 23:24:18 +090088 */
Jian Lib8436bb2017-02-23 03:39:08 +090089 public MappingEntry build() {
90 Mapping.Builder builder;
91
92 // we assign leastSignificantBits of UUID as the mapping identifier for now
93 // id generation scheme can be changed later
94 UUID uuid = UUID.randomUUID();
95
96 builder = DefaultMapping.builder()
97 .withId(uuid.getLeastSignificantBits())
98 .forDevice(deviceId)
99 .withKey(buildKey())
100 .withValue(buildValue());
101
102 // TODO: we assume that the mapping entry will be always
103 // stored in routers without failure for now, which means
104 // the mapping entry state will always be ADDED rather than
105 // PENDING_ADD
106 // we will revisit this part when LISP driver is finished
107 return new DefaultMappingEntry(builder.build(), MappingEntryState.ADDED);
Jian Li77d6e752017-01-29 23:24:18 +0900108 }
109
Jian Lib8436bb2017-02-23 03:39:08 +0900110 /**
111 * Builds mapping key.
112 *
113 * @return mapping key
114 */
115 private MappingKey buildKey() {
116
117 MappingKey.Builder builder = DefaultMappingKey.builder();
118
119 builder.withAddress(address);
120
121 return builder.build();
122 }
123
124 /**
125 * Builds mapping value.
126 *
127 * @return mapping value
128 */
129 private MappingValue buildValue() {
130
131 MappingValue.Builder builder = DefaultMappingValue.builder();
132 builder.withAction(action);
133
134 treatments.forEach(builder::add);
135
136 return builder.build();
137 }
138
139 /**
140 * Builds mapping action.
141 *
142 * @param record LISP map record
143 * @return mapping action
144 */
145 private MappingAction buildAction(LispMapRecord record) {
146
147 if (record == null) {
148 return MappingActions.noAction();
149 }
150
151 switch (record.getAction()) {
152 case NoAction:
153 return MappingActions.noAction();
154 case SendMapRequest:
155 return MappingActions.forward();
156 case NativelyForward:
157 return MappingActions.nativeForward();
158 case Drop:
159 return MappingActions.drop();
160 default:
161 log.warn("Unsupported action type {}", record.getAction());
162 return MappingActions.noAction();
163 }
164 }
165
166 /**
167 * Builds mapping address.
168 *
169 * @param record LISP map record
170 * @return mapping address
171 */
172 private MappingAddress buildAddress(LispMapRecord record) {
173
174 return record == null ? null :
175 getAddress(record.getEidPrefixAfi(), record.getMaskLength());
176 }
177
178 /**
179 * Converts LispAfiAddress into abstracted mapping address.
180 *
181 * @param address LispAfiAddress
182 * @param length mask length
183 * @return abstracted mapping address
184 */
185 private MappingAddress getAddress(LispAfiAddress address, int length) {
186
187 if (address == null) {
188 log.warn("Address is not specified.");
189 return null;
190 }
191
192 switch (address.getAfi()) {
193 case IP4:
194 IpAddress ipv4Address = ((LispIpv4Address) address).getAddress();
195 IpPrefix ipv4Prefix = IpPrefix.valueOf(ipv4Address, length);
196 return MappingAddresses.ipv4MappingAddress(ipv4Prefix);
197 case IP6:
198 IpAddress ipv6Address = ((LispIpv6Address) address).getAddress();
199 IpPrefix ipv6Prefix = IpPrefix.valueOf(ipv6Address, length);
200 return MappingAddresses.ipv6MappingAddress(ipv6Prefix);
201 case AS:
202 int asNum = ((LispAsAddress) address).getASNum();
203 return MappingAddresses.asMappingAddress(String.valueOf(asNum));
204 case DISTINGUISHED_NAME:
205 String dn = ((LispDistinguishedNameAddress)
206 address).getDistinguishedName();
207 return MappingAddresses.dnMappingAddress(dn);
208 case MAC:
209 MacAddress macAddress = ((LispMacAddress) address).getAddress();
210 return MappingAddresses.ethMappingAddress(macAddress);
211 case LCAF:
212 // TODO: need to use extension address to abstract LCAF address
213 break;
214 default:
215 log.warn("Unsupported address type {}", address.getAfi());
216 break;
217 }
218
Jian Li77d6e752017-01-29 23:24:18 +0900219 return null;
220 }
Jian Lib8436bb2017-02-23 03:39:08 +0900221
222 /**
223 * Builds a collection of mapping treatments.
224 *
225 * @param record LISP map record
226 * @return a collection of mapping treatments
227 */
228 private List<MappingTreatment> buildTreatments(LispMapRecord record) {
229
230 List<LispLocator> locators = record.getLocators();
231 List<MappingTreatment> treatments = Lists.newArrayList();
232 for (LispLocator locator : locators) {
233 MappingTreatment.Builder builder = DefaultMappingTreatment.builder();
234 LispAfiAddress address = locator.getLocatorAfi();
235 int addressLength = 0;
236 if (address.getAfi() == IP4) {
237 addressLength = IPV4_PREFIX_LENGTH;
238 } else if (address.getAfi() == IP6) {
239 addressLength = IPV6_PREFIX_LENGTH;
240 }
241
242 final MappingAddress mappingAddress = getAddress(address, addressLength);
243 if (mappingAddress != null) {
244 builder.withAddress(mappingAddress);
245 }
246
247 builder.setUnicastWeight(locator.getWeight())
248 .setUnicastPriority(locator.getPriority())
249 .setMulticastWeight(locator.getMulticastWeight())
250 .setMulticastPriority(locator.getMulticastPriority());
251
252 // TODO: need to convert specific properties to
253 // abstracted extension properties
254
255 treatments.add(builder.build());
256 }
257
258 return treatments;
259 }
Jian Li77d6e752017-01-29 23:24:18 +0900260}