diff options
author | harti <harti@FreeBSD.org> | 2003-07-25 08:35:26 +0000 |
---|---|---|
committer | harti <harti@FreeBSD.org> | 2003-07-25 08:35:26 +0000 |
commit | 3988ab54c6c4cd28cf3c112c745daecff7d3ba6b (patch) | |
tree | 78040d849f07c415480c5eebfb9ac2e05da3e19f /sys/netatm | |
parent | 8c1d1fe008fd4a7cdc1d07c41facffc25ce2b16d (diff) | |
download | FreeBSD-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')
-rw-r--r-- | sys/netatm/atm_ioctl.h | 6 | ||||
-rw-r--r-- | sys/netatm/atm_socket.c | 4 | ||||
-rw-r--r-- | sys/netatm/ipatm/ipatm_usrreq.c | 101 | ||||
-rw-r--r-- | sys/netatm/ipatm/ipatm_var.h | 2 | ||||
-rw-r--r-- | sys/netatm/ipatm/ipatm_vcm.c | 98 |
5 files changed, 205 insertions, 6 deletions
diff --git a/sys/netatm/atm_ioctl.h b/sys/netatm/atm_ioctl.h index f66b62e..d23be60 100644 --- a/sys/netatm/atm_ioctl.h +++ b/sys/netatm/atm_ioctl.h @@ -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 { diff --git a/sys/netatm/atm_socket.c b/sys/netatm/atm_socket.c index 34b9d09..c0f5435 100644 --- a/sys/netatm/atm_socket.c +++ b/sys/netatm/atm_socket.c @@ -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) && 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 |