2 * Copyright (c) 2001-2003
3 * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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
27 * Author: Hartmut Brandt <harti@freebsd.org>
29 * $Begemot: libunimsg/netnatm/msg/traffic.c,v 1.4 2004/07/08 08:22:05 brandt Exp $
31 * Traffic classification
34 #include <netnatm/unimsg.h>
35 #include <netnatm/msg/unistruct.h>
36 #include <netnatm/msg/unimsglib.h>
38 #include <sys/systm.h>
44 * Try to set the parameters for the CPCS from the parameters of the
48 T_CBR23 = 100, T_nrtVBR2_6_UBR12, T_rtVBR236, T_rtVBR2_6
51 static 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;
54 static 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;
58 static const u_int fcbr3 = UNI_TRAFFIC_FPCR0_P | UNI_TRAFFIC_FPCR1_P;
59 static const u_int bcbr3 = UNI_TRAFFIC_BPCR0_P | UNI_TRAFFIC_BPCR1_P;
60 static const u_int fvbr16 = UNI_TRAFFIC_FPCR1_P | UNI_TRAFFIC_FSCR1_P |
62 static const u_int bvbr16 = UNI_TRAFFIC_BPCR1_P | UNI_TRAFFIC_BSCR1_P |
64 static const u_int fvbr23 = UNI_TRAFFIC_FPCR1_P | UNI_TRAFFIC_FSCR0_P |
66 static const u_int bvbr23 = UNI_TRAFFIC_BPCR1_P | UNI_TRAFFIC_BSCR0_P |
68 static const u_int fvbr4 = UNI_TRAFFIC_FPCR0_P | UNI_TRAFFIC_FPCR1_P;
69 static const u_int bvbr4 = UNI_TRAFFIC_BPCR0_P | UNI_TRAFFIC_BPCR1_P;
72 uni_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)
78 u_int ft, bt, be, ftag, btag;
81 switch (bearer->bclass) {
84 if (!(bearer->h.present & UNI_BEARER_ATC_P)) {
88 switch (bearer->atc) {
90 case UNI_BEARER_ATC_CBR1:
91 tclass = UNI_TRAFFIC_CBR1;
95 snprintf(ebuf, ebufsiz, "bad ATC=%#02x for BCOB-A",
102 if (!(bearer->h.present & UNI_BEARER_ATC_P)) {
103 tclass = T_nrtVBR2_6_UBR12;
106 switch (bearer->atc) {
108 case UNI_BEARER_ATC_VBR1:
109 tclass = UNI_TRAFFIC_rtVBR1;
112 case UNI_BEARER_ATC_VBR:
116 case UNI_BEARER_ATC_NVBR1:
117 tclass = UNI_TRAFFIC_nrtVBR1;
120 case UNI_BEARER_ATC_ABR:
121 tclass = UNI_TRAFFIC_ABR;
125 snprintf(ebuf, ebufsiz, "bad ATC=%#02x for BCOB-C",
132 if (!(bearer->h.present & UNI_BEARER_ATC_P)) {
133 tclass = T_nrtVBR2_6_UBR12;
136 switch (bearer->atc) {
138 case UNI_BEARER_ATC_CBR1:
139 tclass = UNI_TRAFFIC_CBR1;
142 case UNI_BEARER_ATC_CBR:
143 case UNI_BEARER_ATCX_4:
144 case UNI_BEARER_ATCX_6:
148 case UNI_BEARER_ATC_VBR1:
149 tclass = UNI_TRAFFIC_rtVBR1;
152 case UNI_BEARER_ATCX_1:
153 case UNI_BEARER_ATC_VBR:
157 case UNI_BEARER_ATC_NVBR1:
158 tclass = UNI_TRAFFIC_nrtVBR1;
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;
168 case UNI_BEARER_ATC_ABR:
169 tclass = UNI_TRAFFIC_ABR;
173 snprintf(ebuf, ebufsiz, "bad ATC=%#02x for BCOB-X",
180 snprintf(ebuf, ebufsiz, "unsupported bearer class tVP");
184 snprintf(ebuf, ebufsiz, "bad bearer class %#02x",
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;
200 snprintf(ebuf, ebufsiz, "illegal BE for " C); \
206 snprintf(ebuf, ebufsiz, "illegal forward tag in " C); \
212 snprintf(ebuf, ebufsiz, "illegal backward tag in " C); \
216 #define FBAD(C) do { \
217 snprintf(ebuf, ebufsiz, "bad forward CRs for " C); \
221 #define BBAD(C) do { \
222 snprintf(ebuf, ebufsiz, "bad backward CRs for " C); \
228 case UNI_TRAFFIC_CBR1:
230 if (ft != UNI_TRAFFIC_FPCR1_P)
233 if (bt != UNI_TRAFFIC_BPCR1_P)
236 *fclass = *bclass = UNI_TRAFFIC_CBR1;
241 if (ft == UNI_TRAFFIC_FPCR0_P) {
242 *fclass = UNI_TRAFFIC_CBR2;
244 } else if (ft == fcbr3) {
245 *fclass = UNI_TRAFFIC_CBR3;
247 snprintf(ebuf, ebufsiz, "need forward tagging for CBR.3");
252 if (bt == UNI_TRAFFIC_BPCR0_P) {
253 *bclass = UNI_TRAFFIC_CBR2;
255 } else if (bt == bcbr3) {
256 *bclass = UNI_TRAFFIC_CBR3;
258 snprintf(ebuf, ebufsiz, "need backward tagging for CBR.3");
265 case UNI_TRAFFIC_rtVBR1:
273 *fclass = *bclass = UNI_TRAFFIC_rtVBR1;
280 *fclass = UNI_TRAFFIC_rtVBR3;
282 *fclass = UNI_TRAFFIC_rtVBR2;
283 } else if (ft == fvbr16) {
284 *fclass = UNI_TRAFFIC_rtVBR6;
290 *bclass = UNI_TRAFFIC_rtVBR3;
292 *bclass = UNI_TRAFFIC_rtVBR2;
293 } else if (bt == bvbr16) {
294 *bclass = UNI_TRAFFIC_rtVBR6;
304 *fclass = UNI_TRAFFIC_rtVBR3;
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;
312 } else if (ft == fvbr16) {
313 *fclass = UNI_TRAFFIC_rtVBR6;
319 *bclass = UNI_TRAFFIC_rtVBR3;
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;
327 } else if (bt == bvbr16) {
328 *bclass = UNI_TRAFFIC_rtVBR6;
334 case UNI_TRAFFIC_nrtVBR1:
342 *fclass = *bclass = UNI_TRAFFIC_nrtVBR1;
345 case T_nrtVBR2_6_UBR12:
347 if (ft != UNI_TRAFFIC_FPCR1_P)
349 if (bt != UNI_TRAFFIC_BPCR1_P)
352 *fclass = UNI_TRAFFIC_UBR2;
354 *fclass = UNI_TRAFFIC_UBR1;
356 *bclass = UNI_TRAFFIC_UBR2;
358 *bclass = UNI_TRAFFIC_UBR1;
363 *fclass = UNI_TRAFFIC_nrtVBR3;
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;
371 } else if (ft == fvbr16) {
372 *fclass = UNI_TRAFFIC_nrtVBR6;
378 *bclass = UNI_TRAFFIC_nrtVBR3;
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;
386 } else if (bt == bvbr16) {
387 *bclass = UNI_TRAFFIC_nrtVBR6;
393 case UNI_TRAFFIC_ABR:
395 if (ft != UNI_TRAFFIC_FPCR1_P)
397 if (bt != UNI_TRAFFIC_BPCR1_P)
401 *fclass = *bclass = UNI_TRAFFIC_ABR;