blob: 4e555ee1633af0f1b2d2f3e2a5e3c4f4a46ca38a [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;
19import org.onosproject.lisp.msg.protocols.DefaultLispInfoReply;
Jian Li24f6cc02016-11-01 16:38:40 +090020import org.onosproject.lisp.msg.protocols.DefaultLispMapNotify.DefaultNotifyBuilder;
21import org.onosproject.lisp.msg.protocols.DefaultLispMapRegister.DefaultRegisterBuilder;
22import org.onosproject.lisp.msg.protocols.LispEidRecord;
Jian Li6ef1b3f2016-11-12 18:16:06 +090023import org.onosproject.lisp.msg.protocols.LispInfoReply;
24import org.onosproject.lisp.msg.protocols.LispInfoReply.InfoReplyBuilder;
25import org.onosproject.lisp.msg.protocols.LispInfoRequest;
26import org.onosproject.lisp.msg.protocols.LispInfoRequest.InfoRequestBuilder;
Jian Liafe2d3f2016-11-01 02:49:07 +090027import org.onosproject.lisp.msg.protocols.LispMapNotify;
Jian Li24f6cc02016-11-01 16:38:40 +090028import org.onosproject.lisp.msg.protocols.LispMapNotify.NotifyBuilder;
29import org.onosproject.lisp.msg.protocols.LispMapRegister;
30import org.onosproject.lisp.msg.protocols.LispMapRegister.RegisterBuilder;
Jian Li451cea32016-10-04 15:27:50 +090031import org.onosproject.lisp.msg.protocols.LispMessage;
Jian Li6ef1b3f2016-11-12 18:16:06 +090032import org.onosproject.lisp.msg.types.LispAfiAddress;
33import org.onosproject.lisp.msg.types.LispIpv4Address;
34import org.onosproject.lisp.msg.types.LispIpv6Address;
35import org.onosproject.lisp.msg.types.LispNoAddress;
Jian Li24f6cc02016-11-01 16:38:40 +090036import org.slf4j.Logger;
37import org.slf4j.LoggerFactory;
38
Jian Li6ef1b3f2016-11-12 18:16:06 +090039import java.net.InetAddress;
Jian Li24f6cc02016-11-01 16:38:40 +090040import java.net.InetSocketAddress;
Jian Li6ef1b3f2016-11-12 18:16:06 +090041import java.net.UnknownHostException;
Jian Li24f6cc02016-11-01 16:38:40 +090042import java.util.Arrays;
43
44import static org.onosproject.lisp.msg.authentication.LispAuthenticationKeyEnum.valueOf;
Jian Li6ef1b3f2016-11-12 18:16:06 +090045import static org.onosproject.lisp.msg.protocols.DefaultLispInfoRequest.DefaultInfoRequestBuilder;
46import static org.onosproject.lisp.msg.types.LispNatLcafAddress.NatAddressBuilder;
Jian Li451cea32016-10-04 15:27:50 +090047
48/**
49 * LISP map server class.
50 * Handles map-register message and acknowledges with map-notify message.
51 */
Jian Li6322a362016-10-31 00:57:19 +090052public class LispMapServer {
53
Jian Lid1a109e2016-11-12 09:00:42 +090054 private static final int MAP_NOTIFY_PORT = 4342;
Jian Li6ef1b3f2016-11-12 18:16:06 +090055 private static final int INFO_REPLY_PORT = 4342;
Jian Li24f6cc02016-11-01 16:38:40 +090056
57 // TODO: need to be configurable
58 private static final String AUTH_KEY = "onos";
59
Jian Li24f6cc02016-11-01 16:38:40 +090060 // TODO: need to be configurable
61 private static final short AUTH_METHOD = 1;
62
63 private static final Logger log = LoggerFactory.getLogger(LispMapServer.class);
64
Jian Li24f6cc02016-11-01 16:38:40 +090065 private LispEidRlocMap mapInfo;
66
67 public LispMapServer() {
Jian Li24f6cc02016-11-01 16:38:40 +090068 mapInfo = LispEidRlocMap.getInstance();
69 }
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();
87 notifyBuilder.withKeyId(AUTH_METHOD);
Jian Lid1a109e2016-11-12 09:00:42 +090088 notifyBuilder.withAuthDataLength(valueOf(AUTH_METHOD).getHashLength());
89 notifyBuilder.withAuthKey(AUTH_KEY);
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());
102 mapInfo.insertMapRecord(eidRecord, record);
103 });
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());
149 replyBuilder.withAuthDataLength(valueOf(AUTH_METHOD).getHashLength());
150 replyBuilder.withAuthKey(AUTH_KEY);
151 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 Lid1a109e2016-11-12 09:00:42 +0900174 registerBuilder.withAuthKey(AUTH_KEY);
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());
195 requestBuilder.withAuthKey(AUTH_KEY);
196 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
202 LispInfoRequest authRequest = requestBuilder.build();
203
204 return Arrays.equals(authRequest.getAuthData(), request.getAuthData());
205 }
Jian Li451cea32016-10-04 15:27:50 +0900206}