BUG-2218: Keep existing link augmentations during discovery process
[controller.git] / opendaylight / adsal / forwarding / staticrouting / src / main / java / org / opendaylight / controller / forwarding / staticrouting / StaticRoute.java
1
2 /*
3  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7  * and is available at http://www.eclipse.org/legal/epl-v10.html
8  */
9
10 package org.opendaylight.controller.forwarding.staticrouting;
11
12 import java.io.Serializable;
13 import java.net.Inet4Address;
14 import java.net.Inet6Address;
15 import java.net.InetAddress;
16 import java.nio.ByteBuffer;
17 import java.util.Map;
18
19 import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
20 import org.opendaylight.controller.sal.core.Node;
21 import org.opendaylight.controller.sal.core.NodeConnector;
22 import org.opendaylight.controller.sal.packet.BitBufferHelper;
23 import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
24 import org.opendaylight.controller.sal.utils.NodeCreator;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 /**
29  * This class defines a static route object.
30  */
31 public class StaticRoute implements Serializable{
32     private static final long serialVersionUID = 1L;
33     protected static final Logger logger = LoggerFactory
34     .getLogger(StaticRoute.class);
35
36     /**
37      * This Enum defines the possible types for the next hop address.
38      */
39     public enum NextHopType implements Serializable {
40         IPADDRESS("nexthop-ip"), SWITCHPORT("nexthop-interface");
41         private NextHopType(String name) {
42             this.name = name;
43         }
44
45         private String name;
46
47         public String toString() {
48             return name;
49         }
50
51         public static NextHopType fromString(String str) {
52             if (str == null)
53                 return IPADDRESS;
54             if (str.equals(IPADDRESS.toString()))
55                 return IPADDRESS;
56             if (str.equals(SWITCHPORT.toString()))
57                 return SWITCHPORT;
58             return IPADDRESS;
59         }
60     }
61
62     InetAddress networkAddress;
63     InetAddress mask;
64     NextHopType type;
65     InetAddress nextHopAddress;
66     Node node;
67     NodeConnector port;
68     HostNodeConnector host;
69
70     /**
71      * Create a static route object with no specific information.
72      */
73     public StaticRoute() {
74
75     }
76
77     /**
78      * Create a static route object from the StaticRouteConfig.
79      * @param: config: StaticRouteConfig
80      */
81     public StaticRoute(StaticRouteConfig config) {
82         networkAddress = config.getStaticRouteIP();
83         mask = StaticRoute.getV4AddressMaskFromDecimal(config
84                 .getStaticRouteMask());
85         type = NextHopType.fromString(config.getNextHopType());
86         nextHopAddress = config.getNextHopIP();
87         Map<Long, Short> switchPort = config.getNextHopSwitchPorts();
88         if ((switchPort != null) && (switchPort.size() == 1)) {
89             node = NodeCreator.createOFNode((Long) switchPort.keySet()
90                     .toArray()[0]);
91             port = NodeConnectorCreator.createOFNodeConnector(
92                     (Short) switchPort.values().toArray()[0], node);
93         }
94     }
95
96     /**
97      * Get the IP address portion of the sub-network of the static route.
98      * @return InetAddress: the IP address portion of the sub-network of the static route
99      */
100     public InetAddress getNetworkAddress() {
101         return networkAddress;
102     }
103
104     /**
105      * Set the IP address portion of the sub-network of the static route.
106      * @param networkAddress The IP address (InetAddress) to be set
107      */
108     public void setNetworkAddress(InetAddress networkAddress) {
109         this.networkAddress = networkAddress;
110     }
111
112     /**
113      * Get the mask of the sub-network of the static route.
114      * @return mask: the mask  (InetAddress) of the sub-network of the static route
115      */
116     public InetAddress getMask() {
117         return mask;
118     }
119
120     /**
121      * Set the sub-network's mask of the static route.
122      * @param mask The mask (InetAddress) to be set
123      */
124     public void setMask(InetAddress mask) {
125         this.mask = mask;
126     }
127
128     /**
129      * Get the NextHopeType of the static route.
130      * @return type: NextHopeType
131      */
132     public NextHopType getType() {
133         return type;
134     }
135
136     /**
137      * Set the nextHopType.
138      * @param type The NextHopType to be set
139      */
140     public void setType(NextHopType type) {
141         this.type = type;
142     }
143
144     /**
145      * Get the next hop IP address.
146      * @return: nextHopAddress (InetAddress)
147      */
148     public InetAddress getNextHopAddress() {
149         return nextHopAddress;
150     }
151
152     /**
153      * Set the next hop IP address.
154      * @param nextHopAddress The IP address (InetAddress) to be set
155      */
156     public void setNextHopAddress(InetAddress nextHopAddress) {
157         this.nextHopAddress = nextHopAddress;
158     }
159
160     /**
161      * Get the Node associated with the static route.
162      * @return: Node
163      */
164     public Node getNode() {
165         return node;
166     }
167
168     /**
169      * Set the node associated to the static route.
170      * @param node: The node to be set
171      */
172     public void setNode(Node node) {
173         this.node = node;
174     }
175
176     /**
177      * Set the port associated to the static route.
178      * @param port The port (NodeConnector) to be set
179      */
180     public void setPort(NodeConnector port) {
181         this.port = port;
182     }
183
184     /**
185      * Get the port associated to the static route.
186      * @return port: The port (NodeConnector)
187      */
188     public NodeConnector getPort() {
189         return port;
190     }
191
192     /**
193      * Get the Host associated to static route.
194      * @return host:  The host (HostNodeConnector)
195      */
196     public HostNodeConnector getHost() {
197         return host;
198     }
199
200     /**
201      * Set the host associated to the static route.
202      * @param host: (HostNodeConnector) to be set
203      */
204     public void setHost(HostNodeConnector host) {
205         this.host = host;
206     }
207
208     @Override
209     public int hashCode() {
210         final int prime = 31;
211         int result = 1;
212         result = prime * result + ((host == null) ? 0 : host.hashCode());
213         result = prime * result + ((mask == null) ? 0 : mask.hashCode());
214         result = prime * result
215                 + ((networkAddress == null) ? 0 : networkAddress.hashCode());
216         result = prime * result
217                 + ((nextHopAddress == null) ? 0 : nextHopAddress.hashCode());
218         result = prime * result + ((port == null) ? 0 : port.hashCode());
219         result = prime * result + ((node == null) ? 0 : node.hashCode());
220         result = prime * result + ((type == null) ? 0 : type.hashCode());
221         return result;
222     }
223
224     @Override
225     public String toString() {
226         return "StaticRoute [networkAddress=" + networkAddress + ", mask="
227                 + mask + ", type=" + type.toString() + ", nextHopAddress="
228                 + nextHopAddress + ", swid=" + node + ", port=" + port
229                 + ", host=" + host + "]";
230     }
231
232     @Override
233     public boolean equals(Object obj) {
234         if (this == obj)
235             return true;
236         if (obj == null)
237             return false;
238         if (getClass() != obj.getClass())
239             return false;
240         StaticRoute other = (StaticRoute) obj;
241         if (!networkAddress.equals(other.networkAddress))
242             return false;
243         if (!mask.equals(other.mask))
244             return false;
245         return true;
246     }
247
248     private static InetAddress getV4AddressMaskFromDecimal(int mask) {
249         int netmask = 0;
250         for (int i = 0; i < mask; i++) {
251             netmask |= (1 << 31 - i);
252         }
253
254         try {
255             return InetAddress.getByAddress(BitBufferHelper
256                     .toByteArray(netmask));
257         } catch (Exception e) {
258             logger.error("",e);
259             return null;
260         }
261     }
262
263     private void applyV4MaskOnByteBuffer(ByteBuffer bb, ByteBuffer bbMask) {
264         for (int i = 0; i < bb.array().length; i++) {
265             bb.put(i, (byte) (bb.get(i) & bbMask.get(i)));
266         }
267     }
268
269     /**
270      * Compute and return the IP address  with longest prefix match from the static route based on the
271      *  destNetworkAddress. Currently it only take IPv4 address format (Inet4Address)
272      * @param destNetworkAddress: the IP address to be based on
273      * @return: InetAddress: the IPv4 address with the longest prefix matching the static route.
274      * If the destNetworkkAddress is not IPv4 format, it will return null.
275      */
276     public InetAddress longestPrefixMatch(InetAddress destNetworkAddress) {
277         if (destNetworkAddress instanceof Inet4Address) {
278             ByteBuffer bbdest = ByteBuffer
279                     .wrap(destNetworkAddress.getAddress());
280             ByteBuffer bbself = ByteBuffer.wrap(networkAddress.getAddress());
281
282             ByteBuffer bbMask = ByteBuffer.wrap(mask.getAddress());
283
284             applyV4MaskOnByteBuffer(bbdest, bbMask);
285             applyV4MaskOnByteBuffer(bbself, bbMask);
286
287             if (bbdest.equals(bbself)) {
288                 try {
289                     return InetAddress.getByAddress(bbself.array());
290                 } catch (Exception e) {
291                     logger.error("",e);
292                 }
293             }
294         }
295         return null;
296     }
297
298     /**
299      * Compare the static route with another static route. It only handles(for now) IPv4Address.
300      * @param s: the other StaticRoute
301      * @return: 0 if they are the same
302      */
303     public int compareTo(StaticRoute s) {
304         if (s == null)
305             return 1;
306         if ((networkAddress instanceof Inet6Address)
307                 || (s.getNetworkAddress() instanceof Inet6Address)) {
308             // HANDLE IPv6 Later
309             return 1;
310         }
311
312         ByteBuffer bbchallenger = ByteBuffer.wrap(s.getNetworkAddress()
313                 .getAddress());
314         ByteBuffer bbself = ByteBuffer.wrap(networkAddress.getAddress());
315         ByteBuffer bbChallengerMask = ByteBuffer.wrap(s.getMask().getAddress());
316         ByteBuffer bbSelfMask = ByteBuffer.wrap(getMask().getAddress());
317
318         applyV4MaskOnByteBuffer(bbchallenger, bbChallengerMask);
319         applyV4MaskOnByteBuffer(bbself, bbSelfMask);
320         return bbself.compareTo(bbchallenger);
321     }
322 }