summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2008-06-14 21:46:23 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2008-06-14 21:46:23 +0000
commit9dabaf5247648b588a451d1bd8f993af74668845 (patch)
treee9469bb3e950733a47fa5e03cb294ec255b36d12 /sbin
parent4c898c225e004ea449b31aa3f7a94e4da6f7a4dc (diff)
add carppeer; an option to specify a different multicast address or
even the unicast address of the remote carp peer. this especially helps when the multicast carp advertisements are causing problems in the network (some crappy switches don't do well with multicast), there are conflicts with VRRP, or the policy of the network does not allow multicast (most Internet eXchange points didn't allow carped OpenBGP routers because of the multicast advertisements). discussed with many ok mpf@
Diffstat (limited to 'sbin')
-rw-r--r--sbin/ifconfig/ifconfig.825
-rw-r--r--sbin/ifconfig/ifconfig.c73
2 files changed, 91 insertions, 7 deletions
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
index 23c84a820b8..7dc23e5bce0 100644
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ifconfig.8,v 1.160 2008/05/07 11:57:19 claudio Exp $
+.\" $OpenBSD: ifconfig.8,v 1.161 2008/06/14 21:46:22 reyk Exp $
.\" $NetBSD: ifconfig.8,v 1.11 1996/01/04 21:27:29 pk Exp $
.\" $FreeBSD: ifconfig.8,v 1.16 1998/02/01 07:03:29 steve Exp $
.\"
@@ -31,7 +31,7 @@
.\"
.\" @(#)ifconfig.8 8.4 (Berkeley) 6/1/94
.\"
-.Dd $Mdocdate: May 7 2008 $
+.Dd $Mdocdate: June 14 2008 $
.Dt IFCONFIG 8
.Os
.Sh NAME
@@ -454,6 +454,7 @@ and
.Op Cm pass Ar passphrase
.Op Cm state Ar state
.Op Cm vhid Ar host-id
+.Op Oo Fl Oc Cm carppeer Ar peer_address
.Ek
.Pp
The options are as follows:
@@ -517,6 +518,26 @@ If the driver is a
pseudo-device, set the virtual host ID to
.Ar n .
Acceptable values are 1 to 255.
+.It Cm carppeer Ar peer_address
+If the driver is a
+.Xr carp 4
+pseudo-device, send the carp advertisements to a specified
+point-to-point peer or multicast group instead of sending the messages
+to the default carp multicast group.
+The
+.Ar peer_address
+is the IP address of the other host taking part in the carp cluster.
+With this option,
+.Xr carp 4
+traffic can be protected using
+.Xr ipsec 4
+and it may be desired in networks that do not allow or have problems
+with IPv4 multicast traffic.
+.It Fl carppeer
+If the driver is a
+.Xr carp 4
+pseudo-device, send the advertisements to the default carp multicast
+group.
.El
.Pp
Taken together, the
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index a3b8995236b..35ff1961498 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ifconfig.c,v 1.198 2008/06/13 06:58:20 reyk Exp $ */
+/* $OpenBSD: ifconfig.c,v 1.199 2008/06/14 21:46:22 reyk Exp $ */
/* $NetBSD: ifconfig.c,v 1.40 1997/10/01 02:19:43 enami Exp $ */
/*
@@ -202,6 +202,8 @@ void getifgroups(void);
void carp_status(void);
void setcarp_advbase(const char *,int);
void setcarp_advskew(const char *, int);
+void setcarppeer(const char *, int);
+void unsetcarppeer(const char *, int);
void setcarp_passwd(const char *, int);
void setcarp_vhid(const char *, int);
void setcarp_state(const char *, int);
@@ -333,6 +335,8 @@ const struct cmd {
{ "-vlandev", 1, 0, unsetvlandev },
{ "advbase", NEXTARG, 0, setcarp_advbase },
{ "advskew", NEXTARG, 0, setcarp_advskew },
+ { "carppeer", NEXTARG, 0, setcarppeer },
+ { "-carppeer", 1, 0, unsetcarppeer },
{ "pass", NEXTARG, 0, setcarp_passwd },
{ "vhid", NEXTARG, 0, setcarp_vhid },
{ "state", NEXTARG, 0, setcarp_state },
@@ -3196,6 +3200,7 @@ carp_status(void)
{
const char *state, *balmode;
struct carpreq carpr;
+ char peer[32];
int i;
memset((char *)&carpr, 0, sizeof(struct carpreq));
@@ -3212,6 +3217,12 @@ carp_status(void)
else
balmode = carp_bal_modes[carpr.carpr_balancing];
+ if (carpr.carpr_peer.s_addr != htonl(INADDR_CARP_GROUP))
+ snprintf(peer, sizeof(peer),
+ " carppeer %s", inet_ntoa(carpr.carpr_peer));
+ else
+ peer[0] = '\0';
+
for (i = 0; carpr.carpr_vhids[i]; i++) {
if (carpr.carpr_states[i] > CARP_MAXSTATE)
state = "<UNKNOWN>";
@@ -3219,17 +3230,18 @@ carp_status(void)
state = carp_states[carpr.carpr_states[i]];
if (carpr.carpr_vhids[1] == 0) {
printf("\tcarp: %s carpdev %s vhid %u advbase %d "
- "advskew %u\n", state,
+ "advskew %u%s\n", state,
carpr.carpr_carpdev[0] != '\0' ?
carpr.carpr_carpdev : "none", carpr.carpr_vhids[0],
- carpr.carpr_advbase, carpr.carpr_advskews[0]);
+ carpr.carpr_advbase, carpr.carpr_advskews[0],
+ peer);
} else {
if (i == 0) {
printf("\tcarp: carpdev %s advbase %d"
- " balancing %s\n",
+ " balancing %s%s\n",
carpr.carpr_carpdev[0] != '\0' ?
carpr.carpr_carpdev : "none",
- carpr.carpr_advbase, balmode);
+ carpr.carpr_advbase, balmode, peer);
}
printf("\t\tstate %s vhid %u advskew %u\n", state,
carpr.carpr_vhids[i], carpr.carpr_advskews[i]);
@@ -3331,6 +3343,57 @@ setcarp_advbase(const char *val, int d)
/* ARGSUSED */
void
+setcarppeer(const char *val, int d)
+{
+ struct carpreq carpr;
+ struct addrinfo hints, *peerres;
+ int ecode;
+
+ memset((char *)&carpr, 0, sizeof(struct carpreq));
+ ifr.ifr_data = (caddr_t)&carpr;
+
+ if (ioctl(s, SIOCGVH, (caddr_t)&ifr) == -1)
+ err(1, "SIOCGVH");
+
+ bzero(&hints, sizeof(hints));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_DGRAM;
+
+ if ((ecode = getaddrinfo(val, NULL, &hints, &peerres)) != 0)
+ errx(1, "error in parsing address string: %s",
+ gai_strerror(ecode));
+
+ if (peerres->ai_addr->sa_family != AF_INET)
+ errx(1, "only IPv4 addresses supported for the carppeer");
+
+ carpr.carpr_peer.s_addr = ((struct sockaddr_in *)
+ peerres->ai_addr)->sin_addr.s_addr;
+
+ if (ioctl(s, SIOCSVH, (caddr_t)&ifr) == -1)
+ err(1, "SIOCSVH");
+
+ freeaddrinfo(peerres);
+}
+
+void
+unsetcarppeer(const char *val, int d)
+{
+ struct carpreq carpr;
+
+ bzero((char *)&carpr, sizeof(struct carpreq));
+ ifr.ifr_data = (caddr_t)&carpr;
+
+ if (ioctl(s, SIOCGVH, (caddr_t)&ifr) == -1)
+ err(1, "SIOCGVH");
+
+ bzero((char *)&carpr.carpr_peer, sizeof(carpr.carpr_peer));
+
+ if (ioctl(s, SIOCSVH, (caddr_t)&ifr) == -1)
+ err(1, "SIOCSVH");
+}
+
+/* ARGSUSED */
+void
setcarp_state(const char *val, int d)
{
struct carpreq carpr;