- Application is no longer blocked when programming hundreds of flows. The Barrier...
[controller.git] / opendaylight / switchmanager / src / main / java / org / opendaylight / controller / switchmanager / Subnet.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.switchmanager;
11
12 import java.io.Serializable;
13 import java.net.InetAddress;
14 import java.net.UnknownHostException;
15 import java.util.HashSet;
16 import java.util.Set;
17
18 import org.apache.commons.lang3.builder.EqualsBuilder;
19 import org.apache.commons.lang3.builder.HashCodeBuilder;
20 import org.opendaylight.controller.sal.core.NodeConnector;
21
22 import org.opendaylight.controller.switchmanager.Subnet;
23 import org.opendaylight.controller.switchmanager.SubnetConfig;
24
25 /**
26  * The class describes subnet information including L3 address, vlan and set of
27  * ports associated with the subnet.
28  */
29 public class Subnet implements Serializable {
30     private static final long serialVersionUID = 1L;
31     // Key fields
32     private InetAddress networkAddress;
33     private short subnetMaskLength;
34     // Property fields
35     private short vlan;
36     private Set<NodeConnector> nodeConnectors;
37
38     public Subnet(InetAddress ip, short maskLen, short vlan) {
39         this.networkAddress = ip;
40         this.subnetMaskLength = maskLen;
41         this.vlan = vlan;
42         this.nodeConnectors = new HashSet<NodeConnector>();
43     }
44
45     public Subnet(SubnetConfig conf) {
46         networkAddress = conf.getIPnum();
47         subnetMaskLength = conf.getIPMaskLen();
48         nodeConnectors = conf.getSubnetNodeConnectors();
49     }
50
51     /**
52      * Add NodeConnectors to a subnet
53      *
54      * @param sp Set of NodeConnectors to add to the subnet
55      */
56     public void addNodeConnectors(Set<NodeConnector> sp) {
57         if (sp == null) {
58             return;
59         }
60
61         for (NodeConnector p : sp) {
62             this.nodeConnectors.add(p);
63         }
64     }
65
66     /**
67      * Delete NodeConnectors from subnet
68      *
69      * @param sp Set of NodeConnectors to add to the subnet
70      */
71     public void deleteNodeConnectors(Set<NodeConnector> sp) {
72         if (sp == null) {
73             return;
74         }
75         for (NodeConnector p : sp) {
76             this.nodeConnectors.remove(p);
77         }
78     }
79
80     /**
81      * Return the list of NodeConnectors configured for this subnet,
82      * could be also an empty set in case of all the known
83      * nodeconnectors.
84      *
85      *
86      * @return The list of NodeConnectors attached to the subnet
87      */
88     public Set<NodeConnector> getNodeConnectors() {
89         return this.nodeConnectors;
90     }
91
92     /**
93      * If the subnet has no node connectors attached to it then it
94      * means that is a whole L2 flat domain
95      *
96      *
97      * @return true if there are no node connectors configured for the
98      * subnet else false
99      */
100     public boolean isFlatLayer2() {
101         return nodeConnectors.isEmpty();
102     }
103
104     /**
105      * getter method
106      *
107      *
108      * @return the Network Address part of the subnet
109      */
110     public InetAddress getNetworkAddress() {
111         return networkAddress;
112     }
113
114     /**
115      * @param networkAddress the networkAddress to set
116      */
117     public Subnet setNetworkAddress(InetAddress networkAddress) {
118         this.networkAddress = networkAddress;
119         return this;
120     }
121
122     /**
123      * getter method
124      *
125      *
126      * @return the subnet mask length
127      */
128     public short getSubnetMaskLength() {
129         return this.subnetMaskLength;
130     }
131
132     public Subnet setSubnetMaskLength(short m) {
133         this.subnetMaskLength = m;
134         return this;
135     }
136
137     /*
138      * returns the prefix of a given IP by applying this subnet's mask
139      */
140     private InetAddress getPrefixForAddress(InetAddress ip) {
141         int bytes = this.subnetMaskLength / 8;
142         int bits = this.subnetMaskLength % 8;
143         byte modifiedByte;
144         byte[] sn = ip.getAddress();
145         if (bits > 0) {
146             modifiedByte = (byte) (sn[bytes] >> (8 - bits));
147             sn[bytes] = (byte) (modifiedByte << (8 - bits));
148             bytes++;
149         }
150         for (; bytes < sn.length; bytes++) {
151             sn[bytes] = (byte) (0);
152         }
153         try {
154             return InetAddress.getByAddress(sn);
155         } catch (UnknownHostException e) {
156             return null;
157         }
158     }
159
160     public boolean isSubnetOf(InetAddress ip) {
161         if (ip == null)
162             return false;
163         InetAddress thisPrefix = getPrefixForAddress(this.networkAddress);
164         InetAddress otherPrefix = getPrefixForAddress(ip);
165         if ((thisPrefix == null) || (otherPrefix == null))
166             return false;
167         if (thisPrefix.equals(otherPrefix))
168             return true;
169         else
170             return false;
171     }
172
173     public short getVlan() {
174         return this.vlan;
175     }
176
177     public Subnet setVlan(short i) {
178         this.vlan = i;
179         return this;
180     }
181
182     /* (non-Javadoc)
183      * @see java.lang.Object#hashCode()
184      */
185     @Override
186     public int hashCode() {
187         return new HashCodeBuilder().append(networkAddress).append(
188                 subnetMaskLength).toHashCode();
189     }
190
191     /* (non-Javadoc)
192      * @see java.lang.Object#equals(java.lang.Object)
193      */
194     @Override
195     public boolean equals(Object obj) {
196         if (this == obj) {
197             return true;
198         }
199         if (obj == null) {
200             return false;
201         }
202         if (obj.getClass() != getClass()) {
203             return false;
204         }
205         Subnet other = (Subnet) obj;
206         // Check only equality for the key fields
207         return new EqualsBuilder().append(networkAddress, other.networkAddress)
208                 .append(subnetMaskLength, other.subnetMaskLength).isEquals();
209     }
210
211     /* (non-Javadoc)
212      * @see java.lang.Object#toString()
213      */
214     @Override
215     public String toString() {
216         return ("Subnet [networkAddress=" + networkAddress.getHostAddress()
217                 + "/" + subnetMaskLength
218                 + ((vlan == 0) ? "" : (" vlan=" + vlan)) + " "
219                 + ((isFlatLayer2()) ? "{[*, *]}" : nodeConnectors.toString()) + "]");
220     }
221
222     public boolean hasNodeConnector(NodeConnector p) {
223         if (p == null) {
224             return false;
225         }
226         if (this.isFlatLayer2()) {
227             return true;
228         }
229         return this.nodeConnectors.contains(p);
230     }
231
232     public boolean isMutualExclusive(Subnet otherSubnet) {
233         if (this.networkAddress.getClass() != otherSubnet.networkAddress
234                 .getClass())
235             return true;
236         if (this.isSubnetOf(otherSubnet.getNetworkAddress())) {
237             return false;
238         }
239         if (otherSubnet.isSubnetOf(this.getNetworkAddress())) {
240             return false;
241         }
242         return true;
243     }
244 }