1121934Sharti/* 2121934Sharti * Copyright (c) 2001-2003 3121934Sharti * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4121934Sharti * All rights reserved. 5121934Sharti * 6121934Sharti * Redistribution and use in source and binary forms, with or without 7121934Sharti * modification, are permitted provided that the following conditions 8121934Sharti * are met: 9121934Sharti * 1. Redistributions of source code must retain the above copyright 10121934Sharti * notice, this list of conditions and the following disclaimer. 11121934Sharti * 2. Redistributions in binary form must reproduce the above copyright 12121934Sharti * notice, this list of conditions and the following disclaimer in the 13121934Sharti * documentation and/or other materials provided with the distribution. 14121934Sharti * 15121934Sharti * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16121934Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17121934Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18121934Sharti * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19121934Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20121934Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21121934Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22121934Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23121934Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24121934Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25121934Sharti * SUCH DAMAGE. 26121934Sharti * 27121934Sharti * Author: Hartmut Brandt <harti@freebsd.org> 28121934Sharti * 29131826Sharti * $Begemot: libunimsg/netnatm/msg/traffic.c,v 1.4 2004/07/08 08:22:05 brandt Exp $ 30121934Sharti * 31121934Sharti * Traffic classification 32121934Sharti */ 33121934Sharti 34121934Sharti#include <netnatm/unimsg.h> 35121934Sharti#include <netnatm/msg/unistruct.h> 36121934Sharti#include <netnatm/msg/unimsglib.h> 37121934Sharti#ifdef _KERNEL 38121934Sharti#include <sys/systm.h> 39121934Sharti#else 40121934Sharti#include <stdio.h> 41121934Sharti#endif 42121934Sharti 43121934Sharti/* 44121934Sharti * Try to set the parameters for the CPCS from the parameters of the 45121934Sharti * connection. 46121934Sharti */ 47121934Shartienum { 48121934Sharti T_CBR23 = 100, T_nrtVBR2_6_UBR12, T_rtVBR236, T_rtVBR2_6 49121934Sharti}; 50121934Sharti 51121934Shartistatic const u_int fmask = UNI_TRAFFIC_FPCR0_P | UNI_TRAFFIC_FPCR1_P | 52121934Sharti UNI_TRAFFIC_FSCR0_P | UNI_TRAFFIC_FSCR1_P | UNI_TRAFFIC_FMBS0_P | 53121934Sharti UNI_TRAFFIC_FMBS1_P | UNI_TRAFFIC_FABR1_P; 54121934Shartistatic const u_int bmask = UNI_TRAFFIC_BPCR0_P | UNI_TRAFFIC_BPCR1_P | 55121934Sharti UNI_TRAFFIC_BSCR0_P | UNI_TRAFFIC_BSCR1_P | UNI_TRAFFIC_BMBS0_P | 56121934Sharti UNI_TRAFFIC_BMBS1_P | UNI_TRAFFIC_BABR1_P; 57121934Sharti 58121934Shartistatic const u_int fcbr3 = UNI_TRAFFIC_FPCR0_P | UNI_TRAFFIC_FPCR1_P; 59121934Shartistatic const u_int bcbr3 = UNI_TRAFFIC_BPCR0_P | UNI_TRAFFIC_BPCR1_P; 60121934Shartistatic const u_int fvbr16 = UNI_TRAFFIC_FPCR1_P | UNI_TRAFFIC_FSCR1_P | 61121934Sharti UNI_TRAFFIC_FMBS1_P; 62121934Shartistatic const u_int bvbr16 = UNI_TRAFFIC_BPCR1_P | UNI_TRAFFIC_BSCR1_P | 63121934Sharti UNI_TRAFFIC_BMBS1_P; 64121934Shartistatic const u_int fvbr23 = UNI_TRAFFIC_FPCR1_P | UNI_TRAFFIC_FSCR0_P | 65121934Sharti UNI_TRAFFIC_FMBS0_P; 66121934Shartistatic const u_int bvbr23 = UNI_TRAFFIC_BPCR1_P | UNI_TRAFFIC_BSCR0_P | 67121934Sharti UNI_TRAFFIC_BMBS0_P; 68121934Shartistatic const u_int fvbr4 = UNI_TRAFFIC_FPCR0_P | UNI_TRAFFIC_FPCR1_P; 69121934Shartistatic const u_int bvbr4 = UNI_TRAFFIC_BPCR0_P | UNI_TRAFFIC_BPCR1_P; 70121934Sharti 71121934Shartiint 72121934Shartiuni_classify_traffic(const struct uni_ie_bearer *bearer, 73121934Sharti const struct uni_ie_traffic *traffic, 74121934Sharti enum uni_traffic_class *fclass, enum uni_traffic_class *bclass, 75121934Sharti char *ebuf, size_t ebufsiz) 76121934Sharti{ 77121934Sharti u_int tclass; 78121934Sharti u_int ft, bt, be, ftag, btag; 79121934Sharti 80121934Sharti /* classify */ 81121934Sharti switch (bearer->bclass) { 82121934Sharti 83121934Sharti case UNI_BEARER_A: 84121934Sharti if (!(bearer->h.present & UNI_BEARER_ATC_P)) { 85121934Sharti tclass = T_CBR23; 86121934Sharti break; 87121934Sharti } 88121934Sharti switch (bearer->atc) { 89121934Sharti 90121934Sharti case UNI_BEARER_ATC_CBR1: 91121934Sharti tclass = UNI_TRAFFIC_CBR1; 92121934Sharti break; 93121934Sharti 94121934Sharti default: 95121934Sharti snprintf(ebuf, ebufsiz, "bad ATC=%#02x for BCOB-A", 96121934Sharti bearer->atc); 97121934Sharti return (-1); 98121934Sharti } 99121934Sharti break; 100121934Sharti 101121934Sharti case UNI_BEARER_C: 102121934Sharti if (!(bearer->h.present & UNI_BEARER_ATC_P)) { 103121934Sharti tclass = T_nrtVBR2_6_UBR12; 104121934Sharti break; 105121934Sharti } 106121934Sharti switch (bearer->atc) { 107121934Sharti 108121934Sharti case UNI_BEARER_ATC_VBR1: 109121934Sharti tclass = UNI_TRAFFIC_rtVBR1; 110121934Sharti break; 111121934Sharti 112121934Sharti case UNI_BEARER_ATC_VBR: 113121934Sharti tclass = T_rtVBR236; 114121934Sharti break; 115121934Sharti 116121934Sharti case UNI_BEARER_ATC_NVBR1: 117121934Sharti tclass = UNI_TRAFFIC_nrtVBR1; 118121934Sharti break; 119121934Sharti 120121934Sharti case UNI_BEARER_ATC_ABR: 121121934Sharti tclass = UNI_TRAFFIC_ABR; 122121934Sharti break; 123121934Sharti 124121934Sharti default: 125121934Sharti snprintf(ebuf, ebufsiz, "bad ATC=%#02x for BCOB-C", 126121934Sharti bearer->atc); 127121934Sharti return (-1); 128121934Sharti } 129121934Sharti break; 130121934Sharti 131121934Sharti case UNI_BEARER_X: 132121934Sharti if (!(bearer->h.present & UNI_BEARER_ATC_P)) { 133121934Sharti tclass = T_nrtVBR2_6_UBR12; 134121934Sharti break; 135121934Sharti } 136121934Sharti switch (bearer->atc) { 137121934Sharti 138121934Sharti case UNI_BEARER_ATC_CBR1: 139121934Sharti tclass = UNI_TRAFFIC_CBR1; 140121934Sharti break; 141121934Sharti 142121934Sharti case UNI_BEARER_ATC_CBR: 143121934Sharti case UNI_BEARER_ATCX_4: 144121934Sharti case UNI_BEARER_ATCX_6: 145121934Sharti tclass = T_CBR23; 146121934Sharti break; 147121934Sharti 148121934Sharti case UNI_BEARER_ATC_VBR1: 149121934Sharti tclass = UNI_TRAFFIC_rtVBR1; 150121934Sharti break; 151121934Sharti 152121934Sharti case UNI_BEARER_ATCX_1: 153121934Sharti case UNI_BEARER_ATC_VBR: 154121934Sharti tclass = T_rtVBR2_6; 155121934Sharti break; 156121934Sharti 157121934Sharti case UNI_BEARER_ATC_NVBR1: 158121934Sharti tclass = UNI_TRAFFIC_nrtVBR1; 159121934Sharti break; 160121934Sharti 161121934Sharti case UNI_BEARER_ATCX_0: 162121934Sharti case UNI_BEARER_ATCX_2: 163121934Sharti case UNI_BEARER_ATCX_8: 164121934Sharti case UNI_BEARER_ATC_NVBR: 165121934Sharti tclass = T_nrtVBR2_6_UBR12; 166121934Sharti break; 167121934Sharti 168121934Sharti case UNI_BEARER_ATC_ABR: 169121934Sharti tclass = UNI_TRAFFIC_ABR; 170121934Sharti break; 171121934Sharti 172121934Sharti default: 173121934Sharti snprintf(ebuf, ebufsiz, "bad ATC=%#02x for BCOB-X", 174121934Sharti bearer->atc); 175121934Sharti return (-1); 176121934Sharti } 177121934Sharti break; 178121934Sharti 179121934Sharti case UNI_BEARER_TVP: 180121934Sharti snprintf(ebuf, ebufsiz, "unsupported bearer class tVP"); 181121934Sharti return (-1); 182121934Sharti 183121934Sharti default: 184121934Sharti snprintf(ebuf, ebufsiz, "bad bearer class %#02x", 185121934Sharti bearer->bclass); 186121934Sharti return (-1); 187121934Sharti } 188121934Sharti 189121934Sharti /* 190121934Sharti * Now traffic IE 191121934Sharti */ 192121934Sharti ft = traffic->h.present & fmask; 193121934Sharti bt = traffic->h.present & bmask; 194121934Sharti be = traffic->h.present & UNI_TRAFFIC_BEST_P; 195121934Sharti ftag = (traffic->h.present & UNI_TRAFFIC_MOPT_P) && traffic->t.ftag; 196121934Sharti btag = (traffic->h.present & UNI_TRAFFIC_MOPT_P) && traffic->t.btag; 197121934Sharti 198121934Sharti#define NOBE(C) \ 199121934Sharti if (be) { \ 200121934Sharti snprintf(ebuf, ebufsiz, "illegal BE for " C); \ 201121934Sharti return (-1); \ 202121934Sharti } 203121934Sharti 204121934Sharti#define NOFT(C) \ 205121934Sharti if (ftag) { \ 206121934Sharti snprintf(ebuf, ebufsiz, "illegal forward tag in " C); \ 207121934Sharti return (-1); \ 208121934Sharti } 209121934Sharti 210121934Sharti#define NOBT(C) \ 211121934Sharti if (btag) { \ 212121934Sharti snprintf(ebuf, ebufsiz, "illegal backward tag in " C); \ 213121934Sharti return (-1); \ 214121934Sharti } 215121934Sharti 216121934Sharti#define FBAD(C) do { \ 217121934Sharti snprintf(ebuf, ebufsiz, "bad forward CRs for " C); \ 218121934Sharti return (-1); \ 219121934Sharti } while (0) 220121934Sharti 221121934Sharti#define BBAD(C) do { \ 222121934Sharti snprintf(ebuf, ebufsiz, "bad backward CRs for " C); \ 223121934Sharti return (-1); \ 224121934Sharti } while (0) 225121934Sharti 226121934Sharti switch (tclass) { 227121934Sharti 228121934Sharti case UNI_TRAFFIC_CBR1: 229121934Sharti NOBE("CBR.1"); 230121934Sharti if (ft != UNI_TRAFFIC_FPCR1_P) 231121934Sharti FBAD("CBR.1"); 232121934Sharti NOFT("CBR.1"); 233121934Sharti if (bt != UNI_TRAFFIC_BPCR1_P) 234121934Sharti BBAD("CBR.1"); 235121934Sharti NOBT("CBR.1"); 236121934Sharti *fclass = *bclass = UNI_TRAFFIC_CBR1; 237121934Sharti break; 238121934Sharti 239121934Sharti case T_CBR23: 240121934Sharti NOBE("CBR.2/3"); 241121934Sharti if (ft == UNI_TRAFFIC_FPCR0_P) { 242121934Sharti *fclass = UNI_TRAFFIC_CBR2; 243121934Sharti NOFT("CBR.2"); 244121934Sharti } else if (ft == fcbr3) { 245121934Sharti *fclass = UNI_TRAFFIC_CBR3; 246121934Sharti if (!ftag) { 247121934Sharti snprintf(ebuf, ebufsiz, "need forward tagging for CBR.3"); 248121934Sharti return (-1); 249121934Sharti } 250121934Sharti } else 251121934Sharti FBAD("CBR.2/3"); 252121934Sharti if (bt == UNI_TRAFFIC_BPCR0_P) { 253121934Sharti *bclass = UNI_TRAFFIC_CBR2; 254121934Sharti NOBT("CBR.2"); 255121934Sharti } else if (bt == bcbr3) { 256121934Sharti *bclass = UNI_TRAFFIC_CBR3; 257121934Sharti if (!btag) { 258121934Sharti snprintf(ebuf, ebufsiz, "need backward tagging for CBR.3"); 259121934Sharti return (-1); 260121934Sharti } 261121934Sharti } else 262121934Sharti BBAD("CBR.2/3"); 263121934Sharti break; 264121934Sharti 265121934Sharti case UNI_TRAFFIC_rtVBR1: 266121934Sharti NOBE("rtVBR.1"); 267121934Sharti if (ft != fvbr16) 268121934Sharti FBAD("rtVBR.1"); 269121934Sharti NOFT("rtVBR.1"); 270121934Sharti if (bt != bvbr16) 271121934Sharti BBAD("rtVBR.1"); 272121934Sharti NOBT("rtVBR.1"); 273121934Sharti *fclass = *bclass = UNI_TRAFFIC_rtVBR1; 274121934Sharti break; 275121934Sharti 276121934Sharti case T_rtVBR236: 277121934Sharti NOBE("rtVBR.2/3/6"); 278121934Sharti if (ft == fvbr23) { 279121934Sharti if (ftag) 280121934Sharti *fclass = UNI_TRAFFIC_rtVBR3; 281121934Sharti else 282121934Sharti *fclass = UNI_TRAFFIC_rtVBR2; 283121934Sharti } else if (ft == fvbr16) { 284121934Sharti *fclass = UNI_TRAFFIC_rtVBR6; 285121934Sharti NOFT("rtVBR.6"); 286121934Sharti } else 287121934Sharti FBAD("rtVBR.2/3/6"); 288121934Sharti if (bt == bvbr23) { 289121934Sharti if (btag) 290121934Sharti *bclass = UNI_TRAFFIC_rtVBR3; 291121934Sharti else 292121934Sharti *bclass = UNI_TRAFFIC_rtVBR2; 293121934Sharti } else if (bt == bvbr16) { 294121934Sharti *bclass = UNI_TRAFFIC_rtVBR6; 295121934Sharti NOBT("rtVBR.6"); 296121934Sharti } else 297121934Sharti BBAD("rtVBR.2/3/6"); 298121934Sharti break; 299121934Sharti 300121934Sharti case T_rtVBR2_6: 301121934Sharti NOBE("rtVBR.2-6"); 302121934Sharti if (ft == fvbr23) { 303121934Sharti if (ftag) 304121934Sharti *fclass = UNI_TRAFFIC_rtVBR3; 305121934Sharti else 306121934Sharti *fclass = UNI_TRAFFIC_rtVBR2; 307121934Sharti } else if (ft == fvbr4) { 308121934Sharti *fclass = UNI_TRAFFIC_rtVBR4; 309121934Sharti } else if (ft == UNI_TRAFFIC_FPCR1_P) { 310121934Sharti *fclass = UNI_TRAFFIC_rtVBR5; 311121934Sharti NOFT("rtVBR.5"); 312121934Sharti } else if (ft == fvbr16) { 313121934Sharti *fclass = UNI_TRAFFIC_rtVBR6; 314121934Sharti NOFT("rtVBR.6"); 315121934Sharti } else 316121934Sharti FBAD("rtVBR.2-6"); 317121934Sharti if (bt == bvbr23) { 318121934Sharti if (btag) 319121934Sharti *bclass = UNI_TRAFFIC_rtVBR3; 320121934Sharti else 321121934Sharti *bclass = UNI_TRAFFIC_rtVBR2; 322121934Sharti } else if (bt == bvbr4) { 323121934Sharti *bclass = UNI_TRAFFIC_rtVBR4; 324121934Sharti } else if (bt == UNI_TRAFFIC_BPCR1_P) { 325121934Sharti *bclass = UNI_TRAFFIC_rtVBR5; 326121934Sharti NOBT("rtVBR.5"); 327121934Sharti } else if (bt == bvbr16) { 328121934Sharti *bclass = UNI_TRAFFIC_rtVBR6; 329121934Sharti NOBT("rtVBR.6"); 330121934Sharti } else 331121934Sharti BBAD("rtVBR.2-6"); 332121934Sharti break; 333121934Sharti 334121934Sharti case UNI_TRAFFIC_nrtVBR1: 335121934Sharti NOBE("nrtVBR.1"); 336121934Sharti if (ft != fvbr16) 337121934Sharti FBAD("nrtVBR.1"); 338121934Sharti NOFT("nrtVBR.1"); 339121934Sharti if (bt != bvbr16) 340121934Sharti BBAD("nrtVBR.1"); 341121934Sharti NOBT("nrtVBR.1"); 342121934Sharti *fclass = *bclass = UNI_TRAFFIC_nrtVBR1; 343121934Sharti break; 344121934Sharti 345121934Sharti case T_nrtVBR2_6_UBR12: 346121934Sharti if (be) { 347121934Sharti if (ft != UNI_TRAFFIC_FPCR1_P) 348121934Sharti FBAD("UBR.1/2"); 349121934Sharti if (bt != UNI_TRAFFIC_BPCR1_P) 350121934Sharti BBAD("UBR.1/2"); 351121934Sharti if (ftag) 352121934Sharti *fclass = UNI_TRAFFIC_UBR2; 353121934Sharti else 354121934Sharti *fclass = UNI_TRAFFIC_UBR1; 355121934Sharti if (btag) 356121934Sharti *bclass = UNI_TRAFFIC_UBR2; 357121934Sharti else 358121934Sharti *bclass = UNI_TRAFFIC_UBR1; 359121934Sharti break; 360121934Sharti } 361121934Sharti if (ft == fvbr23) { 362121934Sharti if (ftag) 363121934Sharti *fclass = UNI_TRAFFIC_nrtVBR3; 364121934Sharti else 365121934Sharti *fclass = UNI_TRAFFIC_nrtVBR2; 366121934Sharti } else if (ft == fvbr4) { 367121934Sharti *fclass = UNI_TRAFFIC_nrtVBR4; 368121934Sharti } else if (ft == UNI_TRAFFIC_FPCR1_P) { 369121934Sharti *fclass = UNI_TRAFFIC_nrtVBR5; 370121934Sharti NOFT("nrtVBR.5"); 371121934Sharti } else if (ft == fvbr16) { 372121934Sharti *fclass = UNI_TRAFFIC_nrtVBR6; 373121934Sharti NOFT("nrtVBR.6"); 374121934Sharti } else 375121934Sharti FBAD("nrtVBR.2-6"); 376121934Sharti if (bt == bvbr23) { 377121934Sharti if (btag) 378121934Sharti *bclass = UNI_TRAFFIC_nrtVBR3; 379121934Sharti else 380121934Sharti *bclass = UNI_TRAFFIC_nrtVBR2; 381121934Sharti } else if (bt == bvbr4) { 382121934Sharti *bclass = UNI_TRAFFIC_nrtVBR4; 383121934Sharti } else if (bt == UNI_TRAFFIC_BPCR1_P) { 384121934Sharti *bclass = UNI_TRAFFIC_nrtVBR5; 385121934Sharti NOBT("nrtVBR.5"); 386121934Sharti } else if (bt == bvbr16) { 387121934Sharti *bclass = UNI_TRAFFIC_nrtVBR6; 388121934Sharti NOBT("nrtVBR.6"); 389121934Sharti } else 390121934Sharti BBAD("nrtVBR.2-6"); 391121934Sharti break; 392121934Sharti 393121934Sharti case UNI_TRAFFIC_ABR: 394121934Sharti NOBE("ABR"); 395121934Sharti if (ft != UNI_TRAFFIC_FPCR1_P) 396121934Sharti FBAD("ABR"); 397121934Sharti if (bt != UNI_TRAFFIC_BPCR1_P) 398121934Sharti BBAD("ABR"); 399121934Sharti NOFT("ABR"); 400121934Sharti NOBT("ABR"); 401121934Sharti *fclass = *bclass = UNI_TRAFFIC_ABR; 402121934Sharti break; 403121934Sharti } 404121934Sharti 405121934Sharti return (0); 406121934Sharti} 407