3 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
10 package org.opendaylight.controller.forwarding.staticrouting;
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;
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;
29 * This class defines a static route object.
31 public class StaticRoute implements Serializable{
32 private static final long serialVersionUID = 1L;
33 protected static final Logger logger = LoggerFactory
34 .getLogger(StaticRoute.class);
37 * This Enum defines the possible types for the next hop address.
39 public enum NextHopType implements Serializable {
40 IPADDRESS("nexthop-ip"), SWITCHPORT("nexthop-interface");
41 private NextHopType(String name) {
47 public String toString() {
51 public static NextHopType fromString(String str) {
54 if (str.equals(IPADDRESS.toString()))
56 if (str.equals(SWITCHPORT.toString()))
62 InetAddress networkAddress;
65 InetAddress nextHopAddress;
68 HostNodeConnector host;
71 * Create a static route object with no specific information.
73 public StaticRoute() {
78 * Create a static route object from the StaticRouteConfig.
79 * @param: config: StaticRouteConfig
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()
91 port = NodeConnectorCreator.createOFNodeConnector(
92 (Short) switchPort.values().toArray()[0], node);
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
100 public InetAddress getNetworkAddress() {
101 return networkAddress;
105 * Set the IP address portion of the sub-network of the static route.
106 * @param networkAddress The IP address (InetAddress) to be set
108 public void setNetworkAddress(InetAddress networkAddress) {
109 this.networkAddress = networkAddress;
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
116 public InetAddress getMask() {
121 * Set the sub-network's mask of the static route.
122 * @param mask The mask (InetAddress) to be set
124 public void setMask(InetAddress mask) {
129 * Get the NextHopeType of the static route.
130 * @return type: NextHopeType
132 public NextHopType getType() {
137 * Set the nextHopType.
138 * @param type The NextHopType to be set
140 public void setType(NextHopType type) {
145 * Get the next hop IP address.
146 * @return: nextHopAddress (InetAddress)
148 public InetAddress getNextHopAddress() {
149 return nextHopAddress;
153 * Set the next hop IP address.
154 * @param nextHopAddress The IP address (InetAddress) to be set
156 public void setNextHopAddress(InetAddress nextHopAddress) {
157 this.nextHopAddress = nextHopAddress;
161 * Get the Node associated with the static route.
164 public Node getNode() {
169 * Set the node associated to the static route.
170 * @param node: The node to be set
172 public void setNode(Node node) {
177 * Set the port associated to the static route.
178 * @param port The port (NodeConnector) to be set
180 public void setPort(NodeConnector port) {
185 * Get the port associated to the static route.
186 * @return port: The port (NodeConnector)
188 public NodeConnector getPort() {
193 * Get the Host associated to static route.
194 * @return host: The host (HostNodeConnector)
196 public HostNodeConnector getHost() {
201 * Set the host associated to the static route.
202 * @param host: (HostNodeConnector) to be set
204 public void setHost(HostNodeConnector host) {
209 public int hashCode() {
210 final int prime = 31;
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());
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 + "]";
233 public boolean equals(Object obj) {
238 if (getClass() != obj.getClass())
240 StaticRoute other = (StaticRoute) obj;
241 if (!networkAddress.equals(other.networkAddress))
243 if (!mask.equals(other.mask))
248 private static InetAddress getV4AddressMaskFromDecimal(int mask) {
250 for (int i = 0; i < mask; i++) {
251 netmask |= (1 << 31 - i);
255 return InetAddress.getByAddress(BitBufferHelper
256 .toByteArray(netmask));
257 } catch (Exception e) {
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)));
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.
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());
282 ByteBuffer bbMask = ByteBuffer.wrap(mask.getAddress());
284 applyV4MaskOnByteBuffer(bbdest, bbMask);
285 applyV4MaskOnByteBuffer(bbself, bbMask);
287 if (bbdest.equals(bbself)) {
289 return InetAddress.getByAddress(bbself.array());
290 } catch (Exception e) {
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
303 public int compareTo(StaticRoute s) {
306 if ((networkAddress instanceof Inet6Address)
307 || (s.getNetworkAddress() instanceof Inet6Address)) {
312 ByteBuffer bbchallenger = ByteBuffer.wrap(s.getNetworkAddress()
314 ByteBuffer bbself = ByteBuffer.wrap(networkAddress.getAddress());
315 ByteBuffer bbChallengerMask = ByteBuffer.wrap(s.getMask().getAddress());
316 ByteBuffer bbSelfMask = ByteBuffer.wrap(getMask().getAddress());
318 applyV4MaskOnByteBuffer(bbchallenger, bbChallengerMask);
319 applyV4MaskOnByteBuffer(bbself, bbSelfMask);
320 return bbself.compareTo(bbchallenger);