summaryrefslogtreecommitdiffstats
path: root/sys/contrib/ngatm/netnatm/msg/traffic.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/ngatm/netnatm/msg/traffic.c')
-rw-r--r--sys/contrib/ngatm/netnatm/msg/traffic.c406
1 files changed, 406 insertions, 0 deletions
diff --git a/sys/contrib/ngatm/netnatm/msg/traffic.c b/sys/contrib/ngatm/netnatm/msg/traffic.c
new file mode 100644
index 0000000..f941ded
--- /dev/null
+++ b/sys/contrib/ngatm/netnatm/msg/traffic.c
@@ -0,0 +1,406 @@
+/*
+ * Copyright (c) 2001-2003
+ * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author: Hartmut Brandt <harti@freebsd.org>
+ *
+ * $Begemot: libunimsg/atm/msg/traffic.c,v 1.3 2003/09/19 11:58:15 hbb Exp $
+ *
+ * Traffic classification
+ */
+
+#include <netnatm/unimsg.h>
+#include <netnatm/msg/unistruct.h>
+#include <netnatm/msg/unimsglib.h>
+#ifdef _KERNEL
+#include <sys/systm.h>
+#else
+#include <stdio.h>
+#endif
+
+/*
+ * Try to set the parameters for the CPCS from the parameters of the
+ * connection.
+ */
+enum {
+ T_CBR23 = 100, T_nrtVBR2_6_UBR12, T_rtVBR236, T_rtVBR2_6
+};
+
+static const u_int fmask = UNI_TRAFFIC_FPCR0_P | UNI_TRAFFIC_FPCR1_P |
+ UNI_TRAFFIC_FSCR0_P | UNI_TRAFFIC_FSCR1_P | UNI_TRAFFIC_FMBS0_P |
+ UNI_TRAFFIC_FMBS1_P | UNI_TRAFFIC_FABR1_P;
+static const u_int bmask = UNI_TRAFFIC_BPCR0_P | UNI_TRAFFIC_BPCR1_P |
+ UNI_TRAFFIC_BSCR0_P | UNI_TRAFFIC_BSCR1_P | UNI_TRAFFIC_BMBS0_P |
+ UNI_TRAFFIC_BMBS1_P | UNI_TRAFFIC_BABR1_P;
+
+static const u_int fcbr3 = UNI_TRAFFIC_FPCR0_P | UNI_TRAFFIC_FPCR1_P;
+static const u_int bcbr3 = UNI_TRAFFIC_BPCR0_P | UNI_TRAFFIC_BPCR1_P;
+static const u_int fvbr16 = UNI_TRAFFIC_FPCR1_P | UNI_TRAFFIC_FSCR1_P |
+ UNI_TRAFFIC_FMBS1_P;
+static const u_int bvbr16 = UNI_TRAFFIC_BPCR1_P | UNI_TRAFFIC_BSCR1_P |
+ UNI_TRAFFIC_BMBS1_P;
+static const u_int fvbr23 = UNI_TRAFFIC_FPCR1_P | UNI_TRAFFIC_FSCR0_P |
+ UNI_TRAFFIC_FMBS0_P;
+static const u_int bvbr23 = UNI_TRAFFIC_BPCR1_P | UNI_TRAFFIC_BSCR0_P |
+ UNI_TRAFFIC_BMBS0_P;
+static const u_int fvbr4 = UNI_TRAFFIC_FPCR0_P | UNI_TRAFFIC_FPCR1_P;
+static const u_int bvbr4 = UNI_TRAFFIC_BPCR0_P | UNI_TRAFFIC_BPCR1_P;
+
+int
+uni_classify_traffic(const struct uni_ie_bearer *bearer,
+ const struct uni_ie_traffic *traffic,
+ enum uni_traffic_class *fclass, enum uni_traffic_class *bclass,
+ char *ebuf, size_t ebufsiz)
+{
+ u_int tclass;
+ u_int ft, bt, be, ftag, btag;
+
+ /* classify */
+ switch (bearer->bclass) {
+
+ case UNI_BEARER_A:
+ if (!(bearer->h.present & UNI_BEARER_ATC_P)) {
+ tclass = T_CBR23;
+ break;
+ }
+ switch (bearer->atc) {
+
+ case UNI_BEARER_ATC_CBR1:
+ tclass = UNI_TRAFFIC_CBR1;
+ break;
+
+ default:
+ snprintf(ebuf, ebufsiz, "bad ATC=%#02x for BCOB-A",
+ bearer->atc);
+ return (-1);
+ }
+ break;
+
+ case UNI_BEARER_C:
+ if (!(bearer->h.present & UNI_BEARER_ATC_P)) {
+ tclass = T_nrtVBR2_6_UBR12;
+ break;
+ }
+ switch (bearer->atc) {
+
+ case UNI_BEARER_ATC_VBR1:
+ tclass = UNI_TRAFFIC_rtVBR1;
+ break;
+
+ case UNI_BEARER_ATC_VBR:
+ tclass = T_rtVBR236;
+ break;
+
+ case UNI_BEARER_ATC_NVBR1:
+ tclass = UNI_TRAFFIC_nrtVBR1;
+ break;
+
+ case UNI_BEARER_ATC_ABR:
+ tclass = UNI_TRAFFIC_ABR;
+ break;
+
+ default:
+ snprintf(ebuf, ebufsiz, "bad ATC=%#02x for BCOB-C",
+ bearer->atc);
+ return (-1);
+ }
+ break;
+
+ case UNI_BEARER_X:
+ if (!(bearer->h.present & UNI_BEARER_ATC_P)) {
+ tclass = T_nrtVBR2_6_UBR12;
+ break;
+ }
+ switch (bearer->atc) {
+
+ case UNI_BEARER_ATC_CBR1:
+ tclass = UNI_TRAFFIC_CBR1;
+ break;
+
+ case UNI_BEARER_ATC_CBR:
+ case UNI_BEARER_ATCX_4:
+ case UNI_BEARER_ATCX_6:
+ tclass = T_CBR23;
+ break;
+
+ case UNI_BEARER_ATC_VBR1:
+ tclass = UNI_TRAFFIC_rtVBR1;
+ break;
+
+ case UNI_BEARER_ATCX_1:
+ case UNI_BEARER_ATC_VBR:
+ tclass = T_rtVBR2_6;
+ break;
+
+ case UNI_BEARER_ATC_NVBR1:
+ tclass = UNI_TRAFFIC_nrtVBR1;
+ break;
+
+ case UNI_BEARER_ATCX_0:
+ case UNI_BEARER_ATCX_2:
+ case UNI_BEARER_ATCX_8:
+ case UNI_BEARER_ATC_NVBR:
+ tclass = T_nrtVBR2_6_UBR12;
+ break;
+
+ case UNI_BEARER_ATC_ABR:
+ tclass = UNI_TRAFFIC_ABR;
+ break;
+
+ default:
+ snprintf(ebuf, ebufsiz, "bad ATC=%#02x for BCOB-X",
+ bearer->atc);
+ return (-1);
+ }
+ break;
+
+ case UNI_BEARER_TVP:
+ snprintf(ebuf, ebufsiz, "unsupported bearer class tVP");
+ return (-1);
+
+ default:
+ snprintf(ebuf, ebufsiz, "bad bearer class %#02x",
+ bearer->bclass);
+ return (-1);
+ }
+
+ /*
+ * Now traffic IE
+ */
+ ft = traffic->h.present & fmask;
+ bt = traffic->h.present & bmask;
+ be = traffic->h.present & UNI_TRAFFIC_BEST_P;
+ ftag = (traffic->h.present & UNI_TRAFFIC_MOPT_P) && traffic->t.ftag;
+ btag = (traffic->h.present & UNI_TRAFFIC_MOPT_P) && traffic->t.btag;
+
+#define NOBE(C) \
+ if (be) { \
+ snprintf(ebuf, ebufsiz, "illegal BE for " C); \
+ return (-1); \
+ }
+
+#define NOFT(C) \
+ if (ftag) { \
+ snprintf(ebuf, ebufsiz, "illegal forward tag in " C); \
+ return (-1); \
+ }
+
+#define NOBT(C) \
+ if (btag) { \
+ snprintf(ebuf, ebufsiz, "illegal backward tag in " C); \
+ return (-1); \
+ }
+
+#define FBAD(C) do { \
+ snprintf(ebuf, ebufsiz, "bad forward CRs for " C); \
+ return (-1); \
+ } while (0)
+
+#define BBAD(C) do { \
+ snprintf(ebuf, ebufsiz, "bad backward CRs for " C); \
+ return (-1); \
+ } while (0)
+
+ switch (tclass) {
+
+ case UNI_TRAFFIC_CBR1:
+ NOBE("CBR.1");
+ if (ft != UNI_TRAFFIC_FPCR1_P)
+ FBAD("CBR.1");
+ NOFT("CBR.1");
+ if (bt != UNI_TRAFFIC_BPCR1_P)
+ BBAD("CBR.1");
+ NOBT("CBR.1");
+ *fclass = *bclass = UNI_TRAFFIC_CBR1;
+ break;
+
+ case T_CBR23:
+ NOBE("CBR.2/3");
+ if (ft == UNI_TRAFFIC_FPCR0_P) {
+ *fclass = UNI_TRAFFIC_CBR2;
+ NOFT("CBR.2");
+ } else if (ft == fcbr3) {
+ *fclass = UNI_TRAFFIC_CBR3;
+ if (!ftag) {
+ snprintf(ebuf, ebufsiz, "need forward tagging for CBR.3");
+ return (-1);
+ }
+ } else
+ FBAD("CBR.2/3");
+ if (bt == UNI_TRAFFIC_BPCR0_P) {
+ *bclass = UNI_TRAFFIC_CBR2;
+ NOBT("CBR.2");
+ } else if (bt == bcbr3) {
+ *bclass = UNI_TRAFFIC_CBR3;
+ if (!btag) {
+ snprintf(ebuf, ebufsiz, "need backward tagging for CBR.3");
+ return (-1);
+ }
+ } else
+ BBAD("CBR.2/3");
+ break;
+
+ case UNI_TRAFFIC_rtVBR1:
+ NOBE("rtVBR.1");
+ if (ft != fvbr16)
+ FBAD("rtVBR.1");
+ NOFT("rtVBR.1");
+ if (bt != bvbr16)
+ BBAD("rtVBR.1");
+ NOBT("rtVBR.1");
+ *fclass = *bclass = UNI_TRAFFIC_rtVBR1;
+ break;
+
+ case T_rtVBR236:
+ NOBE("rtVBR.2/3/6");
+ if (ft == fvbr23) {
+ if (ftag)
+ *fclass = UNI_TRAFFIC_rtVBR3;
+ else
+ *fclass = UNI_TRAFFIC_rtVBR2;
+ } else if (ft == fvbr16) {
+ *fclass = UNI_TRAFFIC_rtVBR6;
+ NOFT("rtVBR.6");
+ } else
+ FBAD("rtVBR.2/3/6");
+ if (bt == bvbr23) {
+ if (btag)
+ *bclass = UNI_TRAFFIC_rtVBR3;
+ else
+ *bclass = UNI_TRAFFIC_rtVBR2;
+ } else if (bt == bvbr16) {
+ *bclass = UNI_TRAFFIC_rtVBR6;
+ NOBT("rtVBR.6");
+ } else
+ BBAD("rtVBR.2/3/6");
+ break;
+
+ case T_rtVBR2_6:
+ NOBE("rtVBR.2-6");
+ if (ft == fvbr23) {
+ if (ftag)
+ *fclass = UNI_TRAFFIC_rtVBR3;
+ else
+ *fclass = UNI_TRAFFIC_rtVBR2;
+ } else if (ft == fvbr4) {
+ *fclass = UNI_TRAFFIC_rtVBR4;
+ } else if (ft == UNI_TRAFFIC_FPCR1_P) {
+ *fclass = UNI_TRAFFIC_rtVBR5;
+ NOFT("rtVBR.5");
+ } else if (ft == fvbr16) {
+ *fclass = UNI_TRAFFIC_rtVBR6;
+ NOFT("rtVBR.6");
+ } else
+ FBAD("rtVBR.2-6");
+ if (bt == bvbr23) {
+ if (btag)
+ *bclass = UNI_TRAFFIC_rtVBR3;
+ else
+ *bclass = UNI_TRAFFIC_rtVBR2;
+ } else if (bt == bvbr4) {
+ *bclass = UNI_TRAFFIC_rtVBR4;
+ } else if (bt == UNI_TRAFFIC_BPCR1_P) {
+ *bclass = UNI_TRAFFIC_rtVBR5;
+ NOBT("rtVBR.5");
+ } else if (bt == bvbr16) {
+ *bclass = UNI_TRAFFIC_rtVBR6;
+ NOBT("rtVBR.6");
+ } else
+ BBAD("rtVBR.2-6");
+ break;
+
+ case UNI_TRAFFIC_nrtVBR1:
+ NOBE("nrtVBR.1");
+ if (ft != fvbr16)
+ FBAD("nrtVBR.1");
+ NOFT("nrtVBR.1");
+ if (bt != bvbr16)
+ BBAD("nrtVBR.1");
+ NOBT("nrtVBR.1");
+ *fclass = *bclass = UNI_TRAFFIC_nrtVBR1;
+ break;
+
+ case T_nrtVBR2_6_UBR12:
+ if (be) {
+ if (ft != UNI_TRAFFIC_FPCR1_P)
+ FBAD("UBR.1/2");
+ if (bt != UNI_TRAFFIC_BPCR1_P)
+ BBAD("UBR.1/2");
+ if (ftag)
+ *fclass = UNI_TRAFFIC_UBR2;
+ else
+ *fclass = UNI_TRAFFIC_UBR1;
+ if (btag)
+ *bclass = UNI_TRAFFIC_UBR2;
+ else
+ *bclass = UNI_TRAFFIC_UBR1;
+ break;
+ }
+ if (ft == fvbr23) {
+ if (ftag)
+ *fclass = UNI_TRAFFIC_nrtVBR3;
+ else
+ *fclass = UNI_TRAFFIC_nrtVBR2;
+ } else if (ft == fvbr4) {
+ *fclass = UNI_TRAFFIC_nrtVBR4;
+ } else if (ft == UNI_TRAFFIC_FPCR1_P) {
+ *fclass = UNI_TRAFFIC_nrtVBR5;
+ NOFT("nrtVBR.5");
+ } else if (ft == fvbr16) {
+ *fclass = UNI_TRAFFIC_nrtVBR6;
+ NOFT("nrtVBR.6");
+ } else
+ FBAD("nrtVBR.2-6");
+ if (bt == bvbr23) {
+ if (btag)
+ *bclass = UNI_TRAFFIC_nrtVBR3;
+ else
+ *bclass = UNI_TRAFFIC_nrtVBR2;
+ } else if (bt == bvbr4) {
+ *bclass = UNI_TRAFFIC_nrtVBR4;
+ } else if (bt == UNI_TRAFFIC_BPCR1_P) {
+ *bclass = UNI_TRAFFIC_nrtVBR5;
+ NOBT("nrtVBR.5");
+ } else if (bt == bvbr16) {
+ *bclass = UNI_TRAFFIC_nrtVBR6;
+ NOBT("nrtVBR.6");
+ } else
+ BBAD("nrtVBR.2-6");
+ break;
+
+ case UNI_TRAFFIC_ABR:
+ NOBE("ABR");
+ if (ft != UNI_TRAFFIC_FPCR1_P)
+ FBAD("ABR");
+ if (bt != UNI_TRAFFIC_BPCR1_P)
+ BBAD("ABR");
+ NOFT("ABR");
+ NOBT("ABR");
+ *fclass = *bclass = UNI_TRAFFIC_ABR;
+ break;
+ }
+
+ return (0);
+}
OpenPOWER on IntegriCloud