Add support for CBR and VBR PVCs. Enhance the error handling for

the 'add pvc' command.

Submitted by:	Vincent Jardin <vjardin@wanadoo.fr>
MFC after:	2 weeks
This commit is contained in:
harti 2003-07-28 15:27:12 +00:00
parent a3f9f68a5c
commit 0f7d88f255
3 changed files with 158 additions and 38 deletions

View File

@ -97,7 +97,7 @@ IP management subcommands:
[<netif>] <host> <ATM address> [<netif>] <host> <ATM address>
.ti -5 .ti -5
.B atm add PVC .B atm add PVC
<interface> <vpi> <vci> <aal> <encaps> IP <netif> <host> | dynamic <interface> <vpi> <vci> <aal> <encaps> IP <netif> [<host> | dynamic] <traffic> <params> ...
.ti -5 .ti -5
.B atm delete ARP .B atm delete ARP
[<netif>] <host> [<netif>] <host>
@ -717,7 +717,7 @@ be subject to aging.
.PP .PP
.in +5 .in +5
.ti -5 .ti -5
\fIatm add PVC <interface> <vpi> <vci> <aal> <encaps> IP <netif> <host> | dynamic\fP \fIatm add PVC <interface> <vpi> <vci> <aal> <encaps> IP <netif> [<host> | dynamic] <traffic> <params...>\fP
.in -5 .in -5
.PP .PP
where: where:
@ -751,6 +751,12 @@ the far end of the PVC, or the word "dynamic" if its address
is to be determined with Inverse ARP. is to be determined with Inverse ARP.
If "dynamic" is specified, LLC/SNAP encapsulation must also If "dynamic" is specified, LLC/SNAP encapsulation must also
be specified. be specified.
.ti -5
\fI<traffic>\fP is the traffic type of the PVC and may be one of
UBR, CBR or VBR.
Following the traffic type the traffic parameters must be given.
For UBR and CBR this is the peak cell rate and for VBR these
are the peak and sustainable cell rate and the maximum burst size.
.PP .PP
This command creates a PVC with the specified attributes and attaches This command creates a PVC with the specified attributes and attaches
it to IP. it to IP.

View File

@ -55,6 +55,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <err.h>
#include "atm.h" #include "atm.h"
@ -135,7 +136,7 @@ static const struct cmd cmds[] = {
static const struct cmd add_subcmd[] = { static const struct cmd add_subcmd[] = {
{ "arp", 2, 3, arp_add, "[<netif>] <IP addr> <ATM addr>" }, { "arp", 2, 3, arp_add, "[<netif>] <IP addr> <ATM addr>" },
{ "pvc", 6, 12, pvc_add, "<intf> <vpi> <vci> <aal> <encaps> <owner> ..." }, { "pvc", 6, 16, pvc_add, "<intf> <vpi> <vci> <aal> <encaps> <owner> <netif> ... [UBR | CBR | VBR]" },
{ 0, 0, 0, NULL, "" } { 0, 0, 0, NULL, "" }
}; };
@ -224,6 +225,19 @@ const struct encaps encaps[] = {
{ 0, 0 }, { 0, 0 },
}; };
/*
* Supported ATM traffic types
*/
struct traffics traffics[] = {
{ "UBR", T_ATM_UBR, 1, "UBR <pcr>" },
{ "CBR", T_ATM_CBR, 1, "CBR <pcr>" },
{ "VBR", T_ATM_VBR, 3, "VBR <pcr> <scr> <mbs>" },
#ifdef notyet
{ "ABR", T_ATM_ABR, 2, "ABR <arg1> <arg2>" },
#endif
{ NULL, 0, 0, NULL }
};
char *prog; char *prog;
char prefix[128] = ""; char prefix[128] = "";
@ -522,7 +536,7 @@ detach(int argc __unused, char **argv, const struct cmd *cmdp __unused)
* *
* Command format: * Command format:
* atm add PVC <interface_name> <vpi> <vci> <aal> <encaps> * atm add PVC <interface_name> <vpi> <vci> <aal> <encaps>
* <owner_name> * <owner_name> [ubr <PCR> | cbr <PCR> | vbr <PCR> <SCR> <MBS>]
* *
* Arguments: * Arguments:
* argc number of arguments to command * argc number of arguments to command
@ -542,8 +556,9 @@ pvc_add(int argc, char **argv, const struct cmd *cmdp)
const struct owner *owp; const struct owner *owp;
const struct aal *alp; const struct aal *alp;
const struct encaps *enp; const struct encaps *enp;
const struct traffics *trafp;
char *cp; char *cp;
long v; u_long v;
int buf_len, s; int buf_len, s;
/* /*
@ -589,21 +604,21 @@ pvc_add(int argc, char **argv, const struct cmd *cmdp)
/* /*
* Validate vpi/vci values * Validate vpi/vci values
*/ */
v = strtol(argv[0], &cp, 0); errno = 0;
if ((*cp != '\0') || (v < 0) || (v >= 1 << 8)) { v = strtoul(argv[0], &cp, 0);
fprintf(stderr, "%s: Invalid VPI value\n", prog); if (errno != 0 || *cp != '\0' || v >= 1 << 8)
exit(1); errx(1, "Invalid VPI value '%s'", argv[0]);
} apr.aar_pvc_vpi = (u_short)v;
apr.aar_pvc_vpi = (u_short) v; argc--;
argc--; argv++; argv++;
v = strtol(argv[0], &cp, 0); errno = 0;
if ((*cp != '\0') || (v < MIN_VCI) || (v >= 1 << 16)) { v = strtoul(argv[0], &cp, 0);
fprintf(stderr, "%s: Invalid VCI value\n", prog); if (errno != 0 || *cp != '\0' || v < MIN_VCI || v >= 1 << 16)
exit(1); errx(1, "Invalid VCI value '%s'", argv[0]);
} apr.aar_pvc_vci = (u_short)v;
apr.aar_pvc_vci = (u_short) v; argc--;
argc--; argv++; argv++;
/* /*
* Validate requested PVC AAL * Validate requested PVC AAL
@ -612,12 +627,11 @@ pvc_add(int argc, char **argv, const struct cmd *cmdp)
if (strcasecmp(alp->a_name, argv[0]) == 0) if (strcasecmp(alp->a_name, argv[0]) == 0)
break; break;
} }
if (alp->a_name == NULL) { if (alp->a_name == NULL)
fprintf(stderr, "%s: Invalid PVC AAL\n", prog); errx(1, "Invalid PVC AAL '%s'", argv[0]);
exit(1);
}
apr.aar_pvc_aal = alp->a_id; apr.aar_pvc_aal = alp->a_id;
argc--; argv++; argc--;
argv++;
/* /*
* Validate requested PVC encapsulation * Validate requested PVC encapsulation
@ -626,12 +640,11 @@ pvc_add(int argc, char **argv, const struct cmd *cmdp)
if (strcasecmp(enp->e_name, argv[0]) == 0) if (strcasecmp(enp->e_name, argv[0]) == 0)
break; break;
} }
if (enp->e_name == NULL) { if (enp->e_name == NULL)
fprintf(stderr, "%s: Invalid PVC encapsulation\n", prog); errx(1, "Invalid PVC encapsulation '%s'", argv[0]);
exit(1);
}
apr.aar_pvc_encaps = enp->e_id; apr.aar_pvc_encaps = enp->e_id;
argc--; argv++; argc--;
argv++;
/* /*
* Validate requested PVC owner * Validate requested PVC owner
@ -640,22 +653,113 @@ pvc_add(int argc, char **argv, const struct cmd *cmdp)
if (strcasecmp(owp->o_name, argv[0]) == 0) if (strcasecmp(owp->o_name, argv[0]) == 0)
break; break;
} }
if (owp->o_name == NULL) { if (owp->o_name == NULL)
fprintf(stderr, "%s: Unknown PVC owner\n", prog); errx(1, "Unknown PVC owner '%s'", argv[0]);
exit(1);
}
apr.aar_pvc_sap = owp->o_sap; apr.aar_pvc_sap = owp->o_sap;
argc--; argv++; if (owp->o_pvcadd == NULL)
errx(1, "Unsupported PVC owner '%s'", argv[0]);
argc--;
argv++;
/* /*
* Perform service user processing * Perform service user processing
*/ */
if (owp->o_pvcadd) { (*owp->o_pvcadd)(argc, argv, cmdp, &apr, int_info);
(*owp->o_pvcadd)(argc, argv, cmdp, &apr, int_info);
argc -= 2;
argv += 2;
if (argc > 0) {
/*
* Validate requested traffic
*/
for (trafp = traffics; trafp->t_name; trafp++) {
if (strcasecmp(trafp->t_name, argv[0]) == 0)
break;
}
if (trafp->t_name == NULL)
errx(1, "Unknown traffic type '%s'", argv[0]);
apr.aar_pvc_traffic_type = trafp->t_type;
argc--;
argv++;
if (trafp->t_argc != argc)
errx(1, "Invalid traffic parameters\n\t %s",
trafp->help);
switch (trafp->t_type) {
case T_ATM_UBR:
case T_ATM_CBR:
errno = 0;
v = strtoul(argv[0], &cp, 0);
if (errno != 0 || *cp != '\0' || v >= 1 << 24)
errx(1, "Invalid PCR value '%s'", argv[0]);
apr.aar_pvc_traffic.forward.PCR_high_priority = (int32_t) v;
apr.aar_pvc_traffic.forward.PCR_all_traffic = (int32_t) v;
apr.aar_pvc_traffic.backward.PCR_high_priority = (int32_t) v;
apr.aar_pvc_traffic.backward.PCR_all_traffic = (int32_t) v;
argc--;
argv++;
apr.aar_pvc_traffic.forward.SCR_high_priority = T_ATM_ABSENT;
apr.aar_pvc_traffic.forward.SCR_all_traffic = T_ATM_ABSENT;
apr.aar_pvc_traffic.backward.SCR_high_priority = T_ATM_ABSENT;
apr.aar_pvc_traffic.backward.SCR_all_traffic = T_ATM_ABSENT;
apr.aar_pvc_traffic.forward.MBS_high_priority = T_ATM_ABSENT;
apr.aar_pvc_traffic.forward.MBS_all_traffic = T_ATM_ABSENT;
apr.aar_pvc_traffic.backward.MBS_high_priority = T_ATM_ABSENT;
apr.aar_pvc_traffic.backward.MBS_all_traffic = T_ATM_ABSENT;
break;
case T_ATM_VBR: /* VBR pcr scr mbs */
errno = 0;
v = strtoul(argv[0], &cp, 0);
if (errno != 0 || *cp != '\0' || v >= 1 << 24)
errx(1, "Invalid PCR value '%s'", argv[0]);
apr.aar_pvc_traffic.forward.PCR_high_priority = (int32_t)v;
apr.aar_pvc_traffic.forward.PCR_all_traffic = (int32_t)v;
apr.aar_pvc_traffic.backward.PCR_high_priority = (int32_t)v;
apr.aar_pvc_traffic.backward.PCR_all_traffic = (int32_t)v;
argc--;
argv++;
errno = 0;
v = strtoul(argv[0], &cp, 0);
if (errno != 0 || *cp != '\0' || v >= 1 << 24)
errx(1, "Invalid SCR value '%s'", argv[0]);
apr.aar_pvc_traffic.forward.SCR_high_priority = (int32_t)v;
apr.aar_pvc_traffic.forward.SCR_all_traffic = (int32_t)v;
apr.aar_pvc_traffic.backward.SCR_high_priority = (int32_t)v;
apr.aar_pvc_traffic.backward.SCR_all_traffic = (int32_t)v;
argc--;
argv++;
errno = 0;
v = strtol(argv[0], &cp, 0);
if (errno != 0 || *cp != '\0' || v >= 1 << 24)
errx(1, "Invalid MBS value '%s'", argv[0]);
apr.aar_pvc_traffic.forward.MBS_high_priority = (int32_t)v;
apr.aar_pvc_traffic.forward.MBS_all_traffic = (int32_t)v;
apr.aar_pvc_traffic.backward.MBS_high_priority = (int32_t)v;
apr.aar_pvc_traffic.backward.MBS_all_traffic = (int32_t)v;
argc--;
argv++;
break;
case T_ATM_ABR:
errx(1, "ABR not yet supported");
default:
errx(1, "Unsupported traffic type '%d'", trafp->t_type);
}
} else { } else {
fprintf(stderr, "%s: Unsupported PVC owner\n", prog); /*
exit(1); * No PVC traffic type
*/
apr.aar_pvc_traffic_type = T_ATM_NULL;
} }
if (argc > 0)
errx(1, "Too many parameters");
/* /*
* Tell the kernel to add the PVC * Tell the kernel to add the PVC

View File

@ -117,6 +117,16 @@ struct encaps {
u_char e_id; /* Encapsulation code */ u_char e_id; /* Encapsulation code */
}; };
/*
* Supported traffic type
*/
struct traffics {
const char *t_name; /* Traffic name: CBR, VBR, UBR, ... */
uint8_t t_type; /* HARP code T_ATM_XXX */
int t_argc; /* Number of args */
const char *help; /* User help string */
};
/* /*
* External variables * External variables
*/ */