aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroupBucket.java
blob: 9d942ee437aebb08f4ce8af0809037caef3218ea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
/*
 * Copyright 2015 Open Networking Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.onosproject.net.group;

import org.onosproject.core.GroupId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.instructions.Instruction;

import java.util.List;
import java.util.Objects;

import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Group bucket implementation. A group bucket is collection of
 * instructions that can be performed on a traffic flow. A select
 * Group can have one or more Buckets where traffic will be
 * processed by a single bucket in the group, based on device
 * specific selection algorithm (e.g. hash on some fields of the
 * incoming traffic flows or round robin) and hence can contains
 * optional weight field to define the weights among the buckets
 * in the group. A failover group bucket is associated with a
 * specific port or group that controls its liveness.
 */
public final class DefaultGroupBucket implements GroupBucket, StoredGroupBucketEntry {
    private final GroupDescription.Type type;
    private final TrafficTreatment treatment;
    private final short weight;
    private final PortNumber watchPort;
    private final GroupId watchGroup;
    private long packets;
    private long bytes;

    /**
     * Group bucket constructor with the parameters.
     *
     * @param type group bucket type
     * @param treatment traffic treatment associated with group bucket
     * @param weight optional weight associated with group bucket
     * @param watchPort port that determines the liveness of group bucket
     * @param watchGroup group that determines the liveness of group bucket
     */
    private DefaultGroupBucket(GroupDescription.Type type,
                               TrafficTreatment treatment,
                               short weight,
                               PortNumber watchPort,
                               GroupId watchGroup) {
        this.type = type;
        this.treatment = checkNotNull(treatment);
        this.weight = weight;
        this.watchPort = watchPort;
        this.watchGroup = watchGroup;
    }

    /**
     * Creates indirect group bucket.
     *
     * @param treatment traffic treatment associated with group bucket
     * @return indirect group bucket object
     */
    public static GroupBucket createIndirectGroupBucket(
                                TrafficTreatment treatment) {
        return new DefaultGroupBucket(GroupDescription.Type.INDIRECT,
                                      treatment,
                                      (short) -1,
                                      null,
                                      null);
    }

    /**
     * Creates select group bucket with weight as 1.
     *
     * @param treatment traffic treatment associated with group bucket
     * @return select group bucket object
     */
    public static GroupBucket createSelectGroupBucket(
                                 TrafficTreatment treatment) {
        return new DefaultGroupBucket(GroupDescription.Type.SELECT,
                                      treatment,
                                      (short) 1,
                                      null,
                                      null);
    }

    /**
     * Creates select group bucket with specified weight.
     *
     * @param treatment traffic treatment associated with group bucket
     * @param weight weight associated with group bucket
     * @return select group bucket object
     */
    public static GroupBucket createSelectGroupBucket(
                                 TrafficTreatment treatment,
                                 short weight) {
        if (weight == 0) {
            return null;
        }

        return new DefaultGroupBucket(GroupDescription.Type.SELECT,
                                      treatment,
                                      weight,
                                      null,
                                      null);
    }

    /**
     * Creates failover group bucket with watchport or watchgroup.
     *
     * @param treatment traffic treatment associated with group bucket
     * @param watchPort port that determines the liveness of group bucket
     * @param watchGroup group that determines the liveness of group bucket
     * @return failover group bucket object
     */
    public static GroupBucket createFailoverGroupBucket(
                                 TrafficTreatment treatment,
                                 PortNumber watchPort,
                                 GroupId watchGroup) {
        checkArgument(((watchPort != null) || (watchGroup != null)));
        return new DefaultGroupBucket(GroupDescription.Type.FAILOVER,
                                      treatment,
                                      (short) -1,
                                      watchPort,
                                      watchGroup);
    }

    /**
     * Creates all group bucket.
     *
     * @param treatment traffic treatment associated with group bucket
     * @return all group bucket object
     */
    public static GroupBucket createAllGroupBucket(TrafficTreatment treatment) {
        return new DefaultGroupBucket(GroupDescription.Type.ALL,
                                      treatment,
                                      (short) -1,
                                      null,
                                      null);
    }

    @Override
    public GroupDescription.Type type() {
        return this.type;
    }

    /**
     * Returns list of Traffic instructions that are part of the bucket.
     *
     * @return TrafficTreatment Traffic instruction list
     */
    @Override
    public TrafficTreatment treatment() {
        return treatment;
    }

    /**
     * Returns weight of select group bucket.
     *
     * @return short weight associated with a bucket
     */
    @Override
    public short weight() {
        return weight;
    }

    /**
     * Returns port number used for liveness detection for a
     * failover bucket.
     *
     * @return PortNumber port number used for liveness detection
     */
    @Override
    public PortNumber watchPort() {
        return watchPort;
    }

    /**
     * Returns group identifier used for liveness detection for a
     * failover bucket.
     *
     * @return GroupId group identifier to be used for liveness detection
     */
    @Override
    public GroupId watchGroup() {
        return watchGroup;
    }

    /*
     * The type and treatment can change on a given bucket
     *
     * (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public int hashCode() {
        return Objects.hash(type, treatment);
    }

    /*
     * The priority and statistics can change on a given treatment and selector
     *
     * (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof DefaultGroupBucket) {
            DefaultGroupBucket that = (DefaultGroupBucket) obj;
            List<Instruction> myInstructions = this.treatment.allInstructions();
            List<Instruction> theirInstructions = that.treatment.allInstructions();

            return Objects.equals(type, that.type) &&
                   myInstructions.containsAll(theirInstructions) &&
                   theirInstructions.containsAll(myInstructions);
        }
        return false;
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("type", type)
                .add("treatment", treatment)
                .add("packets", packets)
                .add("bytes", bytes)
                .toString();
    }

    @Override
    public long packets() {
        return packets;
    }

    @Override
    public long bytes() {
        return bytes;
    }

    @Override
    public void setPackets(long packets) {
        this.packets = packets;
    }

    @Override
    public void setBytes(long bytes) {
        this.bytes = bytes;
    }
}