From 3988ab54c6c4cd28cf3c112c745daecff7d3ba6b Mon Sep 17 00:00:00 2001 From: harti Date: Fri, 25 Jul 2003 08:35:26 +0000 Subject: Add support for VBR and CBR PVCs for IP over ATM. Submitted by: Vincent Jardin MFC after: 2 weeks --- sys/netatm/ipatm/ipatm_usrreq.c | 101 ++++++++++++++++++++++++++++++++++++++++ sys/netatm/ipatm/ipatm_var.h | 2 + sys/netatm/ipatm/ipatm_vcm.c | 98 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 196 insertions(+), 5 deletions(-) (limited to 'sys/netatm/ipatm') 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 -- cgit v1.1