summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
Diffstat (limited to 'sbin')
-rw-r--r--sbin/ifconfig/af_inet.c5
-rw-r--r--sbin/ifconfig/af_inet6.c2
-rw-r--r--sbin/ifconfig/ifcarp.c182
-rw-r--r--sbin/ifconfig/ifconfig.846
-rw-r--r--sbin/ifconfig/ifconfig.c15
-rw-r--r--sbin/ifconfig/ifconfig.h3
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 *);
+
OpenPOWER on IntegriCloud