alshabib
Committed by Gerrit Code Review

Flow Objective implementation

Provides an abstraction which isolates the application from any pipeline
knowledge. By using the provided objectives applications can express
their forwarding desires in a pipeline agnostic way. The objectives
are then consumed by a driver for the specific device who converts them
into the appropriate pipeline coherent flows.

Change-Id: I74a68b4971c367c0cd5b7de9d877abdd117afa98
Showing 26 changed files with 665 additions and 69 deletions
1 +/*
2 + * Copyright 2015 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 + */
16 +package org.onosproject.net.behaviour;
17 +
18 +/**
19 + * Default implementation of a next group.
20 + */
21 +public class DefaultNextGroup implements NextGroup {
22 +
23 + private final byte[] data;
24 +
25 + public DefaultNextGroup(byte[] data) {
26 + this.data = data;
27 + }
28 +
29 + @Override
30 + public byte[] data() {
31 + return data;
32 + }
33 +}
1 +/*
2 + * Copyright 2015 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 + */
16 +package org.onosproject.net.behaviour;
17 +
18 +/**
19 + * Opaque data type for carrying group-like information.
20 + * Only relevant to a pipeliner driver.
21 + */
22 +public interface NextGroup {
23 +
24 + /**
25 + * Serialized form of the next group.
26 + * @return a byte array.
27 + */
28 + byte[] data();
29 +
30 +}
...@@ -21,9 +21,6 @@ import org.onosproject.net.flowobjective.FilteringObjective; ...@@ -21,9 +21,6 @@ import org.onosproject.net.flowobjective.FilteringObjective;
21 import org.onosproject.net.flowobjective.ForwardingObjective; 21 import org.onosproject.net.flowobjective.ForwardingObjective;
22 import org.onosproject.net.flowobjective.NextObjective; 22 import org.onosproject.net.flowobjective.NextObjective;
23 23
24 -import java.util.Collection;
25 -import java.util.concurrent.Future;
26 -
27 /** 24 /**
28 * Behaviour for handling various pipelines. 25 * Behaviour for handling various pipelines.
29 */ 26 */
...@@ -40,24 +37,21 @@ public interface Pipeliner extends HandlerBehaviour { ...@@ -40,24 +37,21 @@ public interface Pipeliner extends HandlerBehaviour {
40 /** 37 /**
41 * Installs the filtering rules onto the device. 38 * Installs the filtering rules onto the device.
42 * 39 *
43 - * @param filterObjectives the collection of filters 40 + * @param filterObjective a filtering objective
44 - * @return a future indicating the success of the operation
45 */ 41 */
46 - Future<Boolean> filter(Collection<FilteringObjective> filterObjectives); 42 + void filter(FilteringObjective filterObjective);
47 43
48 /** 44 /**
49 * Installs the forwarding rules onto the device. 45 * Installs the forwarding rules onto the device.
50 * 46 *
51 - * @param forwardObjectives the collection of forwarding objectives 47 + * @param forwardObjective a forwarding objective
52 - * @return a future indicating the success of the operation
53 */ 48 */
54 - Future<Boolean> forward(Collection<ForwardingObjective> forwardObjectives); 49 + void forward(ForwardingObjective forwardObjective);
55 50
56 /** 51 /**
57 * Installs the next hop elements into the device. 52 * Installs the next hop elements into the device.
58 * 53 *
59 - * @param nextObjectives the collection of next objectives 54 + * @param nextObjective a next objectives
60 - * @return a future indicating the success of the operation
61 */ 55 */
62 - Future<Boolean> next(Collection<NextObjective> nextObjectives); 56 + void next(NextObjective nextObjective);
63 } 57 }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
16 package org.onosproject.net.behaviour; 16 package org.onosproject.net.behaviour;
17 17
18 import org.onlab.osgi.ServiceDirectory; 18 import org.onlab.osgi.ServiceDirectory;
19 +import org.onosproject.net.flowobjective.FlowObjectiveStore;
19 20
20 /** 21 /**
21 * Processing context and supporting services for the pipeline behaviour. 22 * Processing context and supporting services for the pipeline behaviour.
...@@ -30,5 +31,11 @@ public interface PipelinerContext { ...@@ -30,5 +31,11 @@ public interface PipelinerContext {
30 */ 31 */
31 ServiceDirectory directory(); 32 ServiceDirectory directory();
32 33
34 + /**
35 + * Returns the Objective Store where data can be stored and retrieved.
36 + * @return the flow objective store
37 + */
38 + FlowObjectiveStore store();
39 +
33 // TODO: add means to store and access shared state 40 // TODO: add means to store and access shared state
34 } 41 }
......
...@@ -23,6 +23,7 @@ import org.onosproject.net.flow.criteria.Criterion; ...@@ -23,6 +23,7 @@ import org.onosproject.net.flow.criteria.Criterion;
23 import java.util.Collection; 23 import java.util.Collection;
24 import java.util.List; 24 import java.util.List;
25 import java.util.Objects; 25 import java.util.Objects;
26 +import java.util.Optional;
26 27
27 import static com.google.common.base.Preconditions.checkArgument; 28 import static com.google.common.base.Preconditions.checkArgument;
28 import static com.google.common.base.Preconditions.checkNotNull; 29 import static com.google.common.base.Preconditions.checkNotNull;
...@@ -42,6 +43,7 @@ public final class DefaultFilteringObjective implements FilteringObjective { ...@@ -42,6 +43,7 @@ public final class DefaultFilteringObjective implements FilteringObjective {
42 private final List<Criterion> conditions; 43 private final List<Criterion> conditions;
43 private final int id; 44 private final int id;
44 private final Operation op; 45 private final Operation op;
46 + private final Optional<ObjectiveContext> context;
45 47
46 private DefaultFilteringObjective(Type type, boolean permanent, int timeout, 48 private DefaultFilteringObjective(Type type, boolean permanent, int timeout,
47 ApplicationId appId, int priority, Criterion key, 49 ApplicationId appId, int priority, Criterion key,
...@@ -54,6 +56,25 @@ public final class DefaultFilteringObjective implements FilteringObjective { ...@@ -54,6 +56,25 @@ public final class DefaultFilteringObjective implements FilteringObjective {
54 this.priority = priority; 56 this.priority = priority;
55 this.conditions = conditions; 57 this.conditions = conditions;
56 this.op = op; 58 this.op = op;
59 + this.context = Optional.empty();
60 +
61 + this.id = Objects.hash(type, key, conditions, permanent,
62 + timeout, appId, priority);
63 + }
64 +
65 + public DefaultFilteringObjective(Type type, boolean permanent, int timeout,
66 + ApplicationId appId, int priority, Criterion key,
67 + List<Criterion> conditions,
68 + ObjectiveContext context, Operation op) {
69 + this.key = key;
70 + this.type = type;
71 + this.permanent = permanent;
72 + this.timeout = timeout;
73 + this.appId = appId;
74 + this.priority = priority;
75 + this.conditions = conditions;
76 + this.op = op;
77 + this.context = Optional.ofNullable(context);
57 78
58 this.id = Objects.hash(type, key, conditions, permanent, 79 this.id = Objects.hash(type, key, conditions, permanent,
59 timeout, appId, priority); 80 timeout, appId, priority);
...@@ -104,6 +125,11 @@ public final class DefaultFilteringObjective implements FilteringObjective { ...@@ -104,6 +125,11 @@ public final class DefaultFilteringObjective implements FilteringObjective {
104 return op; 125 return op;
105 } 126 }
106 127
128 + @Override
129 + public Optional<ObjectiveContext> context() {
130 + return context;
131 + }
132 +
107 /** 133 /**
108 * Returns a new builder. 134 * Returns a new builder.
109 * 135 *
...@@ -201,6 +227,31 @@ public final class DefaultFilteringObjective implements FilteringObjective { ...@@ -201,6 +227,31 @@ public final class DefaultFilteringObjective implements FilteringObjective {
201 227
202 } 228 }
203 229
230 + @Override
231 + public FilteringObjective add(ObjectiveContext context) {
232 + List<Criterion> conditions = listBuilder.build();
233 + checkNotNull(type, "Must have a type.");
234 + checkArgument(!conditions.isEmpty(), "Must have at least one condition.");
235 + checkNotNull(appId, "Must supply an application id");
236 +
237 + return new DefaultFilteringObjective(type, permanent, timeout,
238 + appId, priority, key, conditions,
239 + context, Operation.ADD);
240 + }
241 +
242 + @Override
243 + public FilteringObjective remove(ObjectiveContext context) {
244 + List<Criterion> conditions = listBuilder.build();
245 + checkNotNull(type, "Must have a type.");
246 + checkArgument(!conditions.isEmpty(), "Must have at least one condition.");
247 + checkNotNull(appId, "Must supply an application id");
248 +
249 +
250 + return new DefaultFilteringObjective(type, permanent, timeout,
251 + appId, priority, key, conditions,
252 + context, Operation.REMOVE);
253 + }
254 +
204 255
205 } 256 }
206 257
......
...@@ -20,6 +20,7 @@ import org.onosproject.net.flow.TrafficSelector; ...@@ -20,6 +20,7 @@ import org.onosproject.net.flow.TrafficSelector;
20 import org.onosproject.net.flow.TrafficTreatment; 20 import org.onosproject.net.flow.TrafficTreatment;
21 21
22 import java.util.Objects; 22 import java.util.Objects;
23 +import java.util.Optional;
23 24
24 import static com.google.common.base.Preconditions.checkArgument; 25 import static com.google.common.base.Preconditions.checkArgument;
25 import static com.google.common.base.Preconditions.checkNotNull; 26 import static com.google.common.base.Preconditions.checkNotNull;
...@@ -38,6 +39,7 @@ public final class DefaultForwardingObjective implements ForwardingObjective { ...@@ -38,6 +39,7 @@ public final class DefaultForwardingObjective implements ForwardingObjective {
38 private final int nextId; 39 private final int nextId;
39 private final TrafficTreatment treatment; 40 private final TrafficTreatment treatment;
40 private final Operation op; 41 private final Operation op;
42 + private final Optional<ObjectiveContext> context;
41 43
42 private final int id; 44 private final int id;
43 45
...@@ -55,6 +57,29 @@ public final class DefaultForwardingObjective implements ForwardingObjective { ...@@ -55,6 +57,29 @@ public final class DefaultForwardingObjective implements ForwardingObjective {
55 this.nextId = nextId; 57 this.nextId = nextId;
56 this.treatment = treatment; 58 this.treatment = treatment;
57 this.op = op; 59 this.op = op;
60 + this.context = Optional.empty();
61 +
62 + this.id = Objects.hash(selector, flag, permanent,
63 + timeout, appId, priority, nextId,
64 + treatment, op);
65 + }
66 +
67 + private DefaultForwardingObjective(TrafficSelector selector,
68 + Flag flag, boolean permanent,
69 + int timeout, ApplicationId appId,
70 + int priority, int nextId,
71 + TrafficTreatment treatment,
72 + ObjectiveContext context, Operation op) {
73 + this.selector = selector;
74 + this.flag = flag;
75 + this.permanent = permanent;
76 + this.timeout = timeout;
77 + this.appId = appId;
78 + this.priority = priority;
79 + this.nextId = nextId;
80 + this.treatment = treatment;
81 + this.op = op;
82 + this.context = Optional.ofNullable(context);
58 83
59 this.id = Objects.hash(selector, flag, permanent, 84 this.id = Objects.hash(selector, flag, permanent,
60 timeout, appId, priority, nextId, 85 timeout, appId, priority, nextId,
...@@ -113,6 +138,11 @@ public final class DefaultForwardingObjective implements ForwardingObjective { ...@@ -113,6 +138,11 @@ public final class DefaultForwardingObjective implements ForwardingObjective {
113 return op; 138 return op;
114 } 139 }
115 140
141 + @Override
142 + public Optional<ObjectiveContext> context() {
143 + return context;
144 + }
145 +
116 /** 146 /**
117 * Returns a new builder. 147 * Returns a new builder.
118 * 148 *
...@@ -186,7 +216,7 @@ public final class DefaultForwardingObjective implements ForwardingObjective { ...@@ -186,7 +216,7 @@ public final class DefaultForwardingObjective implements ForwardingObjective {
186 public ForwardingObjective add() { 216 public ForwardingObjective add() {
187 checkNotNull(selector, "Must have a selector"); 217 checkNotNull(selector, "Must have a selector");
188 checkNotNull(flag, "A flag must be set"); 218 checkNotNull(flag, "A flag must be set");
189 - checkArgument(nextId != null && treatment != null, "Must supply at " + 219 + checkArgument(nextId != null || treatment != null, "Must supply at " +
190 "least a treatment and/or a nextId"); 220 "least a treatment and/or a nextId");
191 checkNotNull(appId, "Must supply an application id"); 221 checkNotNull(appId, "Must supply an application id");
192 return new DefaultForwardingObjective(selector, flag, permanent, 222 return new DefaultForwardingObjective(selector, flag, permanent,
...@@ -198,12 +228,38 @@ public final class DefaultForwardingObjective implements ForwardingObjective { ...@@ -198,12 +228,38 @@ public final class DefaultForwardingObjective implements ForwardingObjective {
198 public ForwardingObjective remove() { 228 public ForwardingObjective remove() {
199 checkNotNull(selector, "Must have a selector"); 229 checkNotNull(selector, "Must have a selector");
200 checkNotNull(flag, "A flag must be set"); 230 checkNotNull(flag, "A flag must be set");
201 - checkArgument(nextId != null && treatment != null, "Must supply at " + 231 + checkArgument(nextId != null || treatment != null, "Must supply at " +
202 "least a treatment and/or a nextId"); 232 "least a treatment and/or a nextId");
203 checkNotNull(appId, "Must supply an application id"); 233 checkNotNull(appId, "Must supply an application id");
204 return new DefaultForwardingObjective(selector, flag, permanent, 234 return new DefaultForwardingObjective(selector, flag, permanent,
205 timeout, appId, priority, 235 timeout, appId, priority,
206 nextId, treatment, Operation.REMOVE); 236 nextId, treatment, Operation.REMOVE);
207 } 237 }
238 +
239 + @Override
240 + public ForwardingObjective add(ObjectiveContext context) {
241 + checkNotNull(selector, "Must have a selector");
242 + checkNotNull(flag, "A flag must be set");
243 + checkArgument(nextId != null || treatment != null, "Must supply at " +
244 + "least a treatment and/or a nextId");
245 + checkNotNull(appId, "Must supply an application id");
246 + return new DefaultForwardingObjective(selector, flag, permanent,
247 + timeout, appId, priority,
248 + nextId, treatment,
249 + context, Operation.ADD);
250 + }
251 +
252 + @Override
253 + public ForwardingObjective remove(ObjectiveContext context) {
254 + checkNotNull(selector, "Must have a selector");
255 + checkNotNull(flag, "A flag must be set");
256 + checkArgument(nextId != null || treatment != null, "Must supply at " +
257 + "least a treatment and/or a nextId");
258 + checkNotNull(appId, "Must supply an application id");
259 + return new DefaultForwardingObjective(selector, flag, permanent,
260 + timeout, appId, priority,
261 + nextId, treatment,
262 + context, Operation.REMOVE);
263 + }
208 } 264 }
209 } 265 }
......
...@@ -21,6 +21,7 @@ import org.onosproject.net.flow.TrafficTreatment; ...@@ -21,6 +21,7 @@ import org.onosproject.net.flow.TrafficTreatment;
21 21
22 import java.util.Collection; 22 import java.util.Collection;
23 import java.util.List; 23 import java.util.List;
24 +import java.util.Optional;
24 25
25 import static com.google.common.base.Preconditions.checkArgument; 26 import static com.google.common.base.Preconditions.checkArgument;
26 import static com.google.common.base.Preconditions.checkNotNull; 27 import static com.google.common.base.Preconditions.checkNotNull;
...@@ -34,13 +35,28 @@ public final class DefaultNextObjective implements NextObjective { ...@@ -34,13 +35,28 @@ public final class DefaultNextObjective implements NextObjective {
34 private final ApplicationId appId; 35 private final ApplicationId appId;
35 private final Type type; 36 private final Type type;
36 private final Integer id; 37 private final Integer id;
38 + private final Operation op;
39 + private final Optional<ObjectiveContext> context;
37 40
38 private DefaultNextObjective(Integer id, List<TrafficTreatment> treatments, 41 private DefaultNextObjective(Integer id, List<TrafficTreatment> treatments,
39 - ApplicationId appId, Type type) { 42 + ApplicationId appId, Type type, Operation op) {
40 this.treatments = treatments; 43 this.treatments = treatments;
41 this.appId = appId; 44 this.appId = appId;
42 this.type = type; 45 this.type = type;
43 this.id = id; 46 this.id = id;
47 + this.op = op;
48 + this.context = Optional.empty();
49 + }
50 +
51 + private DefaultNextObjective(Integer id, List<TrafficTreatment> treatments,
52 + ApplicationId appId, ObjectiveContext context,
53 + Type type, Operation op) {
54 + this.treatments = treatments;
55 + this.appId = appId;
56 + this.type = type;
57 + this.id = id;
58 + this.op = op;
59 + this.context = Optional.ofNullable(context);
44 } 60 }
45 61
46 @Override 62 @Override
...@@ -80,7 +96,12 @@ public final class DefaultNextObjective implements NextObjective { ...@@ -80,7 +96,12 @@ public final class DefaultNextObjective implements NextObjective {
80 96
81 @Override 97 @Override
82 public Operation op() { 98 public Operation op() {
83 - throw new UnsupportedOperationException("Next Objective has no operation"); 99 + return op;
100 + }
101 +
102 + @Override
103 + public Optional<ObjectiveContext> context() {
104 + return context;
84 } 105 }
85 106
86 /** 107 /**
...@@ -101,8 +122,6 @@ public final class DefaultNextObjective implements NextObjective { ...@@ -101,8 +122,6 @@ public final class DefaultNextObjective implements NextObjective {
101 private final ImmutableList.Builder<TrafficTreatment> listBuilder 122 private final ImmutableList.Builder<TrafficTreatment> listBuilder
102 = ImmutableList.builder(); 123 = ImmutableList.builder();
103 124
104 -
105 -
106 @Override 125 @Override
107 public NextObjective.Builder withId(int nextId) { 126 public NextObjective.Builder withId(int nextId) {
108 this.id = nextId; 127 this.id = nextId;
...@@ -143,7 +162,7 @@ public final class DefaultNextObjective implements NextObjective { ...@@ -143,7 +162,7 @@ public final class DefaultNextObjective implements NextObjective {
143 } 162 }
144 163
145 @Override 164 @Override
146 - public Builder fromApp(ApplicationId appId) { 165 + public NextObjective.Builder fromApp(ApplicationId appId) {
147 this.appId = appId; 166 this.appId = appId;
148 return this; 167 return this;
149 } 168 }
...@@ -160,14 +179,49 @@ public final class DefaultNextObjective implements NextObjective { ...@@ -160,14 +179,49 @@ public final class DefaultNextObjective implements NextObjective {
160 } 179 }
161 180
162 @Override 181 @Override
163 - public NextObjective build() { 182 + public NextObjective add() {
183 + List<TrafficTreatment> treatments = listBuilder.build();
184 + checkNotNull(appId, "Must supply an application id");
185 + checkNotNull(id, "id cannot be null");
186 + checkNotNull(type, "The type cannot be null");
187 + checkArgument(!treatments.isEmpty(), "Must have at least one treatment");
188 +
189 + return new DefaultNextObjective(id, treatments, appId, type, Operation.ADD);
190 + }
191 +
192 + @Override
193 + public NextObjective remove() {
194 + List<TrafficTreatment> treatments = listBuilder.build();
195 + checkNotNull(appId, "Must supply an application id");
196 + checkNotNull(id, "id cannot be null");
197 + checkNotNull(type, "The type cannot be null");
198 + checkArgument(!treatments.isEmpty(), "Must have at least one treatment");
199 +
200 + return new DefaultNextObjective(id, treatments, appId, type, Operation.REMOVE);
201 + }
202 +
203 + @Override
204 + public NextObjective add(ObjectiveContext context) {
205 + List<TrafficTreatment> treatments = listBuilder.build();
206 + checkNotNull(appId, "Must supply an application id");
207 + checkNotNull(id, "id cannot be null");
208 + checkNotNull(type, "The type cannot be null");
209 + checkArgument(!treatments.isEmpty(), "Must have at least one treatment");
210 +
211 + return new DefaultNextObjective(id, treatments, appId,
212 + context, type, Operation.ADD);
213 + }
214 +
215 + @Override
216 + public NextObjective remove(ObjectiveContext context) {
164 List<TrafficTreatment> treatments = listBuilder.build(); 217 List<TrafficTreatment> treatments = listBuilder.build();
165 checkNotNull(appId, "Must supply an application id"); 218 checkNotNull(appId, "Must supply an application id");
166 checkNotNull(id, "id cannot be null"); 219 checkNotNull(id, "id cannot be null");
167 checkNotNull(type, "The type cannot be null"); 220 checkNotNull(type, "The type cannot be null");
168 checkArgument(!treatments.isEmpty(), "Must have at least one treatment"); 221 checkArgument(!treatments.isEmpty(), "Must have at least one treatment");
169 222
170 - return new DefaultNextObjective(id, treatments, appId, type); 223 + return new DefaultNextObjective(id, treatments, appId,
224 + context, type, Operation.REMOVE);
171 } 225 }
172 } 226 }
173 } 227 }
......
...@@ -114,6 +114,24 @@ public interface FilteringObjective extends Objective { ...@@ -114,6 +114,24 @@ public interface FilteringObjective extends Objective {
114 */ 114 */
115 public FilteringObjective remove(); 115 public FilteringObjective remove();
116 116
117 + /**
118 + * Builds the filtering objective that will be added.
119 + * The context will be used to notify the calling application.
120 + *
121 + * @param context an objective context
122 + * @return a filtering objective
123 + */
124 + public FilteringObjective add(ObjectiveContext context);
125 +
126 + /**
127 + * Builds the filtering objective that will be removed.
128 + * The context will be used to notify the calling application.
129 + *
130 + * @param context an objective context
131 + * @return a filtering objective
132 + */
133 + public FilteringObjective remove(ObjectiveContext context);
134 +
117 135
118 } 136 }
119 137
......
...@@ -17,9 +17,6 @@ package org.onosproject.net.flowobjective; ...@@ -17,9 +17,6 @@ package org.onosproject.net.flowobjective;
17 17
18 import org.onosproject.net.DeviceId; 18 import org.onosproject.net.DeviceId;
19 19
20 -import java.util.Collection;
21 -import java.util.concurrent.Future;
22 -
23 /** 20 /**
24 * Service for programming data plane flow rules in manner independent of 21 * Service for programming data plane flow rules in manner independent of
25 * specific device table pipeline configuration. 22 * specific device table pipeline configuration.
...@@ -30,27 +27,24 @@ public interface FlowObjectiveService { ...@@ -30,27 +27,24 @@ public interface FlowObjectiveService {
30 * Installs the filtering rules onto the specified device. 27 * Installs the filtering rules onto the specified device.
31 * 28 *
32 * @param deviceId device identifier 29 * @param deviceId device identifier
33 - * @param filteringObjectives the collection of filters 30 + * @param filteringObjective the filtering objective
34 - * @return a future indicating the success of the operation
35 */ 31 */
36 - Future<Boolean> filter(DeviceId deviceId, Collection<FilteringObjective> filteringObjectives); 32 + void filter(DeviceId deviceId, FilteringObjective filteringObjective);
37 33
38 /** 34 /**
39 * Installs the forwarding rules onto the specified device. 35 * Installs the forwarding rules onto the specified device.
40 * 36 *
41 * @param deviceId device identifier 37 * @param deviceId device identifier
42 - * @param forwardingObjectives the collection of forwarding objectives 38 + * @param forwardingObjective the forwarding objective
43 - * @return a future indicating the success of the operation
44 */ 39 */
45 - Future<Boolean> forward(DeviceId deviceId, Collection<ForwardingObjective> forwardingObjectives); 40 + void forward(DeviceId deviceId, ForwardingObjective forwardingObjective);
46 41
47 /** 42 /**
48 * Installs the next hop elements into the specified device. 43 * Installs the next hop elements into the specified device.
49 * 44 *
50 * @param deviceId device identifier 45 * @param deviceId device identifier
51 - * @param nextObjectives the collection of next objectives 46 + * @param nextObjective a next objective
52 - * @return a future indicating the success of the operation
53 */ 47 */
54 - Future<Boolean> next(DeviceId deviceId, Collection<NextObjective> nextObjectives); 48 + void next(DeviceId deviceId, NextObjective nextObjective);
55 49
56 } 50 }
......
1 +/*
2 + * Copyright 2015 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 + */
16 +package org.onosproject.net.flowobjective;
17 +
18 +import org.onosproject.net.behaviour.NextGroup;
19 +import org.onosproject.store.Store;
20 +
21 +/**
22 + * The flow objective store.
23 + */
24 +public interface FlowObjectiveStore
25 + extends Store<ObjectiveEvent, FlowObjectiveStoreDelegate> {
26 +
27 + /**
28 + * Adds a NextGroup to the store.
29 + *
30 + * @param nextId an integer
31 + * @param group a next group opaque object
32 + */
33 + void putNextGroup(Integer nextId, NextGroup group);
34 +
35 + /**
36 + * Fetch a next group from the store.
37 + * @param nextId an integer
38 + * @return a next group
39 + */
40 + NextGroup getNextGroup(Integer nextId);
41 +}
1 +/*
2 + * Copyright 2015 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 + */
16 +package org.onosproject.net.flowobjective;
17 +
18 +import org.onosproject.store.StoreDelegate;
19 +
20 +/**
21 + * Flow Objective store delegate abstraction.
22 + */
23 +public interface FlowObjectiveStoreDelegate extends StoreDelegate<ObjectiveEvent> {
24 +}
...@@ -121,5 +121,23 @@ public interface ForwardingObjective extends Objective { ...@@ -121,5 +121,23 @@ public interface ForwardingObjective extends Objective {
121 * @return a forwarding objective. 121 * @return a forwarding objective.
122 */ 122 */
123 public ForwardingObjective remove(); 123 public ForwardingObjective remove();
124 +
125 + /**
126 + * Builds the forwarding objective that will be added.
127 + * The context will be used to notify the calling application.
128 + *
129 + * @param context an objective context
130 + * @return a forwarding objective
131 + */
132 + public ForwardingObjective add(ObjectiveContext context);
133 +
134 + /**
135 + * Builds the forwarding objective that will be removed.
136 + * The context will be used to notify the calling application.
137 + *
138 + * @param context an objective context
139 + * @return a forwarding objective
140 + */
141 + public ForwardingObjective remove(ObjectiveContext context);
124 } 142 }
125 } 143 }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
15 */ 15 */
16 package org.onosproject.net.flowobjective; 16 package org.onosproject.net.flowobjective;
17 17
18 +import org.onosproject.core.ApplicationId;
18 import org.onosproject.net.flow.TrafficTreatment; 19 import org.onosproject.net.flow.TrafficTreatment;
19 20
20 import java.util.Collection; 21 import java.util.Collection;
...@@ -95,12 +96,40 @@ public interface NextObjective extends Objective { ...@@ -95,12 +96,40 @@ public interface NextObjective extends Objective {
95 */ 96 */
96 public Builder addTreatment(TrafficTreatment treatment); 97 public Builder addTreatment(TrafficTreatment treatment);
97 98
99 + @Override
100 + public Builder fromApp(ApplicationId appId);
101 +
102 + /**
103 + * Builds the next objective that will be added.
104 + *
105 + * @return a next objective
106 + */
107 + public NextObjective add();
108 +
109 + /**
110 + * Builds the next objective that will be removed.
111 + *
112 + * @return a next objective.
113 + */
114 + public NextObjective remove();
115 +
116 + /**
117 + * Builds the next objective that will be added.
118 + * The context will be used to notify the calling application.
119 + *
120 + * @param context an objective context
121 + * @return a next objective
122 + */
123 + public NextObjective add(ObjectiveContext context);
124 +
98 /** 125 /**
99 - * Builds a next step. 126 + * Builds the next objective that will be removed.
127 + * The context will be used to notify the calling application.
100 * 128 *
101 - * @return a next step 129 + * @param context an objective context
130 + * @return a next objective
102 */ 131 */
103 - public NextObjective build(); 132 + public NextObjective remove(ObjectiveContext context);
104 133
105 } 134 }
106 135
......
...@@ -17,6 +17,8 @@ package org.onosproject.net.flowobjective; ...@@ -17,6 +17,8 @@ package org.onosproject.net.flowobjective;
17 17
18 import org.onosproject.core.ApplicationId; 18 import org.onosproject.core.ApplicationId;
19 19
20 +import java.util.Optional;
21 +
20 /** 22 /**
21 * Base representation of an flow description. 23 * Base representation of an flow description.
22 */ 24 */
...@@ -84,6 +86,14 @@ public interface Objective { ...@@ -84,6 +86,14 @@ public interface Objective {
84 Operation op(); 86 Operation op();
85 87
86 /** 88 /**
89 + * Obtains an optional context.
90 + *
91 + * @return optional; which will be empty if there is no context.
92 + * Otherwise it will return the context.
93 + */
94 + Optional<ObjectiveContext> context();
95 +
96 + /**
87 * An objective builder. 97 * An objective builder.
88 */ 98 */
89 public interface Builder { 99 public interface Builder {
......
1 +/*
2 + * Copyright 2015 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 + */
16 +package org.onosproject.net.flowobjective;
17 +
18 +/**
19 + * The context of a objective that will become the subject of
20 + * the notification.
21 + *
22 + * Implementations of this class must be serializable.
23 + */
24 +public interface ObjectiveContext {
25 +
26 + default void onSuccess(Objective objective) {}
27 +
28 + default void onError(Objective objective, ObjectiveError error) {}
29 +
30 +}
1 +/*
2 + * Copyright 2015 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 + */
16 +package org.onosproject.net.flowobjective;
17 +
18 +/**
19 + * Represents the set of errors possible when processing an objective.
20 + */
21 +public enum ObjectiveError {
22 +
23 + /**
24 + * The driver processing this objective does not know how to process it.
25 + */
26 + UNSUPPORTED,
27 +
28 + /**
29 + * The flow installation for this objective failed.
30 + */
31 + FLOWINSTALLATIONFAILED,
32 +
33 + /**
34 + * THe group installation for this objective failed.
35 + */
36 + GROUPINSTALLATIONFAILED,
37 +
38 + /**
39 + * The group was reported as installed but is not missing.
40 + */
41 + GROUPMISSING,
42 +
43 + /**
44 + * An unknown error occurred.
45 + */
46 + UNKNOWN
47 +}
1 +/*
2 + * Copyright 2015 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 + */
16 +package org.onosproject.net.flowobjective;
17 +
18 +import org.onosproject.event.AbstractEvent;
19 +
20 +/**
21 + * Describes a objective event.
22 + */
23 +public class ObjectiveEvent extends AbstractEvent<ObjectiveEvent.Type, Integer> {
24 +
25 + /**
26 + * Type of objective events.
27 + */
28 + public enum Type {
29 + /**
30 + * Signifies that the objective has been added to the store.
31 + */
32 + ADD,
33 +
34 + /**
35 + * Signifies that the objective has been removed.
36 + */
37 + REMOVE
38 + }
39 +
40 + /**
41 + * Creates an event of the given type for the specified objective id.
42 + *
43 + * @param type the type of the event
44 + * @param objective the objective id the event is about
45 + */
46 + public ObjectiveEvent(Type type, Integer objective) {
47 + super(type, objective);
48 + }
49 +
50 + /**
51 + * Creates an event of the given type for the specified objective id at the given
52 + * time.
53 + *
54 + * @param type the type of the event
55 + * @param objective the objective id the event is about
56 + * @param time the time of the event
57 + */
58 + public ObjectiveEvent(Type type, Integer objective, long time) {
59 + super(type, objective, time);
60 + }
61 +}
62 +
1 +/*
2 + * Copyright 2015 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 + */
16 +package org.onosproject.store.flowobjective.impl;
17 +
18 +import org.apache.felix.scr.annotations.Activate;
19 +import org.apache.felix.scr.annotations.Component;
20 +import org.apache.felix.scr.annotations.Deactivate;
21 +import org.apache.felix.scr.annotations.Reference;
22 +import org.apache.felix.scr.annotations.ReferenceCardinality;
23 +import org.apache.felix.scr.annotations.Service;
24 +import org.onlab.util.KryoNamespace;
25 +import org.onosproject.net.behaviour.DefaultNextGroup;
26 +import org.onosproject.net.behaviour.NextGroup;
27 +import org.onosproject.net.flowobjective.FlowObjectiveStore;
28 +import org.onosproject.net.flowobjective.FlowObjectiveStoreDelegate;
29 +import org.onosproject.net.flowobjective.ObjectiveEvent;
30 +import org.onosproject.store.AbstractStore;
31 +import org.onosproject.store.service.ConsistentMap;
32 +import org.onosproject.store.service.Serializer;
33 +import org.onosproject.store.service.StorageService;
34 +import org.onosproject.store.service.Versioned;
35 +import org.slf4j.Logger;
36 +
37 +import static org.slf4j.LoggerFactory.getLogger;
38 +
39 +/**
40 + * Manages the inventory of created next groups.
41 + */
42 +@Component(immediate = true, enabled = true)
43 +@Service
44 +public class DistributedFlowObjectiveStore
45 + extends AbstractStore<ObjectiveEvent, FlowObjectiveStoreDelegate>
46 + implements FlowObjectiveStore {
47 +
48 + private final Logger log = getLogger(getClass());
49 +
50 + private ConsistentMap<Integer, byte[]> nextGroups;
51 +
52 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
53 + protected StorageService storageService;
54 +
55 + @Activate
56 + public void activate() {
57 + nextGroups = storageService.<Integer, byte[]>consistentMapBuilder()
58 + .withName("flowobjective-groups")
59 + .withSerializer(Serializer.using(
60 + new KryoNamespace.Builder()
61 + .register(byte[].class)
62 + .build()))
63 + .build();
64 +
65 + log.info("Started");
66 + }
67 +
68 +
69 + @Deactivate
70 + public void deactivate() {
71 + log.info("Stopped");
72 + }
73 +
74 +
75 + @Override
76 + public void putNextGroup(Integer nextId, NextGroup group) {
77 + nextGroups.putIfAbsent(nextId, group.data());
78 + notifyDelegate(new ObjectiveEvent(ObjectiveEvent.Type.ADD, nextId));
79 + }
80 +
81 + @Override
82 + public NextGroup getNextGroup(Integer nextId) {
83 + Versioned<byte[]> versionGroup = nextGroups.get(nextId);
84 + if (versionGroup != null) {
85 + return new DefaultNextGroup(versionGroup.value());
86 + }
87 + return null;
88 + }
89 +}
...@@ -167,10 +167,13 @@ public class DistributedPacketStore ...@@ -167,10 +167,13 @@ public class DistributedPacketStore
167 public PacketRequestTracker() { 167 public PacketRequestTracker() {
168 requests = storageService.<PacketRequest, Boolean>consistentMapBuilder() 168 requests = storageService.<PacketRequest, Boolean>consistentMapBuilder()
169 .withName("packet-requests") 169 .withName("packet-requests")
170 + .withSerializer(Serializer.using(
171 + new KryoNamespace.Builder().register(KryoNamespaces.API).build()))
170 .withSerializer(new Serializer() { 172 .withSerializer(new Serializer() {
171 KryoNamespace kryo = new KryoNamespace.Builder() 173 KryoNamespace kryo = new KryoNamespace.Builder()
172 .register(KryoNamespaces.API) 174 .register(KryoNamespaces.API)
173 .build(); 175 .build();
176 +
174 @Override 177 @Override
175 public <T> byte[] encode(T object) { 178 public <T> byte[] encode(T object) {
176 return kryo.serialize(object); 179 return kryo.serialize(object);
......
...@@ -44,6 +44,12 @@ ...@@ -44,6 +44,12 @@
44 </dependency> 44 </dependency>
45 45
46 <dependency> 46 <dependency>
47 + <groupId>org.onosproject</groupId>
48 + <artifactId>onos-core-serializers</artifactId>
49 + <version>1.2.0-SNAPSHOT</version>
50 + </dependency>
51 +
52 + <dependency>
47 <groupId>org.easymock</groupId> 53 <groupId>org.easymock</groupId>
48 <artifactId>easymock</artifactId> 54 <artifactId>easymock</artifactId>
49 <scope>test</scope> 55 <scope>test</scope>
......
...@@ -31,11 +31,9 @@ import org.onosproject.net.flow.TrafficSelector; ...@@ -31,11 +31,9 @@ import org.onosproject.net.flow.TrafficSelector;
31 import org.onosproject.net.flowobjective.FilteringObjective; 31 import org.onosproject.net.flowobjective.FilteringObjective;
32 import org.onosproject.net.flowobjective.ForwardingObjective; 32 import org.onosproject.net.flowobjective.ForwardingObjective;
33 import org.onosproject.net.flowobjective.NextObjective; 33 import org.onosproject.net.flowobjective.NextObjective;
34 +import org.onosproject.net.flowobjective.ObjectiveError;
34 import org.slf4j.Logger; 35 import org.slf4j.Logger;
35 36
36 -import java.util.Collection;
37 -import java.util.concurrent.Future;
38 -
39 import static org.slf4j.LoggerFactory.getLogger; 37 import static org.slf4j.LoggerFactory.getLogger;
40 38
41 /** 39 /**
...@@ -58,59 +56,62 @@ public class DefaultSingleTablePipeline extends AbstractHandlerBehaviour impleme ...@@ -58,59 +56,62 @@ public class DefaultSingleTablePipeline extends AbstractHandlerBehaviour impleme
58 } 56 }
59 57
60 @Override 58 @Override
61 - public Future<Boolean> filter(Collection<FilteringObjective> filters) { 59 + public void filter(FilteringObjective filter) {
62 throw new UnsupportedOperationException("Single table does not filter."); 60 throw new UnsupportedOperationException("Single table does not filter.");
63 } 61 }
64 62
65 @Override 63 @Override
66 - public Future<Boolean> forward(Collection<ForwardingObjective> forwardings) { 64 + public void forward(ForwardingObjective fwd) {
67 FlowRuleOperations.Builder flowBuilder = FlowRuleOperations.builder(); 65 FlowRuleOperations.Builder flowBuilder = FlowRuleOperations.builder();
68 - forwardings.forEach(fwd -> {
69 - if (fwd.flag() != ForwardingObjective.Flag.VERSATILE) {
70 - throw new UnsupportedOperationException(
71 - "Only VERSATILE is supported.");
72 - }
73 66
74 - TrafficSelector selector = fwd.selector(); 67 + if (fwd.flag() != ForwardingObjective.Flag.VERSATILE) {
68 + throw new UnsupportedOperationException(
69 + "Only VERSATILE is supported.");
70 + }
75 71
76 - FlowRule rule = new DefaultFlowRule(deviceId, selector, 72 + TrafficSelector selector = fwd.selector();
77 - fwd.treatment(),
78 - fwd.priority(), fwd.appId(),
79 - new DefaultGroupId(fwd.id()),
80 - fwd.timeout(), fwd.permanent());
81 73
82 - switch (fwd.op()) { 74 + FlowRule rule = new DefaultFlowRule(deviceId, selector,
75 + fwd.treatment(),
76 + fwd.priority(), fwd.appId(),
77 + new DefaultGroupId(fwd.id()),
78 + fwd.timeout(), fwd.permanent());
83 79
84 - case ADD: 80 + switch (fwd.op()) {
85 - flowBuilder.add(rule); 81 +
86 - break; 82 + case ADD:
87 - case REMOVE: 83 + flowBuilder.add(rule);
88 - flowBuilder.remove(rule); 84 + break;
89 - break; 85 + case REMOVE:
90 - default: 86 + flowBuilder.remove(rule);
91 - log.warn("Unknown operation {}", fwd.op()); 87 + break;
92 - } 88 + default:
89 + log.warn("Unknown operation {}", fwd.op());
90 + }
93 91
94 - });
95 92
96 SettableFuture<Boolean> future = SettableFuture.create(); 93 SettableFuture<Boolean> future = SettableFuture.create();
97 94
98 flowRuleService.apply(flowBuilder.build(new FlowRuleOperationsContext() { 95 flowRuleService.apply(flowBuilder.build(new FlowRuleOperationsContext() {
99 @Override 96 @Override
100 public void onSuccess(FlowRuleOperations ops) { 97 public void onSuccess(FlowRuleOperations ops) {
101 - future.set(true); 98 + if (fwd.context().isPresent()) {
99 + fwd.context().get().onSuccess(fwd);
100 + }
102 } 101 }
103 102
104 @Override 103 @Override
105 public void onError(FlowRuleOperations ops) { 104 public void onError(FlowRuleOperations ops) {
106 - future.set(false); 105 + if (fwd.context().isPresent()) {
106 + fwd.context().get().onError(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
107 + }
107 } 108 }
108 })); 109 }));
109 - return future; 110 +
110 } 111 }
111 112
112 @Override 113 @Override
113 - public Future<Boolean> next(Collection<NextObjective> nextObjectives) { 114 + public void next(NextObjective nextObjective) {
114 throw new UnsupportedOperationException("Single table does not next hop."); 115 throw new UnsupportedOperationException("Single table does not next hop.");
115 } 116 }
116 117
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
19 <behaviour api="org.onosproject.net.behaviour.Pipeliner" 19 <behaviour api="org.onosproject.net.behaviour.Pipeliner"
20 impl="org.onosproject.driver.pipeline.DefaultSingleTablePipeline"/> 20 impl="org.onosproject.driver.pipeline.DefaultSingleTablePipeline"/>
21 </driver> 21 </driver>
22 - <driver name="ovs-corsa" manufacturer="Nicira, Inc." hwVersion="Open vSwitch" swVersion="2.3.0"> 22 + <driver name="ovs-corsa" manufacturer="Corsa" hwVersion="emulation" swVersion="0.0.0">
23 <behaviour api="org.onosproject.net.behaviour.Pipeliner" 23 <behaviour api="org.onosproject.net.behaviour.Pipeliner"
24 impl="org.onosproject.driver.pipeline.OVSCorsaPipeline"/> 24 impl="org.onosproject.driver.pipeline.OVSCorsaPipeline"/>
25 </driver> 25 </driver>
......
...@@ -195,7 +195,6 @@ public class FlowModBuilderVer13 extends FlowModBuilder { ...@@ -195,7 +195,6 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
195 for (Instruction i : treatments) { 195 for (Instruction i : treatments) {
196 switch (i.type()) { 196 switch (i.type()) {
197 case DROP: 197 case DROP:
198 - log.warn("Saw drop action; assigning drop action");
199 return new LinkedList<>(); 198 return new LinkedList<>();
200 case L0MODIFICATION: 199 case L0MODIFICATION:
201 actions.add(buildL0Modification(i)); 200 actions.add(buildL0Modification(i));
......