Skip to content

Commit

Permalink
add mpw commands (mpwlabel, neghbor, controlword, encap) also rename …
Browse files Browse the repository at this point in the history
…label to mpelabel
  • Loading branch information
yellowman committed May 31, 2016
1 parent 88ff66b commit 8226078
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 6 deletions.
6 changes: 5 additions & 1 deletion commands.c
Expand Up @@ -496,7 +496,7 @@ struct intlist Intlist[] = {
{ "metric", "Set routing metric", CMPL0 0, 0, intmetric },
{ "link", "Set link level options", CMPL0 0, 0, intlink },
{ "arp", "Set Address Resolution Protocol", CMPL0 0, 0, intflags },
{ "label", "Set MPLS Label", CMPL0 0, 0, intlabel },
{ "mpelabel", "Set MPLS MPE Label", CMPL0 0, 0, intmpelabel },
{ "lladdr", "Set Link Level (MAC) Address", CMPL0 0, 0, intlladdr },
{ "nwid", "802.11 network ID", CMPL0 0, 0, intnwid },
{ "nwkey", "802.11 network key", CMPL0 0, 0, intnwkey },
Expand Down Expand Up @@ -524,6 +524,10 @@ struct intlist Intlist[] = {
{ "patch", "Pair interface", CMPL(i) 0, 0, intpatch },
#endif
{ "keepalive", "GRE tunnel keepalive", CMPL0 0, 0, intkeepalive },
{ "mpwlabel", "MPLS pseudowire local-remote labels", CMPL0 0, 0, intmpw },
{ "neighbor", "MPLS pseudowire neighbor IP", CMPL0 0, 0, intmpw },
{ "controlword","MPLS pseudowire controlword", CMPL0 0, 0, intmpw },
{ "encap", "MPLS pseudowire encapsulation", CMPL0 0, 0, intmpw },
{ "syncdev", "PFsync control message interface", CMPL(i) 0, 0, intsyncdev },
{ "syncpeer", "PFsync peer address", CMPL0 0, 0, intsyncpeer },
{ "maxupd", "PFsync max updates, defer first packet", CMPL0 0, 0, intmaxupd },
Expand Down
46 changes: 43 additions & 3 deletions conf.c
Expand Up @@ -70,6 +70,7 @@ void conf_rtables_rtable(FILE *, int);
void conf_rdomain(FILE *, int, char *);
void conf_ifmetrics(FILE *, int, struct if_data, char *);
void conf_pflow(FILE *, int, char *);
void conf_mpw(FILE *, int, char *);
void conf_ctl(FILE *, char *, char *, int);
void conf_intrtlabel(FILE *, int, char *);
void conf_intgroup(FILE *, int, char *);
Expand Down Expand Up @@ -554,6 +555,7 @@ void conf_interfaces(FILE *output, char *only)
conf_pfsync(output, ifs, ifnp->if_name);
conf_trunk(output, ifs, ifnp->if_name);
conf_pflow(output, ifs, ifnp->if_name);
conf_mpw(output, ifs, ifnp->if_name);
conf_ifxflags(output, ifs, ifnp->if_name);
if (timeslot_status(ifs, ifnp->if_name, tmp,
sizeof(tmp)) == 1)
Expand Down Expand Up @@ -756,7 +758,7 @@ void conf_ifxflags(FILE *output, int ifs, char *ifname)
/* set label for mpe */
if (ioctl(ifs, SIOCGETLABEL , (caddr_t)&ifr) != -1)
if (shim.shim_label > 0)
fprintf(output, " label %d\n", shim.shim_label);
fprintf(output, " mpelabel %d\n", shim.shim_label);
}

void conf_rdomain(FILE *output, int ifs, char *ifname)
Expand All @@ -780,7 +782,6 @@ int get_rdomain(int ifs, char *ifname)
return -1;
}


void conf_keepalive(FILE *output, int ifs, char *ifname)
{
struct ifkalivereq ikar;
Expand All @@ -793,7 +794,46 @@ void conf_keepalive(FILE *output, int ifs, char *ifname)
fprintf(output, " keepalive %d %d\n",
ikar.ikar_timeo, ikar.ikar_cnt);
}


void conf_mpw(FILE *output, int ifs, char *ifname)
{
struct sockaddr_in *sin;
struct ifmpwreq imr;
struct ifreq ifr;

bzero(&imr, sizeof(imr));
bzero(&ifr, sizeof(ifr));

strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
ifr.ifr_data = (caddr_t) &imr;
if (ioctl(ifs, SIOCGETMPWCFG, (caddr_t) &ifr) == -1)
return;

switch (imr.imr_type) {
case IMR_TYPE_NONE:
break;
case IMR_TYPE_ETHERNET:
fprintf(output, " encap ethernet\n");
break;
case IMR_TYPE_ETHERNET_TAGGED:
fprintf(output, " encap ethernet-tagged\n");
break;
default:
printf("%% conf_mpw: imr.imr_type %d unknown\n", imr.imr_type);
break;
}

if (imr.imr_flags & IMR_FLAG_CONTROLWORD)
fprintf(output, " controlword\n");

if (imr.imr_lshim.shim_label != 0 || imr.imr_rshim.shim_label != 0)
fprintf(output, " mpwlabel %u %u\n", imr.imr_lshim.shim_label,
imr.imr_rshim.shim_label);

sin = (struct sockaddr_in *) &imr.imr_nexthop;
if (!(sin->sin_addr.s_addr == 0))
fprintf(output, " neighbor %s\n", inet_ntoa(sin->sin_addr));
}

void conf_ifmetrics(FILE *output, int ifs, struct if_data if_data,
char *ifname)
Expand Down
3 changes: 2 additions & 1 deletion externs.h
Expand Up @@ -385,7 +385,7 @@ u_int32_t in4_brdaddr(u_int32_t, u_int32_t);
int intip(char *, int, int, char **);
int intmtu(char *, int, int, char **);
int intkeepalive(char *, int, int, char **);
int intlabel(char *, int, int, char **);
int intmpelabel(char *, int, int, char **);
int intrdomain(char *, int, int, char **);
int intdhcrelay(char *, int, int, char **);
int intmetric(char *, int, int, char **);
Expand All @@ -404,6 +404,7 @@ int intgroup(char *, int, int, char **);
int intrtlabel(char *, int, int, char **);
int intparent(char *, int, int, char **);
int intpatch(char *, int, int, char **);
int intmpw(char *, int, int, char **);
int addaf(char *, int, int);
int removeaf(char *, int, int);
char *get_hwdaddr(char *);
Expand Down
172 changes: 171 additions & 1 deletion if.c
Expand Up @@ -54,6 +54,8 @@ void ipv6ll_db_store(struct sockaddr_in6 *, struct sockaddr_in6 *, int, char *);
void printifhwfeatures(int, char *);
void show_vnet_parent(int, char *);

static struct ifmpwreq imrsave;

static const struct {
char *name;
u_int8_t type;
Expand Down Expand Up @@ -1125,7 +1127,7 @@ intkeepalive(char *ifname, int ifs, int argc, char **argv)
}

int
intlabel(char *ifname, int ifs, int argc, char **argv)
intmpelabel(char *ifname, int ifs, int argc, char **argv)
{
struct ifreq ifr;
struct shim_hdr shim;
Expand Down Expand Up @@ -1173,6 +1175,174 @@ intlabel(char *ifname, int ifs, int argc, char **argv)
return(0);
}

#define MPWLABEL 1
#define MPWNEIGHBOR 2
#define MPWCONTROLWORD 3
#define MPWENCAP 4

static struct mpwc {
char *name;
char *descr;
char *descr2;
int type;
int args;
} mpwcs[] = {
{ "mpwlabel", "local label", "remote label", MPWLABEL, 2 },
{ "neighbor", "neighbor IP", "", MPWNEIGHBOR, 1 },
{ "controlword", "controlword", "", MPWCONTROLWORD, 0 },
{ "encap", "encap-type", "", MPWENCAP, 1 },
{ 0, 0, 0, 0, 0 }
};

/* from ifconfig.c */
int
intmpw(char *ifname, int ifs, int argc, char **argv)
{
int set;
struct sockaddr_in *sin, *sinn;
struct ifmpwreq imr;
struct ifreq ifr;
struct mpwc *x;
const char *errstr;

bzero(&imr, sizeof(imr));
bzero(&ifr, sizeof(ifr));

strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);

if (NO_ARG(argv[0])) {
set = 0;
argc--;
argv++;
} else
set = 1;

x=(struct mpwc *) genget(argv[0], (char **)mpwcs, sizeof(struct mpwc));
if (x == 0) {
printf("%% Internal error - Invalid argument %s\n", argv[0]);
return 0;
} else if (Ambiguous(x)) {
printf("%% Internal error - Ambiguous argument %s\n", argv[0]);
return 0;
}

argc--;
argv++;

if (x->args == 2 && ((!set && argc > 2) || (set && argc != 2))) {
printf("%% %s <%s> <%s>\n", x->name, x->descr, x->descr2);
printf("%% no %s [%s] [%s]\n", x->name, x->descr, x->descr2);
return(0);
}
if (x->args == 1 && ((!set && argc > 1) || (set && argc != 1))) {
printf("%% %s <%s>\n", x->name, x->descr);
printf("%% no %s [%s]\n", x->name, x->descr);
return(0);
}
if (!x->args && argc) {
printf("%% %s\n", x->name);
printf("%% no %s\n", x->name);
return(0);
}

switch(x->type) {
case MPWLABEL:
if (!set) {
imrsave.imr_lshim.shim_label = 0;
imrsave.imr_rshim.shim_label = 0;
break;
}
imrsave.imr_lshim.shim_label = strtonum(argv[0],
(MPLS_LABEL_RESERVED_MAX + 1), MPLS_LABEL_MAX, &errstr);
if (errstr != NULL) {
printf("%% invalid local label: %s\n", errstr);
return 0;
}

imrsave.imr_rshim.shim_label = strtonum(argv[1],
(MPLS_LABEL_RESERVED_MAX + 1), MPLS_LABEL_MAX, &errstr);
if (errstr != NULL) {
printf("%% invalid remote label: %s\n", errstr);
return 0;
}
break;
case MPWNEIGHBOR:
sin = (struct sockaddr_in *) &imrsave.imr_nexthop;
if (set && inet_aton(argv[0], &sin->sin_addr) == 0) {
printf("%% invalid neighbor addresses\n");
return 0;
}
if (!set) {
sin->sin_addr.s_addr = 0;
}
sin->sin_family = AF_INET;
break;
case MPWCONTROLWORD:
if (set)
imrsave.imr_flags |= IMR_FLAG_CONTROLWORD;
else
imrsave.imr_flags &= ~IMR_FLAG_CONTROLWORD;
break;
case MPWENCAP:
if (!set) {
imrsave.imr_type = 0;
break;
}
if (isprefix(argv[0], "ethernet")) {
imrsave.imr_type = IMR_TYPE_ETHERNET;
} else if (isprefix(argv[0], "ethernet-tagged")) {
imrsave.imr_type = IMR_TYPE_ETHERNET_TAGGED;
} else {
printf("%% invalid mpw encapsulation type\n");
return 0;
}
break;
}

ifr.ifr_data = (caddr_t) &imr;
if (ioctl(ifs, SIOCGETMPWCFG, (caddr_t) &ifr) == -1) {
printf("%% SIOCGETMPWCFG: %s\n", strerror(errno));
return 0;
}

if (imrsave.imr_type == 0) {
if (imr.imr_type == 0)
imrsave.imr_type = IMR_TYPE_ETHERNET;
imrsave.imr_type = imr.imr_type;
}
if (x->type != MPWCONTROLWORD)
imrsave.imr_flags |= imr.imr_flags;

if (imrsave.imr_lshim.shim_label == 0 ||
imrsave.imr_rshim.shim_label == 0) {
if (imr.imr_lshim.shim_label == 0 ||
imr.imr_rshim.shim_label == 0) {
printf("%% mpw local / remote label not specified\n");
/*return 0;*/
}
imrsave.imr_lshim.shim_label = imr.imr_lshim.shim_label;
imrsave.imr_rshim.shim_label = imr.imr_rshim.shim_label;
}

sin = (struct sockaddr_in *) &imrsave.imr_nexthop;
sinn = (struct sockaddr_in *) &imr.imr_nexthop;
if (sin->sin_addr.s_addr == 0) {
if (sinn->sin_addr.s_addr == 0) {
printf("%% mpw neighbor address not specified\n");
/*return 0;*/
}

sin->sin_family = sinn->sin_family;
sin->sin_addr.s_addr = sinn->sin_addr.s_addr;
}

ifr.ifr_data = (caddr_t) &imrsave;
if (ioctl(ifs, SIOCSETMPWCFG, (caddr_t) &ifr) == -1)
printf("%% intmpw: SIOCSETMPWCFG: %s\n", strerror(errno));

return 0;
}

int
intdhcrelay(char *ifname, int ifs, int argc, char **argv)
{
Expand Down

0 comments on commit 8226078

Please sign in to comment.