summaryrefslogtreecommitdiffstats
path: root/sys/netatm/ipatm
diff options
context:
space:
mode:
authorharti <harti@FreeBSD.org>2003-07-25 08:35:26 +0000
committerharti <harti@FreeBSD.org>2003-07-25 08:35:26 +0000
commit3988ab54c6c4cd28cf3c112c745daecff7d3ba6b (patch)
tree78040d849f07c415480c5eebfb9ac2e05da3e19f /sys/netatm/ipatm
parent8c1d1fe008fd4a7cdc1d07c41facffc25ce2b16d (diff)
downloadFreeBSD-src-3988ab54c6c4cd28cf3c112c745daecff7d3ba6b.zip
FreeBSD-src-3988ab54c6c4cd28cf3c112c745daecff7d3ba6b.tar.gz
Add support for VBR and CBR PVCs for IP over ATM.
Submitted by: Vincent Jardin <vjardin@wanadoo.fr> MFC after: 2 weeks
Diffstat (limited to 'sys/netatm/ipatm')
-rw-r--r--sys/netatm/ipatm/ipatm_usrreq.c101
-rw-r--r--sys/netatm/ipatm/ipatm_var.h2
-rw-r--r--sys/netatm/ipatm/ipatm_vcm.c98
3 files changed, 196 insertions, 5 deletions
diff --git a/sys/netatm/ipatm/ipatm_usrreq.c b/sys/netatm/ipatm/ipatm_usrreq.c
index df4721e..b98ae26 100644
--- a/sys/netatm/ipatm/ipatm_usrreq.c
+++ b/sys/netatm/ipatm/ipatm_usrreq.c
@@ -91,6 +91,7 @@ ipatm_ioctl(code, data, arg1)
caddr_t cp;
struct in_addr ip;
int space, err = 0;
+ struct t_atm_traffic *traf;
switch (code) {
@@ -158,11 +159,111 @@ ipatm_ioctl(code, data, arg1)
}
/*
+ * Validate PVC traffic
+ */
+#define MAXVAL(bits) ((1 << bits) - 1)
+#define MAXMASK(bits) (~MAXVAL(bits))
+ traf = &aap->aar_pvc_traffic;
+ switch (aap->aar_pvc_traffic_type) {
+
+ case T_ATM_CBR:
+ case T_ATM_UBR:
+ /*
+ * PCR is a value between 0 to the PIF's PCR
+ */
+ if (traf->forward.PCR_high_priority == T_ATM_ABSENT ||
+ (traf->forward.PCR_high_priority & MAXMASK(24))) {
+ err = EINVAL;
+ break;
+ }
+ if (traf->forward.PCR_all_traffic == T_ATM_ABSENT ||
+ (traf->forward.PCR_all_traffic & MAXMASK(24))) {
+ err = EINVAL;
+ break;
+ }
+
+ if (traf->backward.PCR_high_priority == T_ATM_ABSENT ||
+ (traf->backward.PCR_high_priority & MAXMASK(24))) {
+ err = EINVAL;
+ break;
+ }
+ if (traf->backward.PCR_all_traffic == T_ATM_ABSENT ||
+ (traf->backward.PCR_all_traffic & MAXMASK(24))) {
+ err = EINVAL;
+ break;
+ }
+ break;
+
+ case T_ATM_VBR:
+ /*
+ * PCR, SCR and MBS are required
+ */
+ if (traf->forward.PCR_high_priority == T_ATM_ABSENT ||
+ (traf->forward.PCR_high_priority & MAXMASK(24)) ||
+ traf->forward.PCR_all_traffic == T_ATM_ABSENT ||
+ (traf->forward.PCR_all_traffic & MAXMASK(24))) {
+ err = EINVAL;
+ break;
+ }
+ if (traf->forward.SCR_high_priority == T_ATM_ABSENT ||
+ (traf->forward.SCR_high_priority & MAXMASK(24)) ||
+ traf->forward.SCR_all_traffic == T_ATM_ABSENT ||
+ (traf->forward.SCR_all_traffic & MAXMASK(24))) {
+ err = EINVAL;
+ break;
+ }
+ if (traf->forward.MBS_high_priority == T_ATM_ABSENT ||
+ (traf->forward.MBS_high_priority & MAXMASK(24)) ||
+ traf->forward.MBS_all_traffic == T_ATM_ABSENT ||
+ (traf->forward.MBS_all_traffic & MAXMASK(24))) {
+ err = EINVAL;
+ break;
+ }
+
+ if (traf->backward.PCR_high_priority == T_ATM_ABSENT ||
+ (traf->backward.PCR_high_priority & MAXMASK(24)) ||
+ traf->backward.PCR_all_traffic == T_ATM_ABSENT ||
+ (traf->backward.PCR_all_traffic & MAXMASK(24))) {
+ err = EINVAL;
+ break;
+ }
+ if (traf->backward.SCR_high_priority == T_ATM_ABSENT ||
+ (traf->backward.SCR_high_priority & MAXMASK(24)) ||
+ traf->backward.SCR_all_traffic == T_ATM_ABSENT ||
+ (traf->backward.SCR_all_traffic & MAXMASK(24))) {
+ err = EINVAL;
+ break;
+ }
+ if (traf->backward.MBS_high_priority == T_ATM_ABSENT ||
+ (traf->backward.MBS_high_priority & MAXMASK(24)) ||
+ traf->backward.MBS_all_traffic == T_ATM_ABSENT ||
+ (traf->backward.MBS_all_traffic & MAXMASK(24))) {
+ err = EINVAL;
+ break;
+ }
+ break;
+
+ case T_ATM_NULL:
+ /*
+ * No PVC traffic type
+ */
+ break;
+
+ default:
+ err = EINVAL;
+ break;
+ }
+ if (err != 0)
+ break;
+
+ /*
* Build connection request
*/
pv.ipp_ipnif = inp;
pv.ipp_vpi = aap->aar_pvc_vpi;
pv.ipp_vci = aap->aar_pvc_vci;
+ pv.ipp_traffic_type = aap->aar_pvc_traffic_type;
+ pv.ipp_traffic = aap->aar_pvc_traffic;
pv.ipp_encaps = aap->aar_pvc_encaps;
pv.ipp_aal = aap->aar_pvc_aal;
if (aap->aar_pvc_flags & PVC_DYN) {
diff --git a/sys/netatm/ipatm/ipatm_var.h b/sys/netatm/ipatm/ipatm_var.h
index fa79a94..d0e0d3e 100644
--- a/sys/netatm/ipatm/ipatm_var.h
+++ b/sys/netatm/ipatm/ipatm_var.h
@@ -136,6 +136,8 @@ struct ipatmpvc {
Aal_t ipp_aal; /* AAL type */
Encaps_t ipp_encaps; /* VCC encapsulation */
struct sockaddr_in ipp_dst; /* Destination's IP address */
+ uint8_t ipp_traffic_type; /* CBR, UBR, ... */
+ struct t_atm_traffic ipp_traffic; /* traffic parameters */
};
diff --git a/sys/netatm/ipatm/ipatm_vcm.c b/sys/netatm/ipatm/ipatm_vcm.c
index a14f1f1..fe01936 100644
--- a/sys/netatm/ipatm/ipatm_vcm.c
+++ b/sys/netatm/ipatm/ipatm_vcm.c
@@ -391,19 +391,105 @@ ipatm_openpvc(pvp, sivp)
/*
* Fill out connection attributes
+ * Make a temporary copy of the attributes here so that we
+ * do not change the default attributes for SVCs. Otherwise this
+ * will give trouble in a mixed SVC/PVC case.
*/
+ ap = malloc(sizeof(*ap), M_TEMP, M_NOWAIT);
+ if (ap == NULL) {
+ err = ENOMEM;
+ goto done;
+ }
if (pvp->ipp_aal == ATM_AAL5) {
if (pvp->ipp_encaps == ATM_ENC_LLC)
- ap = &ipatm_aal5llc;
+ *ap = ipatm_aal5llc;
else
- ap = &ipatm_aal5null;
+ *ap = ipatm_aal5null;
} else {
- ap = &ipatm_aal4null;
+ *ap = ipatm_aal4null;
}
+ /*
+ * Build the ATM attributes
+ */
ap->nif = nip;
- ap->traffic.v.forward.PCR_all_traffic = nip->nif_pif->pif_pcr;
- ap->traffic.v.backward.PCR_all_traffic = nip->nif_pif->pif_pcr;
+
+ ap->bearer.v.traffic_type = pvp->ipp_traffic_type;
+ switch(ap->bearer.v.traffic_type) {
+ case T_ATM_UBR:
+ case T_ATM_CBR:
+ /*
+ * PCR=0 means `use up to the PIF's PCR'
+ */
+ if (pvp->ipp_traffic.forward.PCR_all_traffic == 0)
+ ap->traffic.v.forward.PCR_all_traffic =
+ nip->nif_pif->pif_pcr;
+ else
+ ap->traffic.v.forward.PCR_all_traffic =
+ pvp->ipp_traffic.forward.PCR_all_traffic;
+
+ if (pvp->ipp_traffic.forward.PCR_high_priority == 0)
+ ap->traffic.v.forward.PCR_high_priority =
+ nip->nif_pif->pif_pcr;
+ else
+ ap->traffic.v.forward.PCR_high_priority =
+ pvp->ipp_traffic.forward.PCR_high_priority;
+
+ if (pvp->ipp_traffic.backward.PCR_all_traffic == 0)
+ ap->traffic.v.backward.PCR_all_traffic =
+ nip->nif_pif->pif_pcr;
+ else
+ ap->traffic.v.backward.PCR_all_traffic =
+ pvp->ipp_traffic.backward.PCR_all_traffic;
+
+ if (pvp->ipp_traffic.backward.PCR_high_priority == 0)
+ ap->traffic.v.backward.PCR_high_priority =
+ nip->nif_pif->pif_pcr;
+ else
+ ap->traffic.v.backward.PCR_high_priority =
+ pvp->ipp_traffic.backward.PCR_high_priority;
+ break;
+
+ case T_ATM_VBR:
+ ap->traffic.v.forward.PCR_all_traffic =
+ pvp->ipp_traffic.forward.PCR_all_traffic;
+ ap->traffic.v.forward.PCR_high_priority =
+ pvp->ipp_traffic.forward.PCR_high_priority;
+ ap->traffic.v.forward.SCR_all_traffic =
+ pvp->ipp_traffic.forward.SCR_all_traffic;
+ ap->traffic.v.forward.SCR_high_priority =
+ pvp->ipp_traffic.forward.SCR_high_priority;
+ ap->traffic.v.forward.MBS_all_traffic =
+ pvp->ipp_traffic.forward.MBS_all_traffic;
+ ap->traffic.v.forward.MBS_high_priority =
+ pvp->ipp_traffic.forward.MBS_high_priority;
+
+ ap->traffic.v.backward.PCR_all_traffic =
+ pvp->ipp_traffic.backward.PCR_all_traffic;
+ ap->traffic.v.backward.PCR_high_priority =
+ pvp->ipp_traffic.backward.PCR_high_priority;
+ ap->traffic.v.backward.SCR_all_traffic =
+ pvp->ipp_traffic.backward.SCR_all_traffic;
+ ap->traffic.v.backward.SCR_high_priority =
+ pvp->ipp_traffic.backward.SCR_high_priority;
+ ap->traffic.v.backward.MBS_all_traffic =
+ pvp->ipp_traffic.backward.MBS_all_traffic;
+ ap->traffic.v.backward.MBS_high_priority =
+ pvp->ipp_traffic.backward.MBS_high_priority;
+ break;
+
+ case T_ATM_NULL:
+ /*
+ * No traffic type
+ */
+ /* FALLTHRU */
+ default:
+ ap->traffic.v.forward.PCR_all_traffic =
+ nip->nif_pif->pif_pcr;
+ ap->traffic.v.backward.PCR_all_traffic =
+ nip->nif_pif->pif_pcr;
+ break;
+ }
ap->called.addr.address_format = T_ATM_PVC_ADDR;
ap->called.addr.address_length = sizeof(Atm_addr_pvc);
pvcp = (Atm_addr_pvc *)ap->called.addr.address;
@@ -417,6 +503,7 @@ ipatm_openpvc(pvp, sivp)
*/
err = atm_cm_connect(&ipatm_endpt, ivp, ap, &ivp->iv_conn);
if (err) {
+ free(ap, M_TEMP);
uma_zfree(ipatm_vc_zone, ivp);
goto done;
}
@@ -425,6 +512,7 @@ ipatm_openpvc(pvp, sivp)
* Save PVC information and link in VCC
*/
/* ivp->iv_ = ap->headout; */
+ free(ap, M_TEMP);
/*
* Queue VCC onto its network interface
OpenPOWER on IntegriCloud