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:
parent
a3f9f68a5c
commit
0f7d88f255
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user