diff options
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/ifconfig/af_inet.c | 5 | ||||
-rw-r--r-- | sbin/ifconfig/af_inet6.c | 2 | ||||
-rw-r--r-- | sbin/ifconfig/ifcarp.c | 182 | ||||
-rw-r--r-- | sbin/ifconfig/ifconfig.8 | 46 | ||||
-rw-r--r-- | sbin/ifconfig/ifconfig.c | 15 | ||||
-rw-r--r-- | sbin/ifconfig/ifconfig.h | 3 |
6 files changed, 164 insertions, 89 deletions
diff --git a/sbin/ifconfig/af_inet.c b/sbin/ifconfig/af_inet.c index edb9b80..bcd17c4 100644 --- a/sbin/ifconfig/af_inet.c +++ b/sbin/ifconfig/af_inet.c @@ -84,8 +84,11 @@ in_status(int s __unused, const struct ifaddrs *ifa) if (ifa->ifa_flags & IFF_BROADCAST) { sin = (struct sockaddr_in *)ifa->ifa_broadaddr; if (sin != NULL && sin->sin_addr.s_addr != 0) - printf("broadcast %s", inet_ntoa(sin->sin_addr)); + printf("broadcast %s ", inet_ntoa(sin->sin_addr)); } + + print_vhid(ifa, " "); + putchar('\n'); } diff --git a/sbin/ifconfig/af_inet6.c b/sbin/ifconfig/af_inet6.c index e39c1c8..0731238 100644 --- a/sbin/ifconfig/af_inet6.c +++ b/sbin/ifconfig/af_inet6.c @@ -307,6 +307,8 @@ in6_status(int s __unused, const struct ifaddrs *ifa) printf("infty "); } + print_vhid(ifa, " "); + putchar('\n'); } diff --git a/sbin/ifconfig/ifcarp.c b/sbin/ifconfig/ifcarp.c index 2306717..2c58fcb 100644 --- a/sbin/ifconfig/ifcarp.c +++ b/sbin/ifconfig/ifcarp.c @@ -35,10 +35,11 @@ #include <stdlib.h> #include <unistd.h> -#include <net/ethernet.h> #include <net/if.h> +#include <net/if_var.h> +#include <netinet/in.h> +#include <netinet/in_var.h> #include <netinet/ip_carp.h> -#include <net/route.h> #include <ctype.h> #include <stdio.h> @@ -52,127 +53,153 @@ static const char *carp_states[] = { CARP_STATES }; -void carp_status(int s); -void setcarp_advbase(const char *,int, int, const struct afswtch *rafp); -void setcarp_advskew(const char *, int, int, const struct afswtch *rafp); -void setcarp_passwd(const char *, int, int, const struct afswtch *rafp); -void setcarp_vhid(const char *, int, int, const struct afswtch *rafp); +static void carp_status(int s); +static void setcarp_vhid(const char *, int, int, const struct afswtch *rafp); +static void setcarp_callback(int, void *); +static void setcarp_advbase(const char *,int, int, const struct afswtch *rafp); +static void setcarp_advskew(const char *, int, int, const struct afswtch *rafp); +static void setcarp_passwd(const char *, int, int, const struct afswtch *rafp); -void +static int carpr_vhid = -1; +static int carpr_advskew = -1; +static int carpr_advbase = -1; +static int carpr_state = -1; +static unsigned char const *carpr_key; + +static void carp_status(int s) { - const char *state; - struct carpreq carpr; + struct carpreq carpr[CARP_MAXVHID]; + int i; - memset((char *)&carpr, 0, sizeof(struct carpreq)); + bzero(carpr, sizeof(struct carpreq) * CARP_MAXVHID); + carpr[0].carpr_count = CARP_MAXVHID; ifr.ifr_data = (caddr_t)&carpr; if (ioctl(s, SIOCGVH, (caddr_t)&ifr) == -1) return; - if (carpr.carpr_vhid > 0) { - if (carpr.carpr_state > CARP_MAXSTATE) - state = "<UNKNOWN>"; + for (i = 0; i < carpr[0].carpr_count; i++) { + printf("\tcarp: %s vhid %d advbase %d advskew %d", + carp_states[carpr[i].carpr_state], carpr[i].carpr_vhid, + carpr[i].carpr_advbase, carpr[i].carpr_advskew); + if (printkeys && carpr[i].carpr_key[0] != '\0') + printf(" key \"%s\"\n", carpr[i].carpr_key); else - state = carp_states[carpr.carpr_state]; - - printf("\tcarp: %s vhid %d advbase %d advskew %d\n", - state, carpr.carpr_vhid, carpr.carpr_advbase, - carpr.carpr_advskew); + printf("\n"); } - - return; - } -void -setcarp_passwd(const char *val, int d, int s, const struct afswtch *afp) +static void +setcarp_vhid(const char *val, int d, int s, const struct afswtch *afp) { - struct carpreq carpr; - - memset((char *)&carpr, 0, sizeof(struct carpreq)); - ifr.ifr_data = (caddr_t)&carpr; - if (ioctl(s, SIOCGVH, (caddr_t)&ifr) == -1) - err(1, "SIOCGVH"); - - memset(carpr.carpr_key, 0, sizeof(carpr.carpr_key)); - /* XXX Should hash the password into the key here, perhaps? */ - strlcpy(carpr.carpr_key, val, CARP_KEY_LEN); - - if (ioctl(s, SIOCSVH, (caddr_t)&ifr) == -1) - err(1, "SIOCSVH"); + carpr_vhid = atoi(val); + + if (carpr_vhid <= 0 || carpr_vhid > CARP_MAXVHID) + errx(1, "vhid must be greater than 0 and less than %u", + CARP_MAXVHID); + + switch (afp->af_af) { +#ifdef INET + case AF_INET: + { + struct in_aliasreq *ifra; + + ifra = (struct in_aliasreq *)afp->af_addreq; + ifra->ifra_vhid = carpr_vhid; + break; + } +#endif +#ifdef INET6 + case AF_INET6: + { + struct in6_aliasreq *ifra; + + ifra = (struct in6_aliasreq *)afp->af_addreq; + ifra->ifra_vhid = carpr_vhid; + break; + } +#endif + default: + errx(1, "%s doesn't support carp(4)", afp->af_name); + } - return; + callback_register(setcarp_callback, NULL); } -void -setcarp_vhid(const char *val, int d, int s, const struct afswtch *afp) +static void +setcarp_callback(int s, void *arg __unused) { - int vhid; struct carpreq carpr; - vhid = atoi(val); - - if (vhid <= 0) - errx(1, "vhid must be greater than 0"); - - memset((char *)&carpr, 0, sizeof(struct carpreq)); + bzero(&carpr, sizeof(struct carpreq)); + carpr.carpr_vhid = carpr_vhid; + carpr.carpr_count = 1; ifr.ifr_data = (caddr_t)&carpr; - if (ioctl(s, SIOCGVH, (caddr_t)&ifr) == -1) + if (ioctl(s, SIOCGVH, (caddr_t)&ifr) == -1 && errno != ENOENT) err(1, "SIOCGVH"); - carpr.carpr_vhid = vhid; + if (carpr_key != NULL) + /* XXX Should hash the password into the key here? */ + strlcpy(carpr.carpr_key, carpr_key, CARP_KEY_LEN); + if (carpr_advskew > -1) + carpr.carpr_advskew = carpr_advskew; + if (carpr_advbase > -1) + carpr.carpr_advbase = carpr_advbase; + if (carpr_state > -1) + carpr.carpr_state = carpr_state; if (ioctl(s, SIOCSVH, (caddr_t)&ifr) == -1) err(1, "SIOCSVH"); - - return; } -void -setcarp_advskew(const char *val, int d, int s, const struct afswtch *afp) +static void +setcarp_passwd(const char *val, int d, int s, const struct afswtch *afp) { - int advskew; - struct carpreq carpr; - - advskew = atoi(val); - memset((char *)&carpr, 0, sizeof(struct carpreq)); - ifr.ifr_data = (caddr_t)&carpr; + if (carpr_vhid == -1) + errx(1, "passwd requires vhid"); - if (ioctl(s, SIOCGVH, (caddr_t)&ifr) == -1) - err(1, "SIOCGVH"); + carpr_key = val; +} - carpr.carpr_advskew = advskew; +static void +setcarp_advskew(const char *val, int d, int s, const struct afswtch *afp) +{ - if (ioctl(s, SIOCSVH, (caddr_t)&ifr) == -1) - err(1, "SIOCSVH"); + if (carpr_vhid == -1) + errx(1, "advskew requires vhid"); - return; + carpr_advskew = atoi(val); } -void +static void setcarp_advbase(const char *val, int d, int s, const struct afswtch *afp) { - int advbase; - struct carpreq carpr; - advbase = atoi(val); + if (carpr_vhid == -1) + errx(1, "advbase requires vhid"); - memset((char *)&carpr, 0, sizeof(struct carpreq)); - ifr.ifr_data = (caddr_t)&carpr; + carpr_advbase = atoi(val); +} - if (ioctl(s, SIOCGVH, (caddr_t)&ifr) == -1) - err(1, "SIOCGVH"); +static void +setcarp_state(const char *val, int d, int s, const struct afswtch *afp) +{ + int i; - carpr.carpr_advbase = advbase; + if (carpr_vhid == -1) + errx(1, "state requires vhid"); - if (ioctl(s, SIOCSVH, (caddr_t)&ifr) == -1) - err(1, "SIOCSVH"); + for (i = 0; i <= CARP_MAXSTATE; i++) + if (strcasecmp(carp_states[i], val) == 0) { + carpr_state = i; + return; + } - return; + errx(1, "unknown state"); } static struct cmd carp_cmds[] = { @@ -180,6 +207,7 @@ static struct cmd carp_cmds[] = { DEF_CMD_ARG("advskew", setcarp_advskew), DEF_CMD_ARG("pass", setcarp_passwd), DEF_CMD_ARG("vhid", setcarp_vhid), + DEF_CMD_ARG("state", setcarp_state), }; static struct afswtch af_carp = { .af_name = "af_carp", diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8 index c6b8ea3..afee726 100644 --- a/sbin/ifconfig/ifconfig.8 +++ b/sbin/ifconfig/ifconfig.8 @@ -28,7 +28,7 @@ .\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94 .\" $FreeBSD$ .\" -.Dd November 12, 2011 +.Dd December 16, 2011 .Dt IFCONFIG 8 .Os .Sh NAME @@ -2445,16 +2445,36 @@ The argument is useless and hence deprecated. .El .Pp -The following parameters are specific to +The following parameters are used to configure .Xr carp 4 -interfaces: +protocol on an interface: .Bl -tag -width indent +.It Cm vhid Ar n +Set the virtual host ID. +This is a required setting to initiate +.Xr carp 4 . +If the virtual host ID doesn't exist yet, it is created and attached to the +interface, otherwise configuration of an existing vhid is adjusted. +If the +.Cm vhid +keyword is supplied along with an +.Dq inet6 +or +.Dq inet +address, then this address is configured to be run under control of the +specified vhid. +Whenever a last address that refers to a particular vhid is removed from an +interface, the vhid is automatically removed from interface and destroyed. +Any other configuration parameters for the +.Xr carp 4 +protocol should be supplied along with the +.Cm vhid +keyword. +Acceptable values for vhid are 1 to 255. .It Cm advbase Ar seconds Specifies the base of the advertisement interval in seconds. The acceptable values are 1 to 255. The default value is 1. -.\" The default value is -.\" .Dv CARP_DFLTINTV . .It Cm advskew Ar interval Specifies the skew to add to the base advertisement interval to make one host advertise slower than another host. @@ -2464,10 +2484,8 @@ The default value is 0. .It Cm pass Ar phrase Set the authentication key to .Ar phrase . -.It Cm vhid Ar n -Set the virtual host ID. -This is a required setting. -Acceptable values are 1 to 255. +.It Cm state Ar MASTER|BACKUP +Forcibly change state of a given vhid. .El .Pp The @@ -2530,8 +2548,9 @@ The .Fl k flag causes keying information for the interface, if available, to be printed. -For example, the values of 802.11 WEP keys will be printed, if accessible to -the current user. +For example, the values of 802.11 WEP keys and +.Xr carp 4 +passphrases will be printed, if accessible to the current user. This information is not printed by default, as it may be considered sensitive. .Pp @@ -2593,6 +2612,11 @@ as a synonym for the canonical form of the option .Fl alias : .Dl # ifconfig em0 inet6 2001:db8:bdbd::123/48 delete .Pp +Configure a single CARP redundant address on igb0, and then switch it +to be master: +.Dl # ifconfig igb0 vhid 1 10.0.0.1/24 pass foobar +.Dl # ifconfig igb0 vhid 1 state master +.Pp Configure the interface .Li xl0 , to use 100baseTX, full duplex Ethernet media options: diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index af280ce..0e3c3a3 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -1078,6 +1078,21 @@ printb(const char *s, unsigned v, const char *bits) } void +print_vhid(const struct ifaddrs *ifa, const char *s) +{ + struct if_data *ifd; + + if (ifa->ifa_data == NULL) + return; + + ifd = ifa->ifa_data; + if (ifd->ifi_vhid == 0) + return; + + printf("vhid %d ", ifd->ifi_vhid); +} + +void ifmaybeload(const char *name) { #define MOD_PREFIX_LEN 3 /* "if_" */ diff --git a/sbin/ifconfig/ifconfig.h b/sbin/ifconfig/ifconfig.h index d6f5349..ea21db5 100644 --- a/sbin/ifconfig/ifconfig.h +++ b/sbin/ifconfig/ifconfig.h @@ -148,3 +148,6 @@ void clone_setdefcallback(const char *, clone_callback_func *); * operations on ifmedia can avoid cmd line ordering confusion. */ struct ifmediareq *ifmedia_getstate(int s); + +void print_vhid(const struct ifaddrs *, const char *); + |