blob: ffabf79a3ae4ef629d6abd1a318665570f12b368 [file] [log] [blame]
Jian Li451cea32016-10-04 15:27:50 +09001/*
2 * Copyright 2016-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.lisp.ctl;
17
Jian Li6ef1b3f2016-11-12 18:16:06 +090018import org.onlab.packet.IpAddress;
Jian Li712ec052016-11-22 03:23:54 +090019import org.onosproject.lisp.msg.authentication.LispAuthenticationConfig;
Jian Li6ef1b3f2016-11-12 18:16:06 +090020import org.onosproject.lisp.msg.protocols.DefaultLispInfoReply;
Jian Li24f6cc02016-11-01 16:38:40 +090021import org.onosproject.lisp.msg.protocols.DefaultLispMapNotify.DefaultNotifyBuilder;
22import org.onosproject.lisp.msg.protocols.DefaultLispMapRegister.DefaultRegisterBuilder;
23import org.onosproject.lisp.msg.protocols.LispEidRecord;
Jian Li6ef1b3f2016-11-12 18:16:06 +090024import org.onosproject.lisp.msg.protocols.LispInfoReply;
25import org.onosproject.lisp.msg.protocols.LispInfoReply.InfoReplyBuilder;
26import org.onosproject.lisp.msg.protocols.LispInfoRequest;
27import org.onosproject.lisp.msg.protocols.LispInfoRequest.InfoRequestBuilder;
Jian Liafe2d3f2016-11-01 02:49:07 +090028import org.onosproject.lisp.msg.protocols.LispMapNotify;
Jian Li24f6cc02016-11-01 16:38:40 +090029import org.onosproject.lisp.msg.protocols.LispMapNotify.NotifyBuilder;
30import org.onosproject.lisp.msg.protocols.LispMapRegister;
31import org.onosproject.lisp.msg.protocols.LispMapRegister.RegisterBuilder;
Jian Li451cea32016-10-04 15:27:50 +090032import org.onosproject.lisp.msg.protocols.LispMessage;
Jian Li6ef1b3f2016-11-12 18:16:06 +090033import org.onosproject.lisp.msg.types.LispAfiAddress;
34import org.onosproject.lisp.msg.types.LispIpv4Address;
35import org.onosproject.lisp.msg.types.LispIpv6Address;
36import org.onosproject.lisp.msg.types.LispNoAddress;
Jian Li24f6cc02016-11-01 16:38:40 +090037import org.slf4j.Logger;
38import org.slf4j.LoggerFactory;
39
Jian Li6ef1b3f2016-11-12 18:16:06 +090040import java.net.InetAddress;
Jian Li24f6cc02016-11-01 16:38:40 +090041import java.net.InetSocketAddress;
Jian Li6ef1b3f2016-11-12 18:16:06 +090042import java.net.UnknownHostException;
Jian Li24f6cc02016-11-01 16:38:40 +090043import java.util.Arrays;
44
45import static org.onosproject.lisp.msg.authentication.LispAuthenticationKeyEnum.valueOf;
Jian Li6ef1b3f2016-11-12 18:16:06 +090046import static org.onosproject.lisp.msg.protocols.DefaultLispInfoRequest.DefaultInfoRequestBuilder;
47import static org.onosproject.lisp.msg.types.LispNatLcafAddress.NatAddressBuilder;
Jian Li451cea32016-10-04 15:27:50 +090048
49/**
50 * LISP map server class.
51 * Handles map-register message and acknowledges with map-notify message.
52 */
Jian Li712ec052016-11-22 03:23:54 +090053public final class LispMapServer {
Jian Li6322a362016-10-31 00:57:19 +090054
Jian Lid1a109e2016-11-12 09:00:42 +090055 private static final int MAP_NOTIFY_PORT = 4342;
Jian Li6ef1b3f2016-11-12 18:16:06 +090056 private static final int INFO_REPLY_PORT = 4342;
Jian Li24f6cc02016-11-01 16:38:40 +090057
Jian Li24f6cc02016-11-01 16:38:40 +090058 private static final Logger log = LoggerFactory.getLogger(LispMapServer.class);
59
Jian Li712ec052016-11-22 03:23:54 +090060 private LispEidRlocMap eidRlocMap = LispEidRlocMap.getInstance();
61 private LispAuthenticationConfig authConfig = LispAuthenticationConfig.getInstance();
Jian Li24f6cc02016-11-01 16:38:40 +090062
Jian Li712ec052016-11-22 03:23:54 +090063 public static LispMapServer getInstance() {
64 return SingletonHelper.INSTANCE;
65 }
66
67 // non-instantiable (except for our Singleton)
68 private LispMapServer() {
Jian Li24f6cc02016-11-01 16:38:40 +090069 }
70
71 /**
72 * Handles map-register message and replies with map-notify message.
73 *
74 * @param message map-register message
75 * @return map-notify message
76 */
Jian Liafe2d3f2016-11-01 02:49:07 +090077 public LispMapNotify processMapRegister(LispMessage message) {
Jian Li24f6cc02016-11-01 16:38:40 +090078
79 LispMapRegister register = (LispMapRegister) message;
80
Jian Lid1a109e2016-11-12 09:00:42 +090081 if (!checkMapRegisterAuthData(register)) {
Jian Li24f6cc02016-11-01 16:38:40 +090082 log.warn("Unmatched authentication data of Map-Register");
83 return null;
84 }
85
Jian Li24f6cc02016-11-01 16:38:40 +090086 NotifyBuilder notifyBuilder = new DefaultNotifyBuilder();
Jian Li712ec052016-11-22 03:23:54 +090087 notifyBuilder.withKeyId(authConfig.lispAuthKeyId());
88 notifyBuilder.withAuthDataLength(valueOf(authConfig.lispAuthKeyId()).getHashLength());
89 notifyBuilder.withAuthKey(authConfig.lispAuthKey());
Jian Li24f6cc02016-11-01 16:38:40 +090090 notifyBuilder.withNonce(register.getNonce());
91 notifyBuilder.withMapRecords(register.getMapRecords());
92
93 LispMapNotify notify = notifyBuilder.build();
94
95 InetSocketAddress address =
Jian Lid1a109e2016-11-12 09:00:42 +090096 new InetSocketAddress(register.getSender().getAddress(), MAP_NOTIFY_PORT);
Jian Li24f6cc02016-11-01 16:38:40 +090097 notify.configSender(address);
98
99 register.getMapRecords().forEach(record -> {
100 LispEidRecord eidRecord =
101 new LispEidRecord(record.getMaskLength(), record.getEidPrefixAfi());
Jian Li712ec052016-11-22 03:23:54 +0900102 eidRlocMap.insertMapRecord(eidRecord, record);
Jian Li24f6cc02016-11-01 16:38:40 +0900103 });
104
105 return notify;
106 }
107
108 /**
Jian Li6ef1b3f2016-11-12 18:16:06 +0900109 * Handles info-request message and replies with info-reply message.
110 *
111 * @param message info-request message
112 * @return info-reply message
113 */
114 public LispInfoReply processInfoRequest(LispMessage message) {
115 LispInfoRequest request = (LispInfoRequest) message;
116
117 if (!checkInfoRequestAuthData(request)) {
118 log.warn("Unmatched authentication data of Info-Request");
119 return null;
120 }
121
122 NatAddressBuilder natBuilder = new NatAddressBuilder();
123 try {
124 LispAfiAddress msAddress =
125 new LispIpv4Address(IpAddress.valueOf(InetAddress.getLocalHost()));
126 natBuilder.withMsRlocAddress(msAddress);
127 natBuilder.withMsUdpPortNumber((short) INFO_REPLY_PORT);
128
129 // try to extract global ETR RLOC address from info-request
130 IpAddress globalRlocIp = IpAddress.valueOf(request.getSender().getAddress());
131 LispAfiAddress globalRlocAddress;
132 if (globalRlocIp.isIp4()) {
133 globalRlocAddress = new LispIpv4Address(globalRlocIp);
134 } else {
135 globalRlocAddress = new LispIpv6Address(globalRlocIp);
136 }
137 natBuilder.withGlobalEtrRlocAddress(globalRlocAddress);
138 natBuilder.withEtrUdpPortNumber((short) request.getSender().getPort());
139 natBuilder.withPrivateEtrRlocAddress(new LispNoAddress());
140
141 // TODO: need to specify RTR addresses
142
143 } catch (UnknownHostException e) {
144 log.warn("Fails during formulate NAT address", e);
145 }
146
147 InfoReplyBuilder replyBuilder = new DefaultLispInfoReply.DefaultInfoReplyBuilder();
148 replyBuilder.withKeyId(request.getKeyId());
Jian Li712ec052016-11-22 03:23:54 +0900149 replyBuilder.withAuthDataLength(valueOf(authConfig.lispAuthKeyId()).getHashLength());
150 replyBuilder.withAuthKey(authConfig.lispAuthKey());
Jian Li6ef1b3f2016-11-12 18:16:06 +0900151 replyBuilder.withNonce(request.getNonce());
152 replyBuilder.withEidPrefix(request.getPrefix());
153 replyBuilder.withMaskLength(request.getMaskLength());
154 replyBuilder.withTtl(request.getTtl());
155 replyBuilder.withNatLcafAddress(natBuilder.build());
156 replyBuilder.withIsInfoReply(true);
157
158 LispInfoReply reply = replyBuilder.build();
159 reply.configSender(request.getSender());
160
161 return reply;
162 }
163
164 /**
Jian Li51aaca12016-11-11 01:56:15 +0900165 * Checks the integrity of the received map-register message by calculating
166 * authentication data from received map-register message.
Jian Li24f6cc02016-11-01 16:38:40 +0900167 *
Jian Li51aaca12016-11-11 01:56:15 +0900168 * @param register map-register message
Jian Li24f6cc02016-11-01 16:38:40 +0900169 * @return evaluation result
170 */
Jian Lid1a109e2016-11-12 09:00:42 +0900171 private boolean checkMapRegisterAuthData(LispMapRegister register) {
Jian Li24f6cc02016-11-01 16:38:40 +0900172 RegisterBuilder registerBuilder = new DefaultRegisterBuilder();
173 registerBuilder.withKeyId(register.getKeyId());
Jian Li712ec052016-11-22 03:23:54 +0900174 registerBuilder.withAuthKey(authConfig.lispAuthKey());
Jian Li24f6cc02016-11-01 16:38:40 +0900175 registerBuilder.withNonce(register.getNonce());
176 registerBuilder.withIsProxyMapReply(register.isProxyMapReply());
177 registerBuilder.withIsWantMapNotify(register.isWantMapNotify());
178 registerBuilder.withMapRecords(register.getMapRecords());
Jian Li6ef1b3f2016-11-12 18:16:06 +0900179
Jian Lid1a109e2016-11-12 09:00:42 +0900180 LispMapRegister authRegister = registerBuilder.build();
Jian Li24f6cc02016-11-01 16:38:40 +0900181
Jian Lid1a109e2016-11-12 09:00:42 +0900182 return Arrays.equals(authRegister.getAuthData(), register.getAuthData());
Jian Li451cea32016-10-04 15:27:50 +0900183 }
Jian Li6ef1b3f2016-11-12 18:16:06 +0900184
185 /**
186 * Checks the integrity of the received info-request message by calculating
187 * authentication data from received info-request message.
188 *
189 * @param request info-request message
190 * @return evaluation result
191 */
192 private boolean checkInfoRequestAuthData(LispInfoRequest request) {
193 InfoRequestBuilder requestBuilder = new DefaultInfoRequestBuilder();
194 requestBuilder.withKeyId(request.getKeyId());
Jian Li712ec052016-11-22 03:23:54 +0900195 requestBuilder.withAuthKey(authConfig.lispAuthKey());
Jian Li6ef1b3f2016-11-12 18:16:06 +0900196 requestBuilder.withNonce(request.getNonce());
197 requestBuilder.withTtl(request.getTtl());
198 requestBuilder.withEidPrefix(request.getPrefix());
199 requestBuilder.withIsInfoReply(request.isInfoReply());
200 requestBuilder.withMaskLength(request.getMaskLength());
201
yoonseon980cd7c2016-11-18 14:18:46 -0800202 LispInfoRequest authRequest = requestBuilder.build();
Jian Li6ef1b3f2016-11-12 18:16:06 +0900203
204 return Arrays.equals(authRequest.getAuthData(), request.getAuthData());
205 }
Jian Li712ec052016-11-22 03:23:54 +0900206
207 /**
208 * Prevents object instantiation from external.
209 */
210 private static class SingletonHelper {
211 private static final LispMapServer INSTANCE = new LispMapServer();
212 }
Jian Li451cea32016-10-04 15:27:50 +0900213}