blob: 4bf196d75d39d30c4ae8f96bc3e00c630f55eb71 [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2014-present Open Networking Laboratory
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07003 *
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 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.net.host;
Pavlin Radoslavov276cd902014-10-24 16:28:01 -070017
Pavlin Radoslavov276cd902014-10-24 16:28:01 -070018import org.onlab.packet.IpAddress;
19import org.onlab.packet.IpPrefix;
20
Jonathan Hart111b42b2015-07-14 13:28:05 -070021import java.util.Objects;
22
23import static com.google.common.base.Preconditions.checkArgument;
Pavlin Radoslavov276cd902014-10-24 16:28:01 -070024import static com.google.common.base.Preconditions.checkNotNull;
25
26/**
27 * Represents a single IP address information on an interface.
28 *
29 * TODO:
30 * - Add computation for the default broadcast address if it is not
31 * specified
32 * - Add explicit checks that each IP address or prefix belong to the
33 * same IP version: IPv4/IPv6.
34 * - Inside the copy constructor we should use copy constructors for each
35 * field
36 */
37public class InterfaceIpAddress {
38 private final IpAddress ipAddress;
39 private final IpPrefix subnetAddress;
40 private final IpAddress broadcastAddress;
41 private final IpAddress peerAddress;
42
43 /**
44 * Copy constructor.
45 *
46 * @param other the object to copy from
47 */
48 public InterfaceIpAddress(InterfaceIpAddress other) {
49 // TODO: we should use copy constructors for each field
50 this.ipAddress = other.ipAddress;
51 this.subnetAddress = other.subnetAddress;
52 this.broadcastAddress = other.broadcastAddress;
53 this.peerAddress = other.peerAddress;
54 }
55
56 /**
57 * Constructor for a given IP address and a subnet address.
58 *
59 * @param ipAddress the IP address
60 * @param subnetAddress the IP subnet address
61 */
62 public InterfaceIpAddress(IpAddress ipAddress, IpPrefix subnetAddress) {
Srinivas Bandibc38cd42016-08-05 13:46:10 +053063 checkArgument(checkNotNull(ipAddress).version() == checkNotNull(subnetAddress).version(),
64 "IP and subnet version mismatch");
65 this.ipAddress = ipAddress;
66 this.subnetAddress = subnetAddress;
67 this.broadcastAddress = computeBroadcastAddress(ipAddress, subnetAddress);
Pavlin Radoslavov276cd902014-10-24 16:28:01 -070068 this.peerAddress = null;
69 }
70
71 /**
72 * Constructor for a given IP address and a subnet address.
73 *
74 * @param ipAddress the IP address
75 * @param subnetAddress the IP subnet address
76 * @param broadcastAddress the IP broadcast address. It can be used
77 * to specify non-default broadcast address
78 */
79 public InterfaceIpAddress(IpAddress ipAddress, IpPrefix subnetAddress,
80 IpAddress broadcastAddress) {
Srinivas Bandibc38cd42016-08-05 13:46:10 +053081 checkArgument(checkNotNull(ipAddress).version() == checkNotNull(subnetAddress).version(),
82 "IP and subnet version mismatch");
83 this.ipAddress = ipAddress;
84 this.subnetAddress = subnetAddress;
Pavlin Radoslavov276cd902014-10-24 16:28:01 -070085 this.broadcastAddress = broadcastAddress;
86 this.peerAddress = null;
87 }
88
89 /**
90 * Constructor for a given IP address and a subnet address.
91 *
92 * @param ipAddress the IP address
93 * @param subnetAddress the IP subnet address
94 * @param broadcastAddress the IP broadcast address. It can be used
95 * to specify non-default broadcast address. It should be null for
96 * point-to-point interfaces with a peer address
97 * @param peerAddress the peer IP address for point-to-point interfaces
98 */
99 public InterfaceIpAddress(IpAddress ipAddress, IpPrefix subnetAddress,
100 IpAddress broadcastAddress,
101 IpAddress peerAddress) {
Srinivas Bandibc38cd42016-08-05 13:46:10 +0530102 checkArgument(checkNotNull(ipAddress).version() == checkNotNull(subnetAddress).version(),
103 "IP and subnet version mismatch");
104 this.ipAddress = ipAddress;
105 this.subnetAddress = subnetAddress;
Pavlin Radoslavov276cd902014-10-24 16:28:01 -0700106 this.broadcastAddress = broadcastAddress;
107 this.peerAddress = peerAddress;
108 }
109
110 /**
111 * Gets the IP address.
112 *
113 * @return the IP address
114 */
115 public IpAddress ipAddress() {
116 return ipAddress;
117 }
118
119 /**
120 * Gets the IP subnet address.
121 *
122 * @return the IP subnet address
123 */
124 public IpPrefix subnetAddress() {
125 return subnetAddress;
126 }
127
128 /**
129 * Gets the subnet IP broadcast address.
130 *
131 * @return the subnet IP broadcast address
132 */
133 public IpAddress broadcastAddress() {
134 return broadcastAddress;
135 }
136
137 /**
138 * Gets the IP point-to-point interface peer address.
139 *
140 * @return the IP point-to-point interface peer address
141 */
142 public IpAddress peerAddress() {
143 return peerAddress;
144 }
145
Jonathan Hart111b42b2015-07-14 13:28:05 -0700146 /**
147 * Converts a CIDR string literal to an interface IP address.
148 * E.g. 10.0.0.1/24
149 *
150 * @param value an IP address value in string form
151 * @return an interface IP address
152 * @throws IllegalArgumentException if the argument is invalid
153 */
154 public static InterfaceIpAddress valueOf(String value) {
155 String[] splits = value.split("/");
156 checkArgument(splits.length == 2, "Invalid IP address and prefix length format");
157
158 // NOTE: IpPrefix will mask-out the bits after the prefix length.
159 IpPrefix subnet = IpPrefix.valueOf(value);
160 IpAddress addr = IpAddress.valueOf(splits[0]);
161 return new InterfaceIpAddress(addr, subnet);
162 }
163
Srinivas Bandibc38cd42016-08-05 13:46:10 +0530164 /**
165 * Compute the IP broadcast address.
166 *
167 * @return the IP broadcast address
168 */
169 public static IpAddress computeBroadcastAddress(IpAddress ipAddress, IpPrefix subnetAddress) {
170 if (ipAddress.isIp6()) {
171 return null;
172 } else {
173 IpAddress maskedIP = IpAddress.makeMaskedAddress(ipAddress, subnetAddress.prefixLength());
174 int ipB = maskedIP.getIp4Address().toInt() | ((1 << (32 - subnetAddress.prefixLength())) - 1);
175 return IpAddress.valueOf(ipB);
176 }
177 }
178
Pavlin Radoslavov276cd902014-10-24 16:28:01 -0700179 @Override
180 public boolean equals(Object other) {
181 if (other == this) {
182 return true;
183 }
184 if (!(other instanceof InterfaceIpAddress)) {
185 return false;
186 }
187 InterfaceIpAddress otherAddr = (InterfaceIpAddress) other;
188
189 return Objects.equals(this.ipAddress, otherAddr.ipAddress)
190 && Objects.equals(this.subnetAddress, otherAddr.subnetAddress)
191 && Objects.equals(this.broadcastAddress,
192 otherAddr.broadcastAddress)
193 && Objects.equals(this.peerAddress, otherAddr.peerAddress);
194 }
195
196 @Override
197 public int hashCode() {
198 return Objects.hash(ipAddress, subnetAddress, broadcastAddress,
199 peerAddress);
200 }
201
202 @Override
203 public String toString() {
Jonathan Hart111b42b2015-07-14 13:28:05 -0700204 return ipAddress.toString() + "/" + subnetAddress.prefixLength();
Pavlin Radoslavov276cd902014-10-24 16:28:01 -0700205 }
206}