blob: 3d190032886c584e30225c693c481e68b199123f [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";
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -070039 private static final String INNER_VLAN = "innerVlan";
40 private static final String OUTER_TPID = "outerTpid";
Simon Hunt10618f62017-06-15 19:30:52 -070041 private static final String DASH = "-";
Thomas Vachuska96d55b12015-05-11 08:52:03 -070042
Charles Chand6d581a2015-11-18 16:51:08 -080043 @Override
44 public boolean isValid() {
Charles Chan60c45282017-07-11 15:07:59 -070045 // locations is mandatory and must have at least one
46 // ipAddresses can be absent, but if present must be valid
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -070047 // innerVlan: 0 < innerVlan < VlanId.MAX_VLAN, if present
48 // outerTpid: either 0x8100 or 0x88a8, if present
49 if (!isIntegralNumber(object, INNER_VLAN, FieldPresence.OPTIONAL, 0, VlanId.MAX_VLAN)) {
50 return false;
51 }
52 checkArgument(!hasField(object, OUTER_TPID) ||
53 (short) (Integer.decode(get(OUTER_TPID, "0")) & 0xFFFF) ==
54 EthType.EtherType.QINQ.ethType().toShort() ||
55 (short) (Integer.decode(get(OUTER_TPID, "0")) & 0xFFFF) ==
56 EthType.EtherType.VLAN.ethType().toShort());
Charles Chan61fc0d82017-04-28 14:13:36 -070057 this.locations();
Thomas Vachuska36008462016-01-07 15:38:20 -080058 this.ipAddresses();
Thomas Vachuska345b0c72018-04-16 12:52:00 -070059 return hasOnlyFields(ALLOWED, NAME, LOC_TYPE, LATITUDE, LONGITUDE, ROLES,
60 GRID_X, GRID_Y, UI_TYPE, RACK_ADDRESS, OWNER, IPS, LOCATIONS,
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -070061 INNER_VLAN, OUTER_TPID);
Charles Chand6d581a2015-11-18 16:51:08 -080062 }
Thomas Vachuska96d55b12015-05-11 08:52:03 -070063
Simon Hunt10618f62017-06-15 19:30:52 -070064 @Override
65 public String name() {
66 // NOTE:
67 // We don't want to default to host ID if friendly name is not set;
68 // (it isn't particularly friendly, e.g. "00:00:00:00:00:01/None").
69 // We'd prefer to clear the annotation, but if we pass null, then the
70 // value won't get set (see BasicElementOperator). So, instead we will
71 // return a DASH to signify "use the default friendly name".
72 return get(NAME, DASH);
73 }
74
Charles Chand6d581a2015-11-18 16:51:08 -080075 /**
Simon Hunt1e20dae2016-10-28 11:26:26 -070076 * Returns the location of the host.
Charles Chand6d581a2015-11-18 16:51:08 -080077 *
Szymon Giermakowskif3578de2017-08-29 22:02:48 +020078 * @return location of the host or null if none specified
79 * @throws IllegalArgumentException if locations are set but empty or not
80 * specified with correct format
Charles Chand6d581a2015-11-18 16:51:08 -080081 */
Charles Chan61fc0d82017-04-28 14:13:36 -070082 public Set<HostLocation> locations() {
Szymon Giermakowskif3578de2017-08-29 22:02:48 +020083 if (!object.has(LOCATIONS)) {
84 return null; //no locations are specified
Charles Chan61fc0d82017-04-28 14:13:36 -070085 }
Szymon Giermakowskif3578de2017-08-29 22:02:48 +020086
87 ImmutableSet.Builder<HostLocation> locationsSetBuilder = ImmutableSet.<HostLocation>builder();
88
89 ArrayNode locationNodes = (ArrayNode) object.path(LOCATIONS);
90 locationNodes.forEach(n -> {
91 ConnectPoint cp = ConnectPoint.deviceConnectPoint((n.asText()));
92 locationsSetBuilder.add(new HostLocation(cp, 0));
93 });
94
95
96 Set<HostLocation> locations = locationsSetBuilder.build();
Charles Chan60c45282017-07-11 15:07:59 -070097 if (locations.isEmpty()) {
98 throw new IllegalArgumentException("Host should have at least one location");
99 }
Szymon Giermakowskif3578de2017-08-29 22:02:48 +0200100
Charles Chan60c45282017-07-11 15:07:59 -0700101 return locations;
Charles Chand6d581a2015-11-18 16:51:08 -0800102 }
103
104 /**
105 * Sets the location of the host.
106 *
Charles Chan61fc0d82017-04-28 14:13:36 -0700107 * @param locations location of the host or null to unset
Thomas Vachuska36008462016-01-07 15:38:20 -0800108 * @return the config of the host
Charles Chand6d581a2015-11-18 16:51:08 -0800109 */
Charles Chan61fc0d82017-04-28 14:13:36 -0700110 public BasicHostConfig setLocations(Set<HostLocation> locations) {
111 return (BasicHostConfig) setOrClear(LOCATIONS, locations);
Charles Chand6d581a2015-11-18 16:51:08 -0800112 }
113
114 /**
Thomas Vachuska36008462016-01-07 15:38:20 -0800115 * Returns IP addresses of the host.
Charles Chand6d581a2015-11-18 16:51:08 -0800116 *
Thomas Vachuska36008462016-01-07 15:38:20 -0800117 * @return IP addresses of the host or null if not set
118 * @throws IllegalArgumentException if not specified with correct format
Charles Chand6d581a2015-11-18 16:51:08 -0800119 */
120 public Set<IpAddress> ipAddresses() {
121 HashSet<IpAddress> ipAddresses = new HashSet<>();
122 if (object.has(IPS)) {
123 ArrayNode ipNodes = (ArrayNode) object.path(IPS);
Thomas Vachuska36008462016-01-07 15:38:20 -0800124 ipNodes.forEach(n -> ipAddresses.add(IpAddress.valueOf(n.asText())));
125 return ipAddresses;
Charles Chand6d581a2015-11-18 16:51:08 -0800126 }
127 return null;
128 }
129
130 /**
131 * Sets the IP addresses of the host.
132 *
Thomas Vachuska36008462016-01-07 15:38:20 -0800133 * @param ipAddresses IP addresses of the host or null to unset
134 * @return the config of the host
Charles Chand6d581a2015-11-18 16:51:08 -0800135 */
136 public BasicHostConfig setIps(Set<IpAddress> ipAddresses) {
137 return (BasicHostConfig) setOrClear(IPS, ipAddresses);
138 }
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -0700139
140 public VlanId innerVlan() {
141 String vlan = get(INNER_VLAN, null);
142 return vlan == null ? VlanId.NONE : VlanId.vlanId(Short.valueOf(vlan));
143 }
144
145 public BasicHostConfig setInnerVlan(VlanId vlanId) {
146 return (BasicHostConfig) setOrClear(INNER_VLAN, vlanId.toString());
147 }
148
149 public EthType outerTpid() {
Jonghwan Hyun800d9d02018-04-09 09:40:50 -0700150 short tpid = (short) (Integer.decode(get(OUTER_TPID, "0x8100")) & 0xFFFF);
Jonghwan Hyun2c95acf2018-03-14 16:47:34 -0700151 if (!(tpid == EthType.EtherType.VLAN.ethType().toShort() ||
152 tpid == EthType.EtherType.QINQ.ethType().toShort())) {
153 return EthType.EtherType.UNKNOWN.ethType();
154 }
155 return EthType.EtherType.lookup(tpid).ethType();
156 }
157
158 public BasicHostConfig setOuterTpid(EthType tpid) {
159 return (BasicHostConfig) setOrClear(OUTER_TPID, String.format("0x%04X", tpid.toShort()));
160 }
161}