alshabib
Committed by Gerrit Code Review

OpenFlow Meter Provider - still need to parse meter stats

Change-Id: I4b313ea003b3801f81ec7d4823bf69de37fd8643
...@@ -32,7 +32,7 @@ public interface Band { ...@@ -32,7 +32,7 @@ public interface Band {
32 32
33 /** 33 /**
34 * defines a simple DiffServ policer that remark 34 * defines a simple DiffServ policer that remark
35 - * the drop precedence of the DSCP eld in the 35 + * the drop precedence of the DSCP field in the
36 * IP header of the packets that exceed the band 36 * IP header of the packets that exceed the band
37 * rate value. 37 * rate value.
38 */ 38 */
...@@ -42,16 +42,32 @@ public interface Band { ...@@ -42,16 +42,32 @@ public interface Band {
42 /** 42 /**
43 * The rate at which this meter applies. 43 * The rate at which this meter applies.
44 * 44 *
45 - * @return the integer value of the rate 45 + * @return the long value of the rate
46 */ 46 */
47 - int rate(); 47 + long rate();
48 48
49 /** 49 /**
50 * The burst size at which the meter applies. 50 * The burst size at which the meter applies.
51 * 51 *
52 - * @return the integer value of the size 52 + * @return the long value of the size
53 */ 53 */
54 - int burst(); 54 + long burst();
55 +
56 + /**
57 + * Only meaningful in the case of a REMARK band type.
58 + * indicates by which amount the drop precedence of
59 + * the packet should be increase if the band is exceeded.
60 + *
61 + * @return a short value
62 + */
63 + short dropPrecedence();
64 +
65 + /**
66 + * Signals the type of band to create.
67 + *
68 + * @return a band type
69 + */
70 + Type type();
55 71
56 72
57 } 73 }
......
...@@ -38,5 +38,52 @@ public enum MeterFailReason { ...@@ -38,5 +38,52 @@ public enum MeterFailReason {
38 /** 38 /**
39 * The meter that was attempted to be modified is unknown. 39 * The meter that was attempted to be modified is unknown.
40 */ 40 */
41 - UNKNOWN 41 + UNKNOWN,
42 +
43 + /**
44 + * The operation for this meter installation timed out.
45 + */
46 + TIMEOUT,
47 +
48 + /**
49 + * Invalid meter definition.
50 + */
51 + INVALID_METER,
52 +
53 + /**
54 + * The target device is unknown.
55 + */
56 + UNKNOWN_DEVICE,
57 +
58 + /**
59 + * Unknown command.
60 + */
61 + UNKNOWN_COMMAND,
62 +
63 + /**
64 + * Unknown flags.
65 + */
66 + UNKNOWN_FLAGS,
67 +
68 + /**
69 + * Bad rate value.
70 + */
71 + BAD_RATE,
72 +
73 + /**
74 + * Bad burst size value.
75 + */
76 + BAD_BURST,
77 +
78 + /**
79 + * Bad band.
80 + */
81 + BAD_BAND,
82 +
83 + /**
84 + * Bad value value.
85 + */
86 + BAD_BAND_VALUE
87 +
88 +
42 } 89 }
......
...@@ -41,7 +41,7 @@ public final class MeterId { ...@@ -41,7 +41,7 @@ public final class MeterId {
41 * 41 *
42 * @return an integer 42 * @return an integer
43 */ 43 */
44 - int id() { 44 + public int id() {
45 return id; 45 return id;
46 } 46 }
47 47
......
...@@ -29,10 +29,10 @@ public interface MeterProviderService extends ProviderService<MeterProvider> { ...@@ -29,10 +29,10 @@ public interface MeterProviderService extends ProviderService<MeterProvider> {
29 /** 29 /**
30 * Notifies the core that a meter operaton failed for a 30 * Notifies the core that a meter operaton failed for a
31 * specific reason. 31 * specific reason.
32 - * @param deviceId 32 + * @param operation the failed operation
33 - * @param operation 33 + * @param reason the failure reason
34 */ 34 */
35 - void meterOperationFailed(DeviceId deviceId, MeterOperation operation, 35 + void meterOperationFailed(MeterOperation operation,
36 MeterFailReason reason); 36 MeterFailReason reason);
37 37
38 /** 38 /**
......
...@@ -29,4 +29,5 @@ ...@@ -29,4 +29,5 @@
29 <artifact>mvn:${project.groupId}/onos-of-provider-packet/${project.version}</artifact> 29 <artifact>mvn:${project.groupId}/onos-of-provider-packet/${project.version}</artifact>
30 <artifact>mvn:${project.groupId}/onos-of-provider-flow/${project.version}</artifact> 30 <artifact>mvn:${project.groupId}/onos-of-provider-flow/${project.version}</artifact>
31 <artifact>mvn:${project.groupId}/onos-of-provider-group/${project.version}</artifact> 31 <artifact>mvn:${project.groupId}/onos-of-provider-group/${project.version}</artifact>
32 + <artifact>mvn:${project.groupId}/onos-of-provider-meter/${project.version}</artifact>
32 </app> 33 </app>
......
...@@ -29,5 +29,6 @@ ...@@ -29,5 +29,6 @@
29 <bundle>mvn:${project.groupId}/onos-of-provider-packet/${project.version}</bundle> 29 <bundle>mvn:${project.groupId}/onos-of-provider-packet/${project.version}</bundle>
30 <bundle>mvn:${project.groupId}/onos-of-provider-flow/${project.version}</bundle> 30 <bundle>mvn:${project.groupId}/onos-of-provider-flow/${project.version}</bundle>
31 <bundle>mvn:${project.groupId}/onos-of-provider-group/${project.version}</bundle> 31 <bundle>mvn:${project.groupId}/onos-of-provider-group/${project.version}</bundle>
32 + <bundle>mvn:${project.groupId}/onos-of-provider-meter/${project.version}</bundle>
32 </feature> 33 </feature>
33 </features> 34 </features>
......
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.provider.of.meter.impl;
17 +
18 +import org.onosproject.net.meter.Band;
19 +import org.onosproject.net.meter.Meter;
20 +import org.onosproject.net.meter.MeterId;
21 +import org.projectfloodlight.openflow.protocol.OFFactory;
22 +import org.projectfloodlight.openflow.protocol.OFMeterFlags;
23 +import org.projectfloodlight.openflow.protocol.OFMeterMod;
24 +import org.projectfloodlight.openflow.protocol.OFMeterModCommand;
25 +import org.projectfloodlight.openflow.protocol.meterband.OFMeterBand;
26 +import org.projectfloodlight.openflow.protocol.meterband.OFMeterBandDrop;
27 +import org.projectfloodlight.openflow.protocol.meterband.OFMeterBandDscpRemark;
28 +import org.slf4j.Logger;
29 +
30 +import java.util.Collection;
31 +import java.util.List;
32 +import java.util.stream.Collectors;
33 +
34 +import static com.google.common.base.Preconditions.checkArgument;
35 +import static com.google.common.base.Preconditions.checkNotNull;
36 +import static org.slf4j.LoggerFactory.getLogger;
37 +
38 +/**
39 + * Builder for a meter modification.
40 + */
41 +public final class MeterModBuilder {
42 +
43 + private final Logger log = getLogger(getClass());
44 +
45 + private final long xid;
46 + private final OFFactory factory;
47 + private Meter.Unit unit = Meter.Unit.KB_PER_SEC;
48 + private boolean burst = false;
49 + private Integer id;
50 + private Collection<Band> bands;
51 +
52 + public MeterModBuilder(long xid, OFFactory factory) {
53 + this.xid = xid;
54 + this.factory = factory;
55 + }
56 +
57 + public static MeterModBuilder builder(long xid, OFFactory factory) {
58 + return new MeterModBuilder(xid, factory);
59 + }
60 +
61 + public MeterModBuilder withRateUnit(Meter.Unit unit) {
62 + this.unit = unit;
63 + return this;
64 + }
65 +
66 + public MeterModBuilder burst() {
67 + this.burst = true;
68 + return this;
69 + }
70 +
71 + public MeterModBuilder withId(MeterId meterId) {
72 + this.id = meterId.id();
73 + return this;
74 + }
75 +
76 + public MeterModBuilder withBands(Collection<Band> bands) {
77 + this.bands = bands;
78 + return this;
79 + }
80 +
81 + public OFMeterMod add() {
82 + validate();
83 + OFMeterMod.Builder builder = builderMeterMod();
84 + builder.setCommand(OFMeterModCommand.ADD.ordinal());
85 + return builder.build();
86 + }
87 +
88 + public OFMeterMod remove() {
89 + validate();
90 + OFMeterMod.Builder builder = builderMeterMod();
91 + builder.setCommand(OFMeterModCommand.DELETE.ordinal());
92 + return builder.build();
93 + }
94 +
95 + public OFMeterMod modify() {
96 + validate();
97 + OFMeterMod.Builder builder = builderMeterMod();
98 + builder.setCommand(OFMeterModCommand.MODIFY.ordinal());
99 + return builder.build();
100 + }
101 +
102 + private OFMeterMod.Builder builderMeterMod() {
103 + OFMeterMod.Builder builder = factory.buildMeterMod();
104 + int flags = 0;
105 + if (burst) {
106 + // covering loxi short comings.
107 + flags |= 1 << OFMeterFlags.BURST.ordinal();
108 + }
109 + switch (unit) {
110 + case PKTS_PER_SEC:
111 + flags |= 1 << OFMeterFlags.PKTPS.ordinal();
112 + break;
113 + case KB_PER_SEC:
114 + flags |= 1 << OFMeterFlags.KBPS.ordinal();
115 + break;
116 + default:
117 + log.warn("Unknown unit type {}", unit);
118 + }
119 + builder.setBands(buildBands());
120 + builder.setFlags(flags)
121 + .setMeterId(id)
122 + .setXid(xid);
123 + return builder;
124 + }
125 +
126 + private List<OFMeterBand> buildBands() {
127 + return bands.stream().map(b -> {
128 + switch (b.type()) {
129 + case DROP:
130 + OFMeterBandDrop.Builder dropBuilder =
131 + factory.meterBands().buildDrop();
132 + if (burst) {
133 + dropBuilder.setBurstSize(b.burst());
134 + }
135 + dropBuilder.setRate(b.rate());
136 + return dropBuilder.build();
137 + case REMARK:
138 + OFMeterBandDscpRemark.Builder remarkBand =
139 + factory.meterBands().buildDscpRemark();
140 + if (burst) {
141 + remarkBand.setBurstSize(b.burst());
142 + }
143 + remarkBand.setRate(b.rate());
144 + remarkBand.setPrecLevel(b.dropPrecedence());
145 + return remarkBand.build();
146 + default:
147 + log.warn("Unknown band type {}", b.type());
148 + return null;
149 + }
150 + }).filter(value -> value != null).collect(Collectors.toList());
151 + }
152 +
153 + private void validate() {
154 + checkNotNull(id, "id cannot be null");
155 + checkNotNull(bands, "Must have bands");
156 + checkArgument(bands.size() > 0, "Must have at lease one band");
157 + }
158 +}
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 +
17 +package org.onosproject.provider.of.meter.impl;
18 +
19 +import org.jboss.netty.util.HashedWheelTimer;
20 +import org.jboss.netty.util.Timeout;
21 +import org.jboss.netty.util.TimerTask;
22 +import org.onlab.util.Timer;
23 +import org.onosproject.openflow.controller.OpenFlowSwitch;
24 +import org.onosproject.openflow.controller.RoleState;
25 +import org.projectfloodlight.openflow.protocol.OFMeterStatsRequest;
26 +import org.slf4j.Logger;
27 +
28 +import java.util.concurrent.TimeUnit;
29 +
30 +import static org.slf4j.LoggerFactory.getLogger;
31 +
32 +/*
33 + * Sends Meter Stats Request and collect the Meter statistics with a time interval.
34 + */
35 +public class MeterStatsCollector implements TimerTask {
36 +
37 + private final HashedWheelTimer timer = Timer.getTimer();
38 + private final OpenFlowSwitch sw;
39 + private final Logger log = getLogger(getClass());
40 + private final int refreshInterval;
41 +
42 + private Timeout timeout;
43 +
44 + private boolean stopTimer = false;
45 +
46 + /**
47 + * Creates a GroupStatsCollector object.
48 + *
49 + * @param sw Open Flow switch
50 + * @param interval time interval for collecting group statistic
51 + */
52 + public MeterStatsCollector(OpenFlowSwitch sw, int interval) {
53 + this.sw = sw;
54 + this.refreshInterval = interval;
55 + }
56 +
57 + @Override
58 + public void run(Timeout timeout) throws Exception {
59 + log.trace("Collecting stats for {}", sw.getStringId());
60 +
61 + sendMeterStatistic();
62 +
63 + if (!this.stopTimer) {
64 + log.trace("Scheduling stats collection in {} seconds for {}",
65 + this.refreshInterval, this.sw.getStringId());
66 + timeout.getTimer().newTimeout(this, refreshInterval,
67 + TimeUnit.SECONDS);
68 + }
69 + }
70 +
71 + private void sendMeterStatistic() {
72 + if (log.isTraceEnabled()) {
73 + log.trace("sendMeterStatistics {}:{}", sw.getStringId(), sw.getRole());
74 + }
75 + if (sw.getRole() != RoleState.MASTER) {
76 + return;
77 + }
78 +
79 + OFMeterStatsRequest.Builder builder =
80 + sw.factory().buildMeterStatsRequest();
81 + builder.setXid(0).setMeterId(0xFFFFFFFF);
82 +
83 + sw.sendMsg(builder.build());
84 +
85 + }
86 +
87 + /**
88 + * Starts the collector.
89 + */
90 + public void start() {
91 + log.info("Starting Meter Stats collection thread for {}", sw.getStringId());
92 + timeout = timer.newTimeout(this, 1, TimeUnit.SECONDS);
93 + }
94 +
95 + /**
96 + * Stops the collector.
97 + */
98 + public void stop() {
99 + log.info("Stopping Meter Stats collection thread for {}", sw.getStringId());
100 + this.stopTimer = true;
101 + timeout.cancel();
102 + }
103 +}
...@@ -16,18 +16,45 @@ ...@@ -16,18 +16,45 @@
16 16
17 package org.onosproject.provider.of.meter.impl; 17 package org.onosproject.provider.of.meter.impl;
18 18
19 +import com.google.common.cache.Cache;
20 +import com.google.common.cache.CacheBuilder;
21 +import com.google.common.cache.RemovalCause;
22 +import com.google.common.cache.RemovalNotification;
23 +import com.google.common.collect.Maps;
24 +import org.apache.felix.scr.annotations.Activate;
19 import org.apache.felix.scr.annotations.Component; 25 import org.apache.felix.scr.annotations.Component;
26 +import org.apache.felix.scr.annotations.Deactivate;
20 import org.apache.felix.scr.annotations.Reference; 27 import org.apache.felix.scr.annotations.Reference;
21 import org.apache.felix.scr.annotations.ReferenceCardinality; 28 import org.apache.felix.scr.annotations.ReferenceCardinality;
22 import org.onosproject.net.DeviceId; 29 import org.onosproject.net.DeviceId;
30 +import org.onosproject.net.meter.Meter;
31 +import org.onosproject.net.meter.MeterFailReason;
23 import org.onosproject.net.meter.MeterOperation; 32 import org.onosproject.net.meter.MeterOperation;
24 import org.onosproject.net.meter.MeterOperations; 33 import org.onosproject.net.meter.MeterOperations;
25 import org.onosproject.net.meter.MeterProvider; 34 import org.onosproject.net.meter.MeterProvider;
35 +import org.onosproject.net.meter.MeterProviderRegistry;
36 +import org.onosproject.net.meter.MeterProviderService;
26 import org.onosproject.net.provider.AbstractProvider; 37 import org.onosproject.net.provider.AbstractProvider;
27 import org.onosproject.net.provider.ProviderId; 38 import org.onosproject.net.provider.ProviderId;
39 +import org.onosproject.openflow.controller.Dpid;
28 import org.onosproject.openflow.controller.OpenFlowController; 40 import org.onosproject.openflow.controller.OpenFlowController;
41 +import org.onosproject.openflow.controller.OpenFlowEventListener;
42 +import org.onosproject.openflow.controller.OpenFlowSwitch;
43 +import org.onosproject.openflow.controller.OpenFlowSwitchListener;
44 +import org.onosproject.openflow.controller.RoleState;
45 +import org.projectfloodlight.openflow.protocol.OFErrorMsg;
46 +import org.projectfloodlight.openflow.protocol.OFErrorType;
47 +import org.projectfloodlight.openflow.protocol.OFMessage;
48 +import org.projectfloodlight.openflow.protocol.OFPortStatus;
49 +import org.projectfloodlight.openflow.protocol.OFStatsReply;
50 +import org.projectfloodlight.openflow.protocol.OFVersion;
51 +import org.projectfloodlight.openflow.protocol.errormsg.OFMeterModFailedErrorMsg;
29 import org.slf4j.Logger; 52 import org.slf4j.Logger;
30 53
54 +import java.util.Map;
55 +import java.util.concurrent.TimeUnit;
56 +import java.util.concurrent.atomic.AtomicLong;
57 +
31 import static org.slf4j.LoggerFactory.getLogger; 58 import static org.slf4j.LoggerFactory.getLogger;
32 59
33 /** 60 /**
...@@ -36,11 +63,28 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -36,11 +63,28 @@ import static org.slf4j.LoggerFactory.getLogger;
36 @Component(immediate = true) 63 @Component(immediate = true)
37 public class OpenFlowMeterProvider extends AbstractProvider implements MeterProvider { 64 public class OpenFlowMeterProvider extends AbstractProvider implements MeterProvider {
38 65
66 +
39 private final Logger log = getLogger(getClass()); 67 private final Logger log = getLogger(getClass());
40 68
41 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 69 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
42 protected OpenFlowController controller; 70 protected OpenFlowController controller;
43 71
72 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
73 + protected MeterProviderRegistry providerRegistry;
74 +
75 + private MeterProviderService providerService;
76 +
77 + private static final AtomicLong XID_COUNTER = new AtomicLong(1);
78 +
79 + static final int POLL_INTERVAL = 10;
80 + static final long TIMEOUT = 30;
81 +
82 + private Cache<Integer, MeterOperation> pendingOperations;
83 + private Cache<Long, MeterOperation> pendingXid;
84 +
85 +
86 + private InternalMeterListener listener = new InternalMeterListener();
87 + private Map<Dpid, MeterStatsCollector> collectors = Maps.newHashMap();
44 88
45 /** 89 /**
46 * Creates a OpenFlow meter provider. 90 * Creates a OpenFlow meter provider.
...@@ -49,13 +93,232 @@ public class OpenFlowMeterProvider extends AbstractProvider implements MeterProv ...@@ -49,13 +93,232 @@ public class OpenFlowMeterProvider extends AbstractProvider implements MeterProv
49 super(new ProviderId("of", "org.onosproject.provider.meter")); 93 super(new ProviderId("of", "org.onosproject.provider.meter"));
50 } 94 }
51 95
96 + @Activate
97 + public void activate() {
98 + providerService = providerRegistry.register(this);
99 +
100 + pendingOperations = CacheBuilder.newBuilder()
101 + .expireAfterWrite(TIMEOUT, TimeUnit.SECONDS)
102 + .removalListener((RemovalNotification<Integer, MeterOperation> notification) -> {
103 + if (notification.getCause() == RemovalCause.EXPIRED) {
104 + providerService.meterOperationFailed(notification.getValue(),
105 + MeterFailReason.TIMEOUT);
106 + }
107 + }).build();
108 +
109 + controller.addEventListener(listener);
110 + controller.addListener(listener);
111 +
112 + controller.getSwitches().forEach((sw -> createStatsCollection(sw)));
113 + }
114 +
115 + @Deactivate
116 + public void deactivate() {
117 + providerRegistry.unregister(this);
118 + controller.removeEventListener(listener);
119 + controller.removeListener(listener);
120 + providerService = null;
121 + }
122 +
52 @Override 123 @Override
53 public void performMeterOperation(DeviceId deviceId, MeterOperations meterOps) { 124 public void performMeterOperation(DeviceId deviceId, MeterOperations meterOps) {
125 + Dpid dpid = Dpid.dpid(deviceId.uri());
126 + OpenFlowSwitch sw = controller.getSwitch(dpid);
127 + if (sw == null) {
128 + log.error("Unknown device {}", deviceId);
129 + meterOps.operations().forEach(op ->
130 + providerService.meterOperationFailed(op,
131 + MeterFailReason.UNKNOWN_DEVICE)
132 + );
133 + return;
134 + }
54 135
136 + meterOps.operations().forEach(op -> performOperation(sw, op));
55 } 137 }
56 138
57 @Override 139 @Override
58 public void performMeterOperation(DeviceId deviceId, MeterOperation meterOp) { 140 public void performMeterOperation(DeviceId deviceId, MeterOperation meterOp) {
141 + Dpid dpid = Dpid.dpid(deviceId.uri());
142 + OpenFlowSwitch sw = controller.getSwitch(dpid);
143 + if (sw == null) {
144 + log.error("Unknown device {}", deviceId);
145 + providerService.meterOperationFailed(meterOp,
146 + MeterFailReason.UNKNOWN_DEVICE);
147 + return;
148 + }
149 +
150 + }
151 +
152 + private void performOperation(OpenFlowSwitch sw, MeterOperation op) {
153 +
154 + pendingOperations.put(op.meter().id().id(), op);
155 +
156 +
157 + Meter meter = op.meter();
158 + MeterModBuilder builder = MeterModBuilder.builder(meter.id().id(), sw.factory());
159 + if (meter.isBurst()) {
160 + builder.burst();
161 + }
162 + builder.withBands(meter.bands())
163 + .withId(meter.id())
164 + .withRateUnit(meter.unit());
165 +
166 + switch (op.type()) {
167 + case ADD:
168 + sw.sendMsg(builder.add());
169 + break;
170 + case REMOVE:
171 + sw.sendMsg(builder.remove());
172 + break;
173 + case MODIFY:
174 + sw.sendMsg(builder.modify());
175 + break;
176 + default:
177 + log.warn("Unknown Meter command {}; not sending anything",
178 + op.type());
179 + providerService.meterOperationFailed(op,
180 + MeterFailReason.UNKNOWN_COMMAND);
181 + }
59 182
60 } 183 }
184 +
185 + private void createStatsCollection(OpenFlowSwitch sw) {
186 + if (isMeterSupported(sw)) {
187 + MeterStatsCollector msc = new MeterStatsCollector(sw, POLL_INTERVAL);
188 + msc.start();
189 + collectors.put(new Dpid(sw.getId()), msc);
190 + }
191 + }
192 +
193 + private boolean isMeterSupported(OpenFlowSwitch sw) {
194 + if (sw.factory().getVersion() == OFVersion.OF_10 ||
195 + sw.factory().getVersion() == OFVersion.OF_11 ||
196 + sw.factory().getVersion() == OFVersion.OF_12) {
197 + return false;
198 + }
199 +
200 + return true;
201 + }
202 +
203 + private void pushMeterStats(Dpid dpid, OFStatsReply msg) {
204 +
205 + }
206 +
207 + private void signalMeterError(OFMeterModFailedErrorMsg meterError,
208 + MeterOperation op) {
209 + switch (meterError.getCode()) {
210 + case UNKNOWN:
211 + providerService.meterOperationFailed(op,
212 + MeterFailReason.UNKNOWN_DEVICE);
213 + break;
214 + case METER_EXISTS:
215 + providerService.meterOperationFailed(op,
216 + MeterFailReason.EXISTING_METER);
217 + break;
218 + case INVALID_METER:
219 + providerService.meterOperationFailed(op,
220 + MeterFailReason.INVALID_METER);
221 + break;
222 + case UNKNOWN_METER:
223 + providerService.meterOperationFailed(op,
224 + MeterFailReason.UNKNOWN);
225 + break;
226 + case BAD_COMMAND:
227 + providerService.meterOperationFailed(op,
228 + MeterFailReason.UNKNOWN_COMMAND);
229 + break;
230 + case BAD_FLAGS:
231 + providerService.meterOperationFailed(op,
232 + MeterFailReason.UNKNOWN_FLAGS);
233 + break;
234 + case BAD_RATE:
235 + providerService.meterOperationFailed(op,
236 + MeterFailReason.BAD_RATE);
237 + break;
238 + case BAD_BURST:
239 + providerService.meterOperationFailed(op,
240 + MeterFailReason.BAD_BURST);
241 + break;
242 + case BAD_BAND:
243 + providerService.meterOperationFailed(op,
244 + MeterFailReason.BAD_BAND);
245 + break;
246 + case BAD_BAND_VALUE:
247 + providerService.meterOperationFailed(op,
248 + MeterFailReason.BAD_BAND_VALUE);
249 + break;
250 + case OUT_OF_METERS:
251 + providerService.meterOperationFailed(op,
252 + MeterFailReason.OUT_OF_METERS);
253 + break;
254 + case OUT_OF_BANDS:
255 + providerService.meterOperationFailed(op,
256 + MeterFailReason.OUT_OF_BANDS);
257 + break;
258 + default:
259 + providerService.meterOperationFailed(op,
260 + MeterFailReason.UNKNOWN);
261 + }
262 + }
263 +
264 + private class InternalMeterListener
265 + implements OpenFlowSwitchListener, OpenFlowEventListener {
266 + @Override
267 + public void handleMessage(Dpid dpid, OFMessage msg) {
268 + switch (msg.getType()) {
269 + case STATS_REPLY:
270 + pushMeterStats(dpid, (OFStatsReply) msg);
271 + break;
272 + case ERROR:
273 + OFErrorMsg error = (OFErrorMsg) msg;
274 + if (error.getErrType() == OFErrorType.METER_MOD_FAILED) {
275 + MeterOperation op =
276 + pendingOperations.getIfPresent(error.getXid());
277 + pendingOperations.invalidate(error.getXid());
278 + if (op == null) {
279 + log.warn("Unknown Meter operation failed {}", error);
280 + } else {
281 + OFMeterModFailedErrorMsg meterError =
282 + (OFMeterModFailedErrorMsg) error;
283 + signalMeterError(meterError, op);
284 + }
285 + }
286 + break;
287 + default:
288 + break;
289 + }
290 +
291 + }
292 +
293 + @Override
294 + public void switchAdded(Dpid dpid) {
295 + createStatsCollection(controller.getSwitch(dpid));
296 + }
297 +
298 + @Override
299 + public void switchRemoved(Dpid dpid) {
300 + MeterStatsCollector msc = collectors.remove(dpid);
301 + if (msc != null) {
302 + msc.stop();
303 + }
304 + }
305 +
306 + @Override
307 + public void switchChanged(Dpid dpid) {
308 +
309 + }
310 +
311 + @Override
312 + public void portChanged(Dpid dpid, OFPortStatus status) {
313 +
314 + }
315 +
316 + @Override
317 + public void receivedRoleReply(Dpid dpid, RoleState requested, RoleState response) {
318 +
319 + }
320 + }
321 +
322 +
323 +
61 } 324 }
......