Adds support for wire configuration and status printing.
diff --git sbin/ifconfig/ifconfig.c sbin/ifconfig/ifconfig.c
index 133ff55..3a363ff 100644
--- sbin/ifconfig/ifconfig.c
+++ sbin/ifconfig/ifconfig.c
@@ -122,6 +122,10 @@ struct sockaddr_in netmask;
#ifndef SMALL
struct ifaliasreq addreq;
+
+int wconfig = 0;
+int wcwconfig = 0;
+struct ifwirereq iwrsave;
#endif /* SMALL */
char name[IFNAMSIZ];
@@ -191,10 +195,16 @@ void setmediainst(const char *, int);
void settimeslot(const char *, int);
void timeslot_status(void);
void setmpelabel(const char *, int);
+void process_wire_commands(void);
+void setwireencap(const char *, int);
+void setwirelabel(const char *, const char *);
+void setwireneighbor(const char *, int);
+void setwirecontrolword(const char *, int);
void setvlantag(const char *, int);
void setvlandev(const char *, int);
void unsetvlandev(const char *, int);
void mpe_status(void);
+void wire_status(void);
void vlan_status(void);
void setinstance(const char *, int);
int main(int, char *[]);
@@ -362,6 +372,11 @@ const struct cmd {
{ "mpls", IFXF_MPLS, 0, setifxflags },
{ "-mpls", -IFXF_MPLS, 0, setifxflags },
{ "mplslabel", NEXTARG, 0, setmpelabel },
+ { "wirelabel", NEXTARG2, 0, NULL, setwirelabel },
+ { "neighbor", NEXTARG, 0, setwireneighbor },
+ { "controlword", 1, 0, setwirecontrolword },
+ { "-controlword", 0, 0, setwirecontrolword },
+ { "encap", NEXTARG, 0, setwireencap },
{ "advbase", NEXTARG, 0, setcarp_advbase },
{ "advskew", NEXTARG, 0, setcarp_advskew },
{ "carppeer", NEXTARG, 0, setcarppeer },
@@ -754,6 +769,9 @@ nextarg:
/* Process any media commands that may have been issued. */
process_media_commands();
+ /* Process wire commands */
+ process_wire_commands();
+
if (af == AF_INET6 && explicit_prefix == 0) {
/*
* Aggregatable address architecture defines all prefixes
@@ -2919,6 +2937,7 @@ status(int link, struct sockaddr_dl *sdl, int ls)
sppp_status();
trunk_status();
mpe_status();
+ wire_status();
pflow_status();
#endif
getifgroups();
@@ -3357,6 +3376,56 @@ mpe_status(void)
printf("\tmpls label: %d\n", shim.shim_label);
}
+void
+wire_status(void)
+{
+ struct sockaddr_in *sin;
+ struct ifwirereq iwr;
+
+ bzero(&iwr, sizeof(iwr));
+ ifr.ifr_data = (caddr_t) &iwr;
+ if (ioctl(s, SIOCGETWIRECFG, (caddr_t) &ifr) == -1)
+ return;
+
+ printf("\tencapsulation-type ");
+ switch (iwr.iwr_type) {
+ case IWR_TYPE_NONE:
+ printf("none");
+ break;
+ case IWR_TYPE_ETHERNET:
+ printf("ethernet");
+ break;
+ case IWR_TYPE_ETHERNET_TAGGED:
+ printf("ethernet-vlan");
+ break;
+ default:
+ printf("unknown");
+ break;
+ }
+
+ if (iwr.iwr_flags & IWR_FLAG_CONTROLWORD)
+ printf(", control-word");
+
+ printf("\n");
+
+ printf("\tmpls label: ");
+ if (iwr.iwr_lshim.shim_label == 0)
+ printf("local none ");
+ else
+ printf("local %u ", iwr.iwr_lshim.shim_label);
+
+ if (iwr.iwr_rshim.shim_label == 0)
+ printf("remote none\n");
+ else
+ printf("remote %u\n", iwr.iwr_rshim.shim_label);
+
+ sin = (struct sockaddr_in *) &iwr.iwr_nexthop;
+ if (sin->sin_addr.s_addr == 0)
+ printf("\tneighbor: none\n");
+ else
+ printf("\tneighbor: %s\n", inet_ntoa(sin->sin_addr));
+}
+
/* ARGSUSED */
void
setmpelabel(const char *val, int d)
@@ -3373,6 +3442,112 @@ setmpelabel(const char *val, int d)
if (ioctl(s, SIOCSETLABEL, (caddr_t)&ifr) == -1)
warn("SIOCSETLABEL");
}
+
+void
+process_wire_commands(void)
+{
+ struct sockaddr_in *sin, *sinn;
+ struct ifwirereq iwr;
+
+ if (wconfig == 0)
+ return;
+
+ bzero(&iwr, sizeof(iwr));
+ ifr.ifr_data = (caddr_t) &iwr;
+ if (ioctl(s, SIOCGETWIRECFG, (caddr_t) &ifr) == -1)
+ err(1, "SIOCGETWIRECFG");
+
+ if (iwrsave.iwr_type == 0) {
+ if (iwr.iwr_type == 0)
+ iwrsave.iwr_type = IWR_TYPE_ETHERNET;
+
+ iwrsave.iwr_type = iwr.iwr_type;
+ }
+ if (wcwconfig == 0)
+ iwrsave.iwr_flags |= iwr.iwr_flags;
+
+ if (iwrsave.iwr_lshim.shim_label == 0 ||
+ iwrsave.iwr_rshim.shim_label == 0) {
+ if (iwr.iwr_lshim.shim_label == 0 ||
+ iwr.iwr_rshim.shim_label == 0)
+ errx(1, "wire local / remote label not specified");
+
+ iwrsave.iwr_lshim.shim_label = iwr.iwr_lshim.shim_label;
+ iwrsave.iwr_rshim.shim_label = iwr.iwr_rshim.shim_label;
+ }
+
+ sin = (struct sockaddr_in *) &iwrsave.iwr_nexthop;
+ sinn = (struct sockaddr_in *) &iwr.iwr_nexthop;
+ if (sin->sin_addr.s_addr == 0) {
+ if (sinn->sin_addr.s_addr == 0)
+ errx(1, "wire neighbor address not specified");
+
+ sin->sin_family = sinn->sin_family;
+ sin->sin_addr.s_addr = sinn->sin_addr.s_addr;
+ }
+
+ ifr.ifr_data = (caddr_t) &iwrsave;
+ if (ioctl(s, SIOCSETWIRECFG, (caddr_t) &ifr) == -1)
+ err(1, "SIOCSETWIRECFG");
+}
+
+void
+setwireencap(const char *value, int d)
+{
+ wconfig = 1;
+
+ if (strcmp(value, "ethernet") == 0)
+ iwrsave.iwr_type = IWR_TYPE_ETHERNET;
+ else if (strcmp(value, "ethernet-vlan") == 0)
+ iwrsave.iwr_type = IWR_TYPE_ETHERNET_TAGGED;
+ else
+ errx(1, "invalid wire encapsulation type");
+}
+
+void
+setwirelabel(const char *local, const char *remote)
+{
+ struct shim_hdr shim;
+ const char *errstr;
+
+ wconfig = 1;
+
+ iwrsave.iwr_lshim.shim_label = strtonum(local,
+ (MPLS_LABEL_RESERVED_MAX + 1), MPLS_LABEL_MAX, &errstr);
+ if (errstr != NULL)
+ errx(1, "invalid local label: %s", errstr);
+
+ iwrsave.iwr_rshim.shim_label = strtonum(remote,
+ (MPLS_LABEL_RESERVED_MAX + 1), MPLS_LABEL_MAX, &errstr);
+ if (errstr != NULL)
+ errx(1, "invalid remote label: %s", errstr);
+}
+
+void
+setwireneighbor(const char *value, int d)
+{
+ struct sockaddr_in *sin;
+
+ wconfig = 1;
+
+ sin = (struct sockaddr_in *) &iwrsave.iwr_nexthop;
+ if (inet_aton(value, &sin->sin_addr) == 0)
+ errx(1, "invalid neighbor addresses");
+
+ sin->sin_family = AF_INET;
+}
+
+void
+setwirecontrolword(const char *value, int d)
+{
+ wconfig = 1;
+ wcwconfig = 1;
+
+ if (d == 1)
+ iwrsave.iwr_flags |= IWR_FLAG_CONTROLWORD;
+ else
+ iwrsave.iwr_flags &= ~IWR_FLAG_CONTROLWORD;
+}
#endif /* SMALL */
static int __tag = 0;