blob: 6e546a85665d46216571f5bbf1983cb737be800d [file] [log] [blame]
Thomas Vachuska96d55b12015-05-11 08:52:03 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Thomas Vachuska96d55b12015-05-11 08:52:03 -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 */
Thomas Vachuska4998caa2015-08-26 13:28:38 -070016package org.onosproject.net.config.basics;
Thomas Vachuska96d55b12015-05-11 08:52:03 -070017
Charles Chand6d581a2015-11-18 16:51:08 -080018import com.fasterxml.jackson.databind.node.ArrayNode;
Szymon Giermakowskif3578de2017-08-29 22:02:48 +020019import com.google.common.collect.ImmutableSet;
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -070020import org.onlab.packet.EthType;
Charles Chand6d581a2015-11-18 16:51:08 -080021import org.onlab.packet.IpAddress;
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -070022import org.onlab.packet.VlanId;
Charles Chand6d581a2015-11-18 16:51:08 -080023import org.onosproject.net.ConnectPoint;
Thomas Vachuska96d55b12015-05-11 08:52:03 -070024import org.onosproject.net.HostId;
Charles Chan61fc0d82017-04-28 14:13:36 -070025import org.onosproject.net.HostLocation;
Thomas Vachuska36008462016-01-07 15:38:20 -080026
Charles Chand6d581a2015-11-18 16:51:08 -080027import java.util.HashSet;
28import java.util.Set;
Thomas Vachuska96d55b12015-05-11 08:52:03 -070029
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -070030import static com.google.common.base.Preconditions.checkArgument;
31
Thomas Vachuska96d55b12015-05-11 08:52:03 -070032/**
33 * Basic configuration for network end-station hosts.
34 */
Thomas Vachuska36008462016-01-07 15:38:20 -080035public final class BasicHostConfig extends BasicElementConfig<HostId> {
36
Charles Chand6d581a2015-11-18 16:51:08 -080037 private static final String IPS = "ips";
Charles Chan61fc0d82017-04-28 14:13:36 -070038 private static final String LOCATIONS = "locations";
Charles Chaneb5bd492019-12-18 15:49:39 -080039 private static final String AUX_LOCATIONS = "auxLocations";
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -070040 private static final String INNER_VLAN = "innerVlan";
41 private static final String OUTER_TPID = "outerTpid";
Simon Hunt10618f62017-06-15 19:30:52 -070042 private static final String DASH = "-";
Thomas Vachuska96d55b12015-05-11 08:52:03 -070043
Charles Chand6d581a2015-11-18 16:51:08 -080044 @Override
45 public boolean isValid() {
Charles Chan60c45282017-07-11 15:07:59 -070046 // locations is mandatory and must have at least one
47 // ipAddresses can be absent, but if present must be valid
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -070048 // innerVlan: 0 < innerVlan < VlanId.MAX_VLAN, if present
49 // outerTpid: either 0x8100 or 0x88a8, if present
50 if (!isIntegralNumber(object, INNER_VLAN, FieldPresence.OPTIONAL, 0, VlanId.MAX_VLAN)) {
51 return false;
52 }
53 checkArgument(!hasField(object, OUTER_TPID) ||
54 (short) (Integer.decode(get(OUTER_TPID, "0")) & 0xFFFF) ==
55 EthType.EtherType.QINQ.ethType().toShort() ||
56 (short) (Integer.decode(get(OUTER_TPID, "0")) & 0xFFFF) ==
57 EthType.EtherType.VLAN.ethType().toShort());
Charles Chan61fc0d82017-04-28 14:13:36 -070058 this.locations();
Thomas Vachuska36008462016-01-07 15:38:20 -080059 this.ipAddresses();
Charles Chaneb5bd492019-12-18 15:49:39 -080060 this.auxLocations();
Thomas Vachuska345b0c72018-04-16 12:52:00 -070061 return hasOnlyFields(ALLOWED, NAME, LOC_TYPE, LATITUDE, LONGITUDE, ROLES,
Charles Chaneb5bd492019-12-18 15:49:39 -080062 GRID_X, GRID_Y, UI_TYPE, RACK_ADDRESS, OWNER, IPS, LOCATIONS, AUX_LOCATIONS,
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -070063 INNER_VLAN, OUTER_TPID);
Charles Chand6d581a2015-11-18 16:51:08 -080064 }
Thomas Vachuska96d55b12015-05-11 08:52:03 -070065
Simon Hunt10618f62017-06-15 19:30:52 -070066 @Override
67 public String name() {
68 // NOTE:
69 // We don't want to default to host ID if friendly name is not set;
70 // (it isn't particularly friendly, e.g. "00:00:00:00:00:01/None").
71 // We'd prefer to clear the annotation, but if we pass null, then the
72 // value won't get set (see BasicElementOperator). So, instead we will
73 // return a DASH to signify "use the default friendly name".
74 return get(NAME, DASH);
75 }
76
Charles Chand6d581a2015-11-18 16:51:08 -080077 /**
Simon Hunt1e20dae2016-10-28 11:26:26 -070078 * Returns the location of the host.
Charles Chand6d581a2015-11-18 16:51:08 -080079 *
Szymon Giermakowskif3578de2017-08-29 22:02:48 +020080 * @return location of the host or null if none specified
81 * @throws IllegalArgumentException if locations are set but empty or not
82 * specified with correct format
Charles Chand6d581a2015-11-18 16:51:08 -080083 */
Charles Chan61fc0d82017-04-28 14:13:36 -070084 public Set<HostLocation> locations() {
Szymon Giermakowskif3578de2017-08-29 22:02:48 +020085 if (!object.has(LOCATIONS)) {
86 return null; //no locations are specified
Charles Chan61fc0d82017-04-28 14:13:36 -070087 }
Szymon Giermakowskif3578de2017-08-29 22:02:48 +020088
89 ImmutableSet.Builder<HostLocation> locationsSetBuilder = ImmutableSet.<HostLocation>builder();
90
91 ArrayNode locationNodes = (ArrayNode) object.path(LOCATIONS);
92 locationNodes.forEach(n -> {
93 ConnectPoint cp = ConnectPoint.deviceConnectPoint((n.asText()));
94 locationsSetBuilder.add(new HostLocation(cp, 0));
95 });
96
97
98 Set<HostLocation> locations = locationsSetBuilder.build();
Charles Chan60c45282017-07-11 15:07:59 -070099 if (locations.isEmpty()) {
100 throw new IllegalArgumentException("Host should have at least one location");
101 }
Szymon Giermakowskif3578de2017-08-29 22:02:48 +0200102
Charles Chan60c45282017-07-11 15:07:59 -0700103 return locations;
Charles Chand6d581a2015-11-18 16:51:08 -0800104 }
105
106 /**
Charles Chaneb5bd492019-12-18 15:49:39 -0800107 * Returns the auxLocations of the host.
108 *
109 * @return auxLocations of the host or null if none specified
110 * @throws IllegalArgumentException if auxLocations are set but empty or not
111 * specified with correct format
112 */
113 public Set<HostLocation> auxLocations() {
114 if (!object.has(AUX_LOCATIONS)) {
115 return null; //no auxLocations are specified
116 }
117
118 ImmutableSet.Builder<HostLocation> auxLocationsSetBuilder = ImmutableSet.<HostLocation>builder();
119
120 ArrayNode auxLocationNodes = (ArrayNode) object.path(AUX_LOCATIONS);
121 auxLocationNodes.forEach(n -> {
122 ConnectPoint cp = ConnectPoint.deviceConnectPoint((n.asText()));
123 auxLocationsSetBuilder.add(new HostLocation(cp, 0));
124 });
125
126 return auxLocationsSetBuilder.build();
127 }
128
129 /**
Charles Chand6d581a2015-11-18 16:51:08 -0800130 * Sets the location of the host.
131 *
Charles Chan61fc0d82017-04-28 14:13:36 -0700132 * @param locations location of the host or null to unset
Thomas Vachuska36008462016-01-07 15:38:20 -0800133 * @return the config of the host
Charles Chand6d581a2015-11-18 16:51:08 -0800134 */
Charles Chan61fc0d82017-04-28 14:13:36 -0700135 public BasicHostConfig setLocations(Set<HostLocation> locations) {
136 return (BasicHostConfig) setOrClear(LOCATIONS, locations);
Charles Chand6d581a2015-11-18 16:51:08 -0800137 }
138
139 /**
Charles Chaneb5bd492019-12-18 15:49:39 -0800140 * Sets the auxLocations of the host.
141 *
142 * @param auxLocations auxLocations of the host or null to unset
143 * @return the config of the host
144 */
145 public BasicHostConfig setAuxLocations(Set<HostLocation> auxLocations) {
146 return (BasicHostConfig) setOrClear(AUX_LOCATIONS, auxLocations);
147 }
148
149
150 /**
Thomas Vachuska36008462016-01-07 15:38:20 -0800151 * Returns IP addresses of the host.
Charles Chand6d581a2015-11-18 16:51:08 -0800152 *
Thomas Vachuska36008462016-01-07 15:38:20 -0800153 * @return IP addresses of the host or null if not set
154 * @throws IllegalArgumentException if not specified with correct format
Charles Chand6d581a2015-11-18 16:51:08 -0800155 */
156 public Set<IpAddress> ipAddresses() {
157 HashSet<IpAddress> ipAddresses = new HashSet<>();
158 if (object.has(IPS)) {
159 ArrayNode ipNodes = (ArrayNode) object.path(IPS);
Thomas Vachuska36008462016-01-07 15:38:20 -0800160 ipNodes.forEach(n -> ipAddresses.add(IpAddress.valueOf(n.asText())));
161 return ipAddresses;
Charles Chand6d581a2015-11-18 16:51:08 -0800162 }
163 return null;
164 }
165
166 /**
167 * Sets the IP addresses of the host.
168 *
Thomas Vachuska36008462016-01-07 15:38:20 -0800169 * @param ipAddresses IP addresses of the host or null to unset
170 * @return the config of the host
Charles Chand6d581a2015-11-18 16:51:08 -0800171 */
172 public BasicHostConfig setIps(Set<IpAddress> ipAddresses) {
173 return (BasicHostConfig) setOrClear(IPS, ipAddresses);
174 }
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -0700175
176 public VlanId innerVlan() {
177 String vlan = get(INNER_VLAN, null);
178 return vlan == null ? VlanId.NONE : VlanId.vlanId(Short.valueOf(vlan));
179 }
180
181 public BasicHostConfig setInnerVlan(VlanId vlanId) {
182 return (BasicHostConfig) setOrClear(INNER_VLAN, vlanId.toString());
183 }
184
185 public EthType outerTpid() {
Jonghwan Hyun800d9d02018-04-09 09:40:50 -0700186 short tpid = (short) (Integer.decode(get(OUTER_TPID, "0x8100")) & 0xFFFF);
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -0700187 if (!(tpid == EthType.EtherType.VLAN.ethType().toShort() ||
188 tpid == EthType.EtherType.QINQ.ethType().toShort())) {
189 return EthType.EtherType.UNKNOWN.ethType();
190 }
191 return EthType.EtherType.lookup(tpid).ethType();
192 }
193
194 public BasicHostConfig setOuterTpid(EthType tpid) {
195 return (BasicHostConfig) setOrClear(OUTER_TPID, String.format("0x%04X", tpid.toShort()));
196 }
197}