blob: 52a3924cc72c90a0843dc41a4bcc0a69e74d1b48 [file] [log] [blame]
Brian O'Connor7cbbbb72016-04-09 02:13:23 -07001/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
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 */
Luca Prete9c2ee072016-02-16 11:00:44 -080016package org.onosproject.vpls;
17
nosignal5fd282e2016-09-16 16:11:40 -070018import com.google.common.collect.ImmutableSet;
19import com.google.common.collect.Lists;
Luca Prete9c2ee072016-02-16 11:00:44 -080020import org.onlab.packet.MacAddress;
Luca Prete9c2ee072016-02-16 11:00:44 -080021import org.onosproject.core.ApplicationId;
22import org.onosproject.net.ConnectPoint;
nosignal5fd282e2016-09-16 16:11:40 -070023import org.onosproject.net.FilteredConnectPoint;
24import org.onosproject.net.Host;
Luca Prete9c2ee072016-02-16 11:00:44 -080025import org.onosproject.net.flow.DefaultTrafficSelector;
Luca Prete9c2ee072016-02-16 11:00:44 -080026import org.onosproject.net.flow.TrafficSelector;
Luca Prete9c2ee072016-02-16 11:00:44 -080027import org.onosproject.net.intent.Intent;
28import org.onosproject.net.intent.IntentService;
nosignal5fd282e2016-09-16 16:11:40 -070029import org.onosproject.net.intent.IntentState;
Luca Prete9c2ee072016-02-16 11:00:44 -080030import org.onosproject.net.intent.Key;
31import org.onosproject.net.intent.MultiPointToSinglePointIntent;
32import org.onosproject.net.intent.SinglePointToMultiPointIntent;
33import org.onosproject.routing.IntentSynchronizationService;
34import org.slf4j.Logger;
35import org.slf4j.LoggerFactory;
36
Luca Prete9c2ee072016-02-16 11:00:44 -080037import java.util.Collection;
Luca Prete9c2ee072016-02-16 11:00:44 -080038import java.util.List;
39import java.util.Set;
Luca Prete9c2ee072016-02-16 11:00:44 -080040
41/**
42 * Synchronizes intents between the in-memory intent store and the
43 * IntentService.
44 */
45public class IntentInstaller {
nosignal5fd282e2016-09-16 16:11:40 -070046 private static final String SUBMIT =
47 "Submitting intents to the Intent Synchronizer";
48 private static final String WITHDRAW =
49 "Withdrawing intents to the Intent Synchronizer";
50 private static final String SP2MP =
51 "Building sp2mp intent from {}";
52 private static final String MP2SP =
53 "Building mp2sp intent to {}";
54
Luca Prete9c2ee072016-02-16 11:00:44 -080055 private static final Logger log = LoggerFactory.getLogger(
56 IntentInstaller.class);
57
58 private static final int PRIORITY_OFFSET = 1000;
59
nosignal5fd282e2016-09-16 16:11:40 -070060 private static final Set<IntentState> WITHDRAWN_INTENT_STATES =
61 ImmutableSet.of(IntentState.WITHDRAWN,
62 IntentState.WITHDRAW_REQ,
63 IntentState.WITHDRAWING);
64
65 static final String PREFIX_BROADCAST = "brc";
66 static final String PREFIX_UNICAST = "uni";
67 static final String DASH = "-";
Luca Prete9c2ee072016-02-16 11:00:44 -080068
69 private final ApplicationId appId;
70 private final IntentSynchronizationService intentSynchronizer;
71 private final IntentService intentService;
72
73 /**
74 * Class constructor.
75 *
76 * @param appId the Application ID
77 * @param intentService the intent service
78 * @param intentSynchronizer the intent synchronizer service
79 */
80 public IntentInstaller(ApplicationId appId, IntentService intentService,
81 IntentSynchronizationService intentSynchronizer) {
82 this.appId = appId;
83 this.intentService = intentService;
84 this.intentSynchronizer = intentSynchronizer;
85 }
86
87 /**
Luca Prete9c2ee072016-02-16 11:00:44 -080088 * Requests to install the intents passed as argument to the Intent Service.
89 *
90 * @param intents intents to be submitted
91 */
nosignal5fd282e2016-09-16 16:11:40 -070092 protected void submitIntents(Collection<Intent> intents) {
93 log.debug(SUBMIT);
94 intents.forEach(intentSynchronizer::submit);
Luca Prete9c2ee072016-02-16 11:00:44 -080095 }
96
97 /**
nosignal5fd282e2016-09-16 16:11:40 -070098 * Requests to withdraw the intents passed as argument to the Intent Service.
Luca Prete9c2ee072016-02-16 11:00:44 -080099 *
nosignal5fd282e2016-09-16 16:11:40 -0700100 * @param intents intents to be withdraw
Luca Prete9c2ee072016-02-16 11:00:44 -0800101 */
nosignal5fd282e2016-09-16 16:11:40 -0700102 protected void withdrawIntents(Collection<Intent> intents) {
103 log.debug(WITHDRAW);
104 intents.forEach(intentSynchronizer::withdraw);
105 }
106
107 /**
108 * Returns list of intents belongs to a VPLS.
109 *
110 * @param name required VPLS network name
111 * @return list of intents belongs to a VPLS
112 */
113 protected List<Intent> getIntentsFromVpls(String name) {
114 List<Intent> intents = Lists.newArrayList();
115
116 intentService.getIntents().forEach(intent -> {
117 if (intent.key().toString().startsWith(name)) {
118 intents.add(intent);
119 }
120 });
121
122 return intents;
123 }
124
125 /**
126 * Builds a broadcast intent.
127 *
128 * @param key key to identify the intent
129 * @param src the source connect point
130 * @param dsts the destination connect points
131 * @return the generated single-point to multi-point intent
132 */
133 protected SinglePointToMultiPointIntent buildBrcIntent(Key key,
134 FilteredConnectPoint src,
135 Set<FilteredConnectPoint> dsts) {
136 log.debug(SP2MP, src);
Luca Prete9c2ee072016-02-16 11:00:44 -0800137
138 SinglePointToMultiPointIntent intent;
139
nosignal5fd282e2016-09-16 16:11:40 -0700140 TrafficSelector selector = DefaultTrafficSelector.builder()
Luca Prete9c2ee072016-02-16 11:00:44 -0800141 .matchEthDst(MacAddress.BROADCAST)
nosignal5fd282e2016-09-16 16:11:40 -0700142 .build();
Luca Prete9c2ee072016-02-16 11:00:44 -0800143
144 intent = SinglePointToMultiPointIntent.builder()
145 .appId(appId)
146 .key(key)
147 .selector(selector)
nosignal5fd282e2016-09-16 16:11:40 -0700148 .filteredIngressPoint(src)
149 .filteredEgressPoints(dsts)
Luca Prete9c2ee072016-02-16 11:00:44 -0800150 .priority(PRIORITY_OFFSET)
151 .build();
152 return intent;
153 }
154
155 /**
nosignal5fd282e2016-09-16 16:11:40 -0700156 * Builds a unicast intent.
Luca Prete9c2ee072016-02-16 11:00:44 -0800157 *
nosignal5fd282e2016-09-16 16:11:40 -0700158 * @param key key to identify the intent
159 * @param srcs the source Connect Points
160 * @param dst the destination Connect Point
161 * @param host destination Host
162 * @return the generated multi-point to single-point intent
Luca Prete9c2ee072016-02-16 11:00:44 -0800163 */
nosignal5fd282e2016-09-16 16:11:40 -0700164 protected MultiPointToSinglePointIntent buildUniIntent(Key key,
165 Set<FilteredConnectPoint> srcs,
166 FilteredConnectPoint dst,
167 Host host) {
168 log.debug(MP2SP, dst);
Luca Prete9c2ee072016-02-16 11:00:44 -0800169
nosignal5fd282e2016-09-16 16:11:40 -0700170 TrafficSelector selector = DefaultTrafficSelector.builder()
171 .matchEthDst(host.mac())
172 .build();
Luca Prete9c2ee072016-02-16 11:00:44 -0800173
Luca Prete9c2ee072016-02-16 11:00:44 -0800174
nosignal5fd282e2016-09-16 16:11:40 -0700175 return MultiPointToSinglePointIntent.builder()
Luca Prete9c2ee072016-02-16 11:00:44 -0800176 .appId(appId)
177 .key(key)
178 .selector(selector)
nosignal5fd282e2016-09-16 16:11:40 -0700179 .filteredIngressPoints(srcs)
180 .filteredEgressPoint(dst)
Luca Prete9c2ee072016-02-16 11:00:44 -0800181 .priority(PRIORITY_OFFSET)
182 .build();
nosignal5fd282e2016-09-16 16:11:40 -0700183
Luca Prete9c2ee072016-02-16 11:00:44 -0800184 }
185
186 /**
nosignal5fd282e2016-09-16 16:11:40 -0700187 * Builds an intent Key for either for a single-point to multi-point or
188 * multi-point to single-point intent, based on a prefix that defines
Luca Prete9c2ee072016-02-16 11:00:44 -0800189 * the type of intent, the single connection point representing the source
nosignal5fd282e2016-09-16 16:11:40 -0700190 * or the destination and the VLAN identifier representing the network.
Luca Prete9c2ee072016-02-16 11:00:44 -0800191 *
nosignal5fd282e2016-09-16 16:11:40 -0700192 * @param prefix key prefix
193 * @param cPoint connect point for single source/destination
194 * @param networkName VPLS network name
195 * @param hostMac source/destination mac address
196 * @return key to identify the intent
Luca Prete9c2ee072016-02-16 11:00:44 -0800197 */
nosignal5fd282e2016-09-16 16:11:40 -0700198 protected Key buildKey(String prefix,
199 ConnectPoint cPoint,
200 String networkName,
201 MacAddress hostMac) {
202 String keyString = networkName +
203 DASH +
204 prefix +
205 DASH +
206 cPoint.deviceId() +
207 DASH +
208 cPoint.port() +
209 DASH +
210 hostMac;
Luca Prete9c2ee072016-02-16 11:00:44 -0800211
212 return Key.of(keyString, appId);
213 }
214
215 /**
nosignal5fd282e2016-09-16 16:11:40 -0700216 * Returns true if the specified intent exists; false otherwise.
Luca Prete9c2ee072016-02-16 11:00:44 -0800217 *
nosignal5fd282e2016-09-16 16:11:40 -0700218 * @param intentKey intent key
219 * @return true if the intent exists, false otherwise
Luca Prete9c2ee072016-02-16 11:00:44 -0800220 */
nosignal5fd282e2016-09-16 16:11:40 -0700221 protected boolean intentExists(Key intentKey) {
222 if (intentService.getIntent(intentKey) == null) {
223 return false;
224 }
Luca Prete9c2ee072016-02-16 11:00:44 -0800225
nosignal5fd282e2016-09-16 16:11:40 -0700226 // Intent does not exist if intent withdrawn
227 IntentState currentIntentState = intentService.getIntentState(intentKey);
228 if (WITHDRAWN_INTENT_STATES.contains(currentIntentState)) {
229 return false;
230 }
231
232 return true;
233 }
Luca Prete9c2ee072016-02-16 11:00:44 -0800234}