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