blob: 9741f7896053ed9f76461fe42453eff30f958d54 [file] [log] [blame]
Charles Chan5270ed02016-01-30 23:22:37 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Charles Chan5270ed02016-01-30 23:22:37 -08003 *
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 */
16
17package org.onosproject.segmentrouting.config;
18
19import com.fasterxml.jackson.databind.JsonNode;
20import com.fasterxml.jackson.databind.node.ArrayNode;
21import com.google.common.collect.ImmutableSet;
Andrea Campanellad980c6d2018-04-30 11:48:55 +020022import org.onlab.packet.IpPrefix;
Charles Chan5270ed02016-01-30 23:22:37 -080023import org.onlab.packet.MacAddress;
24import org.onosproject.core.ApplicationId;
Charles Chand9681e72016-02-22 19:27:29 -080025import org.onosproject.net.ConnectPoint;
Charles Chan5270ed02016-01-30 23:22:37 -080026import org.onosproject.net.config.Config;
Charles Chand9681e72016-02-22 19:27:29 -080027
Charles Chan5270ed02016-01-30 23:22:37 -080028import java.util.Set;
29
30import static com.google.common.base.MoreObjects.toStringHelper;
31
32/**
33 * App configuration object for Segment Routing.
34 */
35public class SegmentRoutingAppConfig extends Config<ApplicationId> {
36 private static final String VROUTER_MACS = "vRouterMacs";
Charles Chand9681e72016-02-22 19:27:29 -080037 private static final String SUPPRESS_SUBNET = "suppressSubnet";
Charles Chanb3007e12016-05-20 10:55:40 -070038 private static final String SUPPRESS_HOST_BY_PORT = "suppressHostByPort";
39 // TODO We might want to move SUPPRESS_HOST_BY_PROVIDER to Component Config
40 private static final String SUPPRESS_HOST_BY_PROVIDER = "suppressHostByProvider";
Pier Ventre98161782016-10-31 15:00:01 -070041 private static final String MPLS_ECMP = "MPLS-ECMP";
Andrea Campanellad980c6d2018-04-30 11:48:55 +020042 private static final String BLACKHOLE_IPS = "blackholeIps";
Charles Chan5270ed02016-01-30 23:22:37 -080043
44 @Override
45 public boolean isValid() {
Charles Chan03a73e02016-10-24 14:52:01 -070046 return hasOnlyFields(VROUTER_MACS, SUPPRESS_SUBNET,
Andrea Campanellad980c6d2018-04-30 11:48:55 +020047 SUPPRESS_HOST_BY_PORT, SUPPRESS_HOST_BY_PROVIDER, MPLS_ECMP, BLACKHOLE_IPS) &&
Charles Chan03a73e02016-10-24 14:52:01 -070048 vRouterMacs() != null &&
Charles Chanb3007e12016-05-20 10:55:40 -070049 suppressSubnet() != null && suppressHostByPort() != null &&
Andrea Campanellad980c6d2018-04-30 11:48:55 +020050 suppressHostByProvider() != null &&
51 blackholeIPs() != null;
52 }
53
54 /**
55 * Gets ips to blackhole from the config.
56 *
57 * @return Set of ips to blackhole, empty is not specified,
58 * or null if not valid
59 */
60 public Set<IpPrefix> blackholeIPs() {
61 if (!object.has(BLACKHOLE_IPS)) {
62 return ImmutableSet.of();
63 }
64
65 ImmutableSet.Builder<IpPrefix> builder = ImmutableSet.builder();
66 ArrayNode arrayNode = (ArrayNode) object.path(BLACKHOLE_IPS);
67 for (JsonNode jsonNode : arrayNode) {
68 IpPrefix address;
69
70 String addrStr = jsonNode.asText(null);
71 if (addrStr == null) {
72 return null;
73 }
74 try {
75 address = IpPrefix.valueOf(addrStr);
76 } catch (IllegalArgumentException e) {
77 return null;
78 }
79
80 builder.add(address);
81 }
82 return builder.build();
83 }
84
85 /**
86 * Sets ips to blackhole to the config.
87 *
88 * @param blackholeIps a set of ips to blackhole
89 * @return this {@link SegmentRoutingAppConfig}
90 */
91 public SegmentRoutingAppConfig setBalckholeIps(Set<IpPrefix> blackholeIps) {
92 if (blackholeIps == null) {
93 object.remove(BLACKHOLE_IPS);
94 } else {
95 ArrayNode arrayNode = mapper.createArrayNode();
96
97 blackholeIps.forEach(ip -> {
98 arrayNode.add(ip.toString());
99 });
100
101 object.set(BLACKHOLE_IPS, arrayNode);
102 }
103 return this;
Charles Chan5270ed02016-01-30 23:22:37 -0800104 }
105
106 /**
Pier Ventre98161782016-10-31 15:00:01 -0700107 * Gets MPLS-ECMP configuration from the config.
108 *
109 * @return the configuration of MPLS-ECMP. If it is not
110 * specified, the default behavior is false.
111 */
112 public boolean mplsEcmp() {
113 return get(MPLS_ECMP, false);
114 }
115
116 /**
117 * Sets MPLS-ECMP to the config.
118 *
119 * @param mplsEcmp the MPLS-ECMP configuration
120 * @return this {@link SegmentRoutingAppConfig}
121 */
122 public SegmentRoutingAppConfig setMplsEcmp(boolean mplsEcmp) {
123 object.put(MPLS_ECMP, mplsEcmp);
124 return this;
125 }
126
127 /**
Charles Chan5270ed02016-01-30 23:22:37 -0800128 * Gets vRouters from the config.
129 *
Charles Chand9681e72016-02-22 19:27:29 -0800130 * @return Set of vRouter MAC addresses, empty is not specified,
131 * or null if not valid
Charles Chan5270ed02016-01-30 23:22:37 -0800132 */
133 public Set<MacAddress> vRouterMacs() {
134 if (!object.has(VROUTER_MACS)) {
Charles Chand9681e72016-02-22 19:27:29 -0800135 return ImmutableSet.of();
Charles Chan5270ed02016-01-30 23:22:37 -0800136 }
137
138 ImmutableSet.Builder<MacAddress> builder = ImmutableSet.builder();
139 ArrayNode arrayNode = (ArrayNode) object.path(VROUTER_MACS);
140 for (JsonNode jsonNode : arrayNode) {
141 MacAddress mac;
142
143 String macStr = jsonNode.asText(null);
144 if (macStr == null) {
145 return null;
146 }
147 try {
148 mac = MacAddress.valueOf(macStr);
149 } catch (IllegalArgumentException e) {
150 return null;
151 }
152
153 builder.add(mac);
154 }
155 return builder.build();
156 }
157
158 /**
159 * Sets vRouters to the config.
160 *
161 * @param vRouterMacs a set of vRouter MAC addresses
162 * @return this {@link SegmentRoutingAppConfig}
163 */
164 public SegmentRoutingAppConfig setVRouterMacs(Set<MacAddress> vRouterMacs) {
165 if (vRouterMacs == null) {
166 object.remove(VROUTER_MACS);
167 } else {
168 ArrayNode arrayNode = mapper.createArrayNode();
169
170 vRouterMacs.forEach(mac -> {
171 arrayNode.add(mac.toString());
172 });
173
174 object.set(VROUTER_MACS, arrayNode);
175 }
176 return this;
177 }
178
Charles Chanf2565a92016-02-10 20:46:58 -0800179 /**
Charles Chand9681e72016-02-22 19:27:29 -0800180 * Gets names of ports to which SegmentRouting does not push subnet rules.
Charles Chanf2565a92016-02-10 20:46:58 -0800181 *
Charles Chand9681e72016-02-22 19:27:29 -0800182 * @return Set of port names, empty if not specified, or null
183 * if not valid
Charles Chanf2565a92016-02-10 20:46:58 -0800184 */
Charles Chand9681e72016-02-22 19:27:29 -0800185 public Set<ConnectPoint> suppressSubnet() {
186 if (!object.has(SUPPRESS_SUBNET)) {
187 return ImmutableSet.of();
Charles Chanf2565a92016-02-10 20:46:58 -0800188 }
189
Charles Chand9681e72016-02-22 19:27:29 -0800190 ImmutableSet.Builder<ConnectPoint> builder = ImmutableSet.builder();
191 ArrayNode arrayNode = (ArrayNode) object.path(SUPPRESS_SUBNET);
Charles Chanf2565a92016-02-10 20:46:58 -0800192 for (JsonNode jsonNode : arrayNode) {
193 String portName = jsonNode.asText(null);
194 if (portName == null) {
195 return null;
196 }
Charles Chand9681e72016-02-22 19:27:29 -0800197 try {
198 builder.add(ConnectPoint.deviceConnectPoint(portName));
199 } catch (IllegalArgumentException e) {
200 return null;
201 }
Charles Chanf2565a92016-02-10 20:46:58 -0800202 }
203 return builder.build();
204 }
205
206 /**
Charles Chand9681e72016-02-22 19:27:29 -0800207 * Sets names of ports to which SegmentRouting does not push subnet rules.
Charles Chanf2565a92016-02-10 20:46:58 -0800208 *
Charles Chand9681e72016-02-22 19:27:29 -0800209 * @param suppressSubnet names of ports to which SegmentRouting does not push
210 * subnet rules
Charles Chanf2565a92016-02-10 20:46:58 -0800211 * @return this {@link SegmentRoutingAppConfig}
212 */
Charles Chand9681e72016-02-22 19:27:29 -0800213 public SegmentRoutingAppConfig setSuppressSubnet(Set<ConnectPoint> suppressSubnet) {
214 if (suppressSubnet == null) {
215 object.remove(SUPPRESS_SUBNET);
Charles Chanf2565a92016-02-10 20:46:58 -0800216 } else {
217 ArrayNode arrayNode = mapper.createArrayNode();
Charles Chand9681e72016-02-22 19:27:29 -0800218 suppressSubnet.forEach(connectPoint -> {
219 arrayNode.add(connectPoint.deviceId() + "/" + connectPoint.port());
Charles Chanf2565a92016-02-10 20:46:58 -0800220 });
Charles Chand9681e72016-02-22 19:27:29 -0800221 object.set(SUPPRESS_SUBNET, arrayNode);
222 }
223 return this;
224 }
225
226 /**
Charles Chanb3007e12016-05-20 10:55:40 -0700227 * Gets connect points to which SegmentRouting does not push host rules.
Charles Chand9681e72016-02-22 19:27:29 -0800228 *
Charles Chanb3007e12016-05-20 10:55:40 -0700229 * @return Set of connect points, empty if not specified, or null
Charles Chand9681e72016-02-22 19:27:29 -0800230 * if not valid
231 */
Charles Chanb3007e12016-05-20 10:55:40 -0700232 public Set<ConnectPoint> suppressHostByPort() {
233 if (!object.has(SUPPRESS_HOST_BY_PORT)) {
Charles Chand9681e72016-02-22 19:27:29 -0800234 return ImmutableSet.of();
235 }
236
237 ImmutableSet.Builder<ConnectPoint> builder = ImmutableSet.builder();
Charles Chanb3007e12016-05-20 10:55:40 -0700238 ArrayNode arrayNode = (ArrayNode) object.path(SUPPRESS_HOST_BY_PORT);
Charles Chand9681e72016-02-22 19:27:29 -0800239 for (JsonNode jsonNode : arrayNode) {
240 String portName = jsonNode.asText(null);
241 if (portName == null) {
242 return null;
243 }
244 try {
245 builder.add(ConnectPoint.deviceConnectPoint(portName));
246 } catch (IllegalArgumentException e) {
247 return null;
248 }
249 }
250 return builder.build();
251 }
252
253 /**
Charles Chanb3007e12016-05-20 10:55:40 -0700254 * Sets connect points to which SegmentRouting does not push host rules.
Charles Chand9681e72016-02-22 19:27:29 -0800255 *
Charles Chanb3007e12016-05-20 10:55:40 -0700256 * @param connectPoints connect points to which SegmentRouting does not push
Charles Chand9681e72016-02-22 19:27:29 -0800257 * host rules
258 * @return this {@link SegmentRoutingAppConfig}
259 */
Charles Chanb3007e12016-05-20 10:55:40 -0700260 public SegmentRoutingAppConfig setSuppressHostByPort(Set<ConnectPoint> connectPoints) {
261 if (connectPoints == null) {
262 object.remove(SUPPRESS_HOST_BY_PORT);
Charles Chand9681e72016-02-22 19:27:29 -0800263 } else {
264 ArrayNode arrayNode = mapper.createArrayNode();
Charles Chanb3007e12016-05-20 10:55:40 -0700265 connectPoints.forEach(connectPoint -> {
Charles Chand9681e72016-02-22 19:27:29 -0800266 arrayNode.add(connectPoint.deviceId() + "/" + connectPoint.port());
267 });
Charles Chanb3007e12016-05-20 10:55:40 -0700268 object.set(SUPPRESS_HOST_BY_PORT, arrayNode);
Charles Chanf2565a92016-02-10 20:46:58 -0800269 }
270 return this;
271 }
272
Charles Chan6ea94fc2016-05-10 17:29:47 -0700273 /**
Charles Chanb3007e12016-05-20 10:55:40 -0700274 * Gets provider names from which SegmentRouting does not learn host info.
Charles Chan6ea94fc2016-05-10 17:29:47 -0700275 *
Charles Chanb3007e12016-05-20 10:55:40 -0700276 * @return array of provider names that need to be ignored
Charles Chan6ea94fc2016-05-10 17:29:47 -0700277 */
Charles Chanb3007e12016-05-20 10:55:40 -0700278 public Set<String> suppressHostByProvider() {
279 if (!object.has(SUPPRESS_HOST_BY_PROVIDER)) {
280 return ImmutableSet.of();
281 }
282
283 ImmutableSet.Builder<String> builder = ImmutableSet.builder();
284 ArrayNode arrayNode = (ArrayNode) object.path(SUPPRESS_HOST_BY_PROVIDER);
285 for (JsonNode jsonNode : arrayNode) {
286 String providerName = jsonNode.asText(null);
287 if (providerName == null) {
288 return null;
289 }
290 builder.add(providerName);
291 }
292 return builder.build();
Charles Chan6ea94fc2016-05-10 17:29:47 -0700293 }
294
295 /**
Charles Chanb3007e12016-05-20 10:55:40 -0700296 * Sets provider names from which SegmentRouting does not learn host info.
Charles Chan6ea94fc2016-05-10 17:29:47 -0700297 *
Charles Chanb3007e12016-05-20 10:55:40 -0700298 * @param providers set of provider names
Charles Chan6ea94fc2016-05-10 17:29:47 -0700299 * @return this {@link SegmentRoutingAppConfig}
300 */
Charles Chanb3007e12016-05-20 10:55:40 -0700301 public SegmentRoutingAppConfig setSuppressHostByProvider(Set<String> providers) {
302 if (providers == null) {
303 object.remove(SUPPRESS_HOST_BY_PROVIDER);
304 } else {
305 ArrayNode arrayNode = mapper.createArrayNode();
306 providers.forEach(arrayNode::add);
307 object.set(SUPPRESS_HOST_BY_PROVIDER, arrayNode);
308 }
Charles Chan6ea94fc2016-05-10 17:29:47 -0700309 return this;
310 }
311
Charles Chan5270ed02016-01-30 23:22:37 -0800312 @Override
313 public String toString() {
314 return toStringHelper(this)
315 .add("vRouterMacs", vRouterMacs())
Charles Chand9681e72016-02-22 19:27:29 -0800316 .add("suppressSubnet", suppressSubnet())
Charles Chanb3007e12016-05-20 10:55:40 -0700317 .add("suppressHostByPort", suppressHostByPort())
318 .add("suppressHostByProvider", suppressHostByProvider())
Pier Ventre98161782016-10-31 15:00:01 -0700319 .add("mplsEcmp", mplsEcmp())
Andrea Campanellad980c6d2018-04-30 11:48:55 +0200320 .add("blackholeIps", blackholeIPs())
Charles Chan5270ed02016-01-30 23:22:37 -0800321 .toString();
322 }
323}