Deleted Added
sdiff udiff text old ( 121934 ) new ( 131826 )
full compact
1/*
2 * Copyright (c) 2001-2003
3 * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * Author: Hartmut Brandt <harti@freebsd.org>
28 *
29 * $Begemot: libunimsg/atm/msg/traffic.c,v 1.3 2003/09/19 11:58:15 hbb Exp $
30 *
31 * Traffic classification
32 */
33
34#include <netnatm/unimsg.h>
35#include <netnatm/msg/unistruct.h>
36#include <netnatm/msg/unimsglib.h>
37#ifdef _KERNEL
38#include <sys/systm.h>
39#else
40#include <stdio.h>
41#endif
42
43/*
44 * Try to set the parameters for the CPCS from the parameters of the
45 * connection.
46 */
47enum {
48 T_CBR23 = 100, T_nrtVBR2_6_UBR12, T_rtVBR236, T_rtVBR2_6
49};
50
51static const u_int fmask = UNI_TRAFFIC_FPCR0_P | UNI_TRAFFIC_FPCR1_P |
52 UNI_TRAFFIC_FSCR0_P | UNI_TRAFFIC_FSCR1_P | UNI_TRAFFIC_FMBS0_P |
53 UNI_TRAFFIC_FMBS1_P | UNI_TRAFFIC_FABR1_P;
54static const u_int bmask = UNI_TRAFFIC_BPCR0_P | UNI_TRAFFIC_BPCR1_P |
55 UNI_TRAFFIC_BSCR0_P | UNI_TRAFFIC_BSCR1_P | UNI_TRAFFIC_BMBS0_P |
56 UNI_TRAFFIC_BMBS1_P | UNI_TRAFFIC_BABR1_P;
57
58static const u_int fcbr3 = UNI_TRAFFIC_FPCR0_P | UNI_TRAFFIC_FPCR1_P;
59static const u_int bcbr3 = UNI_TRAFFIC_BPCR0_P | UNI_TRAFFIC_BPCR1_P;
60static const u_int fvbr16 = UNI_TRAFFIC_FPCR1_P | UNI_TRAFFIC_FSCR1_P |
61 UNI_TRAFFIC_FMBS1_P;
62static const u_int bvbr16 = UNI_TRAFFIC_BPCR1_P | UNI_TRAFFIC_BSCR1_P |
63 UNI_TRAFFIC_BMBS1_P;
64static const u_int fvbr23 = UNI_TRAFFIC_FPCR1_P | UNI_TRAFFIC_FSCR0_P |
65 UNI_TRAFFIC_FMBS0_P;
66static const u_int bvbr23 = UNI_TRAFFIC_BPCR1_P | UNI_TRAFFIC_BSCR0_P |
67 UNI_TRAFFIC_BMBS0_P;
68static const u_int fvbr4 = UNI_TRAFFIC_FPCR0_P | UNI_TRAFFIC_FPCR1_P;
69static const u_int bvbr4 = UNI_TRAFFIC_BPCR0_P | UNI_TRAFFIC_BPCR1_P;
70
71int
72uni_classify_traffic(const struct uni_ie_bearer *bearer,
73 const struct uni_ie_traffic *traffic,
74 enum uni_traffic_class *fclass, enum uni_traffic_class *bclass,
75 char *ebuf, size_t ebufsiz)
76{
77 u_int tclass;
78 u_int ft, bt, be, ftag, btag;
79
80 /* classify */
81 switch (bearer->bclass) {
82
83 case UNI_BEARER_A:
84 if (!(bearer->h.present & UNI_BEARER_ATC_P)) {
85 tclass = T_CBR23;
86 break;
87 }
88 switch (bearer->atc) {
89
90 case UNI_BEARER_ATC_CBR1:
91 tclass = UNI_TRAFFIC_CBR1;
92 break;
93
94 default:
95 snprintf(ebuf, ebufsiz, "bad ATC=%#02x for BCOB-A",
96 bearer->atc);
97 return (-1);
98 }
99 break;
100
101 case UNI_BEARER_C:
102 if (!(bearer->h.present & UNI_BEARER_ATC_P)) {
103 tclass = T_nrtVBR2_6_UBR12;
104 break;
105 }
106 switch (bearer->atc) {
107
108 case UNI_BEARER_ATC_VBR1:
109 tclass = UNI_TRAFFIC_rtVBR1;
110 break;
111
112 case UNI_BEARER_ATC_VBR:
113 tclass = T_rtVBR236;
114 break;
115
116 case UNI_BEARER_ATC_NVBR1:
117 tclass = UNI_TRAFFIC_nrtVBR1;
118 break;
119
120 case UNI_BEARER_ATC_ABR:
121 tclass = UNI_TRAFFIC_ABR;
122 break;
123
124 default:
125 snprintf(ebuf, ebufsiz, "bad ATC=%#02x for BCOB-C",
126 bearer->atc);
127 return (-1);
128 }
129 break;
130
131 case UNI_BEARER_X:
132 if (!(bearer->h.present & UNI_BEARER_ATC_P)) {
133 tclass = T_nrtVBR2_6_UBR12;
134 break;
135 }
136 switch (bearer->atc) {
137
138 case UNI_BEARER_ATC_CBR1:
139 tclass = UNI_TRAFFIC_CBR1;
140 break;
141
142 case UNI_BEARER_ATC_CBR:
143 case UNI_BEARER_ATCX_4:
144 case UNI_BEARER_ATCX_6:
145 tclass = T_CBR23;
146 break;
147
148 case UNI_BEARER_ATC_VBR1:
149 tclass = UNI_TRAFFIC_rtVBR1;
150 break;
151
152 case UNI_BEARER_ATCX_1:
153 case UNI_BEARER_ATC_VBR:
154 tclass = T_rtVBR2_6;
155 break;
156
157 case UNI_BEARER_ATC_NVBR1:
158 tclass = UNI_TRAFFIC_nrtVBR1;
159 break;
160
161 case UNI_BEARER_ATCX_0:
162 case UNI_BEARER_ATCX_2:
163 case UNI_BEARER_ATCX_8:
164 case UNI_BEARER_ATC_NVBR:
165 tclass = T_nrtVBR2_6_UBR12;
166 break;
167
168 case UNI_BEARER_ATC_ABR:
169 tclass = UNI_TRAFFIC_ABR;
170 break;
171
172 default:
173 snprintf(ebuf, ebufsiz, "bad ATC=%#02x for BCOB-X",
174 bearer->atc);
175 return (-1);
176 }
177 break;
178
179 case UNI_BEARER_TVP:
180 snprintf(ebuf, ebufsiz, "unsupported bearer class tVP");
181 return (-1);
182
183 default:
184 snprintf(ebuf, ebufsiz, "bad bearer class %#02x",
185 bearer->bclass);
186 return (-1);
187 }
188
189 /*
190 * Now traffic IE
191 */
192 ft = traffic->h.present & fmask;
193 bt = traffic->h.present & bmask;
194 be = traffic->h.present & UNI_TRAFFIC_BEST_P;
195 ftag = (traffic->h.present & UNI_TRAFFIC_MOPT_P) && traffic->t.ftag;
196 btag = (traffic->h.present & UNI_TRAFFIC_MOPT_P) && traffic->t.btag;
197
198#define NOBE(C) \
199 if (be) { \
200 snprintf(ebuf, ebufsiz, "illegal BE for " C); \
201 return (-1); \
202 }
203
204#define NOFT(C) \
205 if (ftag) { \
206 snprintf(ebuf, ebufsiz, "illegal forward tag in " C); \
207 return (-1); \
208 }
209
210#define NOBT(C) \
211 if (btag) { \
212 snprintf(ebuf, ebufsiz, "illegal backward tag in " C); \
213 return (-1); \
214 }
215
216#define FBAD(C) do { \
217 snprintf(ebuf, ebufsiz, "bad forward CRs for " C); \
218 return (-1); \
219 } while (0)
220
221#define BBAD(C) do { \
222 snprintf(ebuf, ebufsiz, "bad backward CRs for " C); \
223 return (-1); \
224 } while (0)
225
226 switch (tclass) {
227
228 case UNI_TRAFFIC_CBR1:
229 NOBE("CBR.1");
230 if (ft != UNI_TRAFFIC_FPCR1_P)
231 FBAD("CBR.1");
232 NOFT("CBR.1");
233 if (bt != UNI_TRAFFIC_BPCR1_P)
234 BBAD("CBR.1");
235 NOBT("CBR.1");
236 *fclass = *bclass = UNI_TRAFFIC_CBR1;
237 break;
238
239 case T_CBR23:
240 NOBE("CBR.2/3");
241 if (ft == UNI_TRAFFIC_FPCR0_P) {
242 *fclass = UNI_TRAFFIC_CBR2;
243 NOFT("CBR.2");
244 } else if (ft == fcbr3) {
245 *fclass = UNI_TRAFFIC_CBR3;
246 if (!ftag) {
247 snprintf(ebuf, ebufsiz, "need forward tagging for CBR.3");
248 return (-1);
249 }
250 } else
251 FBAD("CBR.2/3");
252 if (bt == UNI_TRAFFIC_BPCR0_P) {
253 *bclass = UNI_TRAFFIC_CBR2;
254 NOBT("CBR.2");
255 } else if (bt == bcbr3) {
256 *bclass = UNI_TRAFFIC_CBR3;
257 if (!btag) {
258 snprintf(ebuf, ebufsiz, "need backward tagging for CBR.3");
259 return (-1);
260 }
261 } else
262 BBAD("CBR.2/3");
263 break;
264
265 case UNI_TRAFFIC_rtVBR1:
266 NOBE("rtVBR.1");
267 if (ft != fvbr16)
268 FBAD("rtVBR.1");
269 NOFT("rtVBR.1");
270 if (bt != bvbr16)
271 BBAD("rtVBR.1");
272 NOBT("rtVBR.1");
273 *fclass = *bclass = UNI_TRAFFIC_rtVBR1;
274 break;
275
276 case T_rtVBR236:
277 NOBE("rtVBR.2/3/6");
278 if (ft == fvbr23) {
279 if (ftag)
280 *fclass = UNI_TRAFFIC_rtVBR3;
281 else
282 *fclass = UNI_TRAFFIC_rtVBR2;
283 } else if (ft == fvbr16) {
284 *fclass = UNI_TRAFFIC_rtVBR6;
285 NOFT("rtVBR.6");
286 } else
287 FBAD("rtVBR.2/3/6");
288 if (bt == bvbr23) {
289 if (btag)
290 *bclass = UNI_TRAFFIC_rtVBR3;
291 else
292 *bclass = UNI_TRAFFIC_rtVBR2;
293 } else if (bt == bvbr16) {
294 *bclass = UNI_TRAFFIC_rtVBR6;
295 NOBT("rtVBR.6");
296 } else
297 BBAD("rtVBR.2/3/6");
298 break;
299
300 case T_rtVBR2_6:
301 NOBE("rtVBR.2-6");
302 if (ft == fvbr23) {
303 if (ftag)
304 *fclass = UNI_TRAFFIC_rtVBR3;
305 else
306 *fclass = UNI_TRAFFIC_rtVBR2;
307 } else if (ft == fvbr4) {
308 *fclass = UNI_TRAFFIC_rtVBR4;
309 } else if (ft == UNI_TRAFFIC_FPCR1_P) {
310 *fclass = UNI_TRAFFIC_rtVBR5;
311 NOFT("rtVBR.5");
312 } else if (ft == fvbr16) {
313 *fclass = UNI_TRAFFIC_rtVBR6;
314 NOFT("rtVBR.6");
315 } else
316 FBAD("rtVBR.2-6");
317 if (bt == bvbr23) {
318 if (btag)
319 *bclass = UNI_TRAFFIC_rtVBR3;
320 else
321 *bclass = UNI_TRAFFIC_rtVBR2;
322 } else if (bt == bvbr4) {
323 *bclass = UNI_TRAFFIC_rtVBR4;
324 } else if (bt == UNI_TRAFFIC_BPCR1_P) {
325 *bclass = UNI_TRAFFIC_rtVBR5;
326 NOBT("rtVBR.5");
327 } else if (bt == bvbr16) {
328 *bclass = UNI_TRAFFIC_rtVBR6;
329 NOBT("rtVBR.6");
330 } else
331 BBAD("rtVBR.2-6");
332 break;
333
334 case UNI_TRAFFIC_nrtVBR1:
335 NOBE("nrtVBR.1");
336 if (ft != fvbr16)
337 FBAD("nrtVBR.1");
338 NOFT("nrtVBR.1");
339 if (bt != bvbr16)
340 BBAD("nrtVBR.1");
341 NOBT("nrtVBR.1");
342 *fclass = *bclass = UNI_TRAFFIC_nrtVBR1;
343 break;
344
345 case T_nrtVBR2_6_UBR12:
346 if (be) {
347 if (ft != UNI_TRAFFIC_FPCR1_P)
348 FBAD("UBR.1/2");
349 if (bt != UNI_TRAFFIC_BPCR1_P)
350 BBAD("UBR.1/2");
351 if (ftag)
352 *fclass = UNI_TRAFFIC_UBR2;
353 else
354 *fclass = UNI_TRAFFIC_UBR1;
355 if (btag)
356 *bclass = UNI_TRAFFIC_UBR2;
357 else
358 *bclass = UNI_TRAFFIC_UBR1;
359 break;
360 }
361 if (ft == fvbr23) {
362 if (ftag)
363 *fclass = UNI_TRAFFIC_nrtVBR3;
364 else
365 *fclass = UNI_TRAFFIC_nrtVBR2;
366 } else if (ft == fvbr4) {
367 *fclass = UNI_TRAFFIC_nrtVBR4;
368 } else if (ft == UNI_TRAFFIC_FPCR1_P) {
369 *fclass = UNI_TRAFFIC_nrtVBR5;
370 NOFT("nrtVBR.5");
371 } else if (ft == fvbr16) {
372 *fclass = UNI_TRAFFIC_nrtVBR6;
373 NOFT("nrtVBR.6");
374 } else
375 FBAD("nrtVBR.2-6");
376 if (bt == bvbr23) {
377 if (btag)
378 *bclass = UNI_TRAFFIC_nrtVBR3;
379 else
380 *bclass = UNI_TRAFFIC_nrtVBR2;
381 } else if (bt == bvbr4) {
382 *bclass = UNI_TRAFFIC_nrtVBR4;
383 } else if (bt == UNI_TRAFFIC_BPCR1_P) {
384 *bclass = UNI_TRAFFIC_nrtVBR5;
385 NOBT("nrtVBR.5");
386 } else if (bt == bvbr16) {
387 *bclass = UNI_TRAFFIC_nrtVBR6;
388 NOBT("nrtVBR.6");
389 } else
390 BBAD("nrtVBR.2-6");
391 break;
392
393 case UNI_TRAFFIC_ABR:
394 NOBE("ABR");
395 if (ft != UNI_TRAFFIC_FPCR1_P)
396 FBAD("ABR");
397 if (bt != UNI_TRAFFIC_BPCR1_P)
398 BBAD("ABR");
399 NOFT("ABR");
400 NOBT("ABR");
401 *fclass = *bclass = UNI_TRAFFIC_ABR;
402 break;
403 }
404
405 return (0);
406}