Add support for VBR and CBR PVCs for IP over ATM.

Submitted by:	Vincent Jardin <vjardin@wanadoo.fr>
MFC after:	2 weeks
This commit is contained in:
harti 2003-07-25 08:35:26 +00:00
parent 4ac693aa72
commit a727c2e451
5 changed files with 205 additions and 6 deletions

View File

@ -123,6 +123,8 @@ struct atmaddreq {
Aal_t aaru_pvc_aal; /* AAL */
Encaps_t aaru_pvc_encaps; /* Encapsulation */
u_char aaru_pvc_flags; /* Flags (see below) */
uint8_t aaru_pvc_traffic_type; /* traffic type */
struct t_atm_traffic aaru_pvc_traffic; /* traffic parameters */
} aaru_add_pvc;
/* Add ARP table entry */
@ -142,6 +144,8 @@ struct atmaddreq {
#define aar_pvc_aal aar_u.aaru_add_pvc.aaru_pvc_aal
#define aar_pvc_encaps aar_u.aaru_add_pvc.aaru_pvc_encaps
#define aar_pvc_flags aar_u.aaru_add_pvc.aaru_pvc_flags
#define aar_pvc_traffic_type aar_u.aaru_add_pvc.aaru_pvc_traffic_type
#define aar_pvc_traffic aar_u.aaru_add_pvc.aaru_pvc_traffic
#define aar_arp_intf aar_u.aaru_add_arp.aaru_arp_intf
#define aar_arp_dst aar_u.aaru_add_arp.aaru_arp_dst
#define aar_arp_addr aar_u.aaru_add_arp.aaru_arp_addr
@ -321,6 +325,8 @@ struct air_netif_rsp {
/*
* VCC information
* Todo: add avp_traffic_type and avp_traffic. Update unisig_if.c,
* spans_if.c and sigpvc_if.c
*/
#define O_CNT 8
struct air_vcc_rsp {

View File

@ -819,7 +819,9 @@ atm_sock_setopt(so, sopt, atp)
return (EINVAL);
if ((p.brr.traffic_type != T_ATM_NULL) &&
(p.brr.traffic_type != T_ATM_CBR) &&
(p.brr.traffic_type != T_ATM_VBR))
(p.brr.traffic_type != T_ATM_VBR) &&
(p.brr.traffic_type != T_ATM_ABR) &&
(p.brr.traffic_type != T_ATM_UBR))
return (EINVAL);
if ((p.brr.timing_requirements != T_ATM_NULL) &&
(p.brr.timing_requirements != T_ATM_END_TO_END) &&

View File

@ -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) {
@ -157,12 +158,112 @@ 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) {

View File

@ -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 */
};

View File

@ -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