blob: 44c865a5aed12ef64e294b5f8392d6c415244cef [file] [log] [blame]
Jian Li0dab5962016-12-15 03:44:28 +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 Lib1a8fd02016-12-27 03:55:32 +090018import com.google.common.base.Objects;
Jian Lib86d8ad2017-05-03 02:53:44 +090019import com.google.common.collect.ImmutableList;
Jian Li0dab5962016-12-15 03:44:28 +090020import io.netty.channel.Channel;
21import org.onlab.packet.IpAddress;
Jian Lib86d8ad2017-05-03 02:53:44 +090022import org.onosproject.lisp.msg.protocols.LispEidRecord;
Jian Li0dab5962016-12-15 03:44:28 +090023import org.onosproject.lisp.msg.protocols.LispMessage;
24import org.onosproject.net.Device;
25import org.slf4j.Logger;
26import org.slf4j.LoggerFactory;
27
28import java.net.InetSocketAddress;
29import java.net.SocketAddress;
Jian Lib86d8ad2017-05-03 02:53:44 +090030import java.util.List;
Jian Li0dab5962016-12-15 03:44:28 +090031
32/**
33 * An abstract representation of a LISP router.
34 * This class can be extended by others to serve as a base for their vendor
35 * specific representation of a router.
36 */
37public abstract class AbstractLispRouter implements LispRouter {
38
39 private final Logger log = LoggerFactory.getLogger(getClass());
40
41 private static final String DROP_MESSAGE_WARN =
42 "Drop message {} destined to router {} as channel is closed.";
43
44 private Channel channel;
45 private String channelId;
46
47 private boolean connected;
48 private boolean subscribed;
49 private LispRouterId routerId;
50 private LispRouterAgent agent;
Jian Lib86d8ad2017-05-03 02:53:44 +090051 private List<LispEidRecord> records;
Jian Li0dab5962016-12-15 03:44:28 +090052
53 /**
54 * A default constructor.
55 *
56 * @param routerId router identifier
57 */
58 AbstractLispRouter(LispRouterId routerId) {
59 this.routerId = routerId;
60 }
61
62 @Override
63 public final String channelId() {
64 return channelId;
65 }
66
67 @Override
68 public final IpAddress routerId() {
69 return routerId.id();
70 }
71
72 @Override
73 public final String stringId() {
74 return routerId.toString();
75 }
76
77 @Override
78 public final void setChannel(Channel channel) {
79 this.channel = channel;
80 final SocketAddress address = channel.remoteAddress();
81 if (address instanceof InetSocketAddress) {
Jian Lib1a8fd02016-12-27 03:55:32 +090082 channelId = genChannelId((InetSocketAddress) address);
Jian Li0dab5962016-12-15 03:44:28 +090083 }
84 }
85
86 @Override
87 public final void setConnected(boolean connected) {
88 this.connected = connected;
89 }
90
91 @Override
92 public final boolean isConnected() {
93 return connected;
94 }
95
Jian Li0dab5962016-12-15 03:44:28 +090096 @Override
97 public final boolean isSubscribed() {
98 return subscribed;
99 }
100
101 @Override
102 public final void setSubscribed(boolean subscribed) {
103 this.subscribed = subscribed;
104 }
105
106 @Override
107 public final void setAgent(LispRouterAgent agent) {
108 // we never assign the agent more than one time
109 if (this.agent == null) {
110 this.agent = agent;
111 }
112 }
113
114 @Override
115 public final Device.Type deviceType() {
116 return Device.Type.ROUTER;
117 }
118
119 @Override
120 public void sendMessage(LispMessage message) {
121 if (channel.isOpen()) {
122 // TODO: need to consider to use writeAndFlush if possible
123 channel.write(message);
124 agent.processDownstreamMessage(routerId, message);
125 } else {
126 log.warn(DROP_MESSAGE_WARN, message, routerId);
127 }
128 }
129
130 @Override
131 public void handleMessage(LispMessage message) {
132 this.agent.processUpstreamMessage(routerId, message);
133 }
134
135 @Override
136 public final boolean connectRouter() {
Jian Lib86d8ad2017-05-03 02:53:44 +0900137 setConnected(true);
Jian Li0dab5962016-12-15 03:44:28 +0900138 return this.agent.addConnectedRouter(routerId, this);
139 }
140
141 @Override
142 public final void disconnectRouter() {
143 setConnected(false);
144 channel.close();
145 }
146
147 @Override
Jian Lib86d8ad2017-05-03 02:53:44 +0900148 public List<LispEidRecord> getEidRecords() {
149 return records;
150 }
151
152 @Override
153 public void setEidRecords(List<LispEidRecord> records) {
154 this.records = ImmutableList.copyOf(records);
155 }
156
157 @Override
Jian Li0dab5962016-12-15 03:44:28 +0900158 public String toString() {
159
160 StringBuilder sb = new StringBuilder();
161 sb.append(this.getClass().getName());
162
163 String address = (channel != null) ? channel.remoteAddress().toString() : "?";
164 String routerId = (stringId() != null) ? stringId() : "?";
165
166 sb.append(" [");
167 sb.append(address);
168 sb.append(" routerId[");
169 sb.append(routerId);
170 sb.append("]]");
171
172 return sb.toString();
173 }
Jian Lib1a8fd02016-12-27 03:55:32 +0900174
175 @Override
176 public boolean equals(Object o) {
177 if (this == o) {
178 return true;
179 }
180 if (o == null || getClass() != o.getClass()) {
181 return false;
182 }
183
184 AbstractLispRouter that = (AbstractLispRouter) o;
185 return Objects.equal(channel, that.channel) &&
186 Objects.equal(channelId, that.channelId) &&
187 Objects.equal(connected, that.connected) &&
188 Objects.equal(subscribed, that.subscribed) &&
189 Objects.equal(routerId, that.routerId) &&
190 Objects.equal(agent, that.agent);
191 }
192
193 @Override
194 public int hashCode() {
195 return Objects.hashCode(channel, channelId, connected,
196 subscribed, routerId, agent);
197 }
198
199 /**
200 * Generates a string format of channel ID from the given InetSocketAddress.
201 *
202 * @param inetAddress InetAddress object
203 * @return string format of channel ID
204 */
205 private String genChannelId(InetSocketAddress inetAddress) {
206 StringBuilder sb = new StringBuilder();
207 final IpAddress ipAddress = IpAddress.valueOf(inetAddress.getAddress());
208 if (ipAddress.isIp4()) {
209 sb.append(ipAddress.toString());
210 sb.append(":");
211 sb.append(inetAddress.getPort());
212 } else {
213 sb.append("[");
214 sb.append(ipAddress.toString());
215 sb.append("]:");
216 sb.append(inetAddress.getPort());
217 }
218 return sb.toString();
219 }
Jian Li0dab5962016-12-15 03:44:28 +0900220}