Module Name:    src
Committed By:   kardel
Date:           Thu Jan 16 12:56:40 UTC 2020

Modified Files:
        src/share/man/man4: carp.4
        src/sys/netinet: ip_carp.c ip_carp.h

Log Message:
Provide SIOCGIFMEDIA ioctl to deliver link status.
Add link0 (IFF_LINK0) flag to map INIT state to LINK_STATE_DOWN
instead of LINK_STATE_UNKNOWN. This allows routing software to
suppress routes to the interface of the carp interface when in
init state (e. g. link down in the parent interface).


To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/share/man/man4/carp.4
cvs rdiff -u -r1.104 -r1.105 src/sys/netinet/ip_carp.c
cvs rdiff -u -r1.10 -r1.11 src/sys/netinet/ip_carp.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/share/man/man4/carp.4
diff -u src/share/man/man4/carp.4:1.6 src/share/man/man4/carp.4:1.7
--- src/share/man/man4/carp.4:1.6	Wed Apr 10 00:18:39 2019
+++ src/share/man/man4/carp.4	Thu Jan 16 12:56:39 2020
@@ -1,4 +1,4 @@
-.\"	$NetBSD: carp.4,v 1.6 2019/04/10 00:18:39 sevan Exp $
+.\"	$NetBSD: carp.4,v 1.7 2020/01/16 12:56:39 kardel Exp $
 .\"	$OpenBSD: carp.4,v 1.19 2005/08/09 09:52:12 jmc Exp $
 .\"
 .\" Copyright (c) 2003, Ryan McBride.  All rights reserved.
@@ -24,7 +24,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd April 10, 2019
+.Dd January 16, 2020
 .Dt CARP 4
 .Os
 .Sh NAME
@@ -76,6 +76,20 @@ or through the
 .Dv SIOCSVH
 ioctl.
 .Pp
+Setting the
+.Cm link0
+parameter will cause the carp interface to report
+.Dv LINK_STATE_DOWN
+in non
+.Dv MASTER/BACKUP
+mode instead of
+.Dv LINK_STATE_UNKNOWN
+as link status.
+This prevents routing software to announce routes for the carp
+interface when in
+.Dv INIT
+mode.
+.Pp
 Additionally, there are a number of global parameters which can be set using
 .Xr sysctl 8 :
 .Bl -tag -width xxxxxxxxxxxxxxxxxxxxxxxxxx

Index: src/sys/netinet/ip_carp.c
diff -u src/sys/netinet/ip_carp.c:1.104 src/sys/netinet/ip_carp.c:1.105
--- src/sys/netinet/ip_carp.c:1.104	Sun Nov 10 21:16:38 2019
+++ src/sys/netinet/ip_carp.c	Thu Jan 16 12:56:40 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_carp.c,v 1.104 2019/11/10 21:16:38 chs Exp $	*/
+/*	$NetBSD: ip_carp.c,v 1.105 2020/01/16 12:56:40 kardel Exp $	*/
 /*	$OpenBSD: ip_carp.c,v 1.113 2005/11/04 08:11:54 mcbride Exp $	*/
 
 /*
@@ -33,7 +33,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_carp.c,v 1.104 2019/11/10 21:16:38 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_carp.c,v 1.105 2020/01/16 12:56:40 kardel Exp $");
 
 /*
  * TODO:
@@ -67,6 +67,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip_carp.c,v 
 #include <net/pfil.h>
 #include <net/if_types.h>
 #include <net/if_ether.h>
+#include <net/if_media.h>
 #include <net/route.h>
 #include <net/netisr.h>
 #include <net/net_stats.h>
@@ -122,6 +123,7 @@ struct carp_softc {
 #define	sc_carpdev	sc_ac.ec_if.if_carpdev
 	int ah_cookie;
 	int lh_cookie;
+	struct ifmedia  sc_im;	/* ifmedia for link status */
 	struct ip_moptions sc_imo;
 #ifdef INET6
 	struct ip6_moptions sc_im6o;
@@ -233,6 +235,9 @@ static int	carp_clone_destroy(struct ifn
 static int	carp_ether_addmulti(struct carp_softc *, struct ifreq *);
 static int	carp_ether_delmulti(struct carp_softc *, struct ifreq *);
 static void	carp_ether_purgemulti(struct carp_softc *);
+static int      carp_mediachange(struct ifnet *ifp);
+static void	carp_mediastatus(struct ifnet *ifp, struct ifmediareq *imr);
+static void	carp_update_link_state(struct carp_softc *sc);
 
 static void	sysctl_net_inet_carp_setup(struct sysctllog **);
 
@@ -893,6 +898,8 @@ carp_clone_create(struct if_clone *ifc, 
 
 		return rv;
 	}
+	ifmedia_init(&sc->sc_im, 0, carp_mediachange, carp_mediastatus);
+	sc->sc_im.ifm_media = IFM_CARP;
 	ether_ifattach(ifp, NULL);
 	carp_set_enaddr(sc);
 	/* Overwrite ethernet defaults */
@@ -908,6 +915,7 @@ carp_clone_destroy(struct ifnet *ifp)
 {
 	struct carp_softc *sc = ifp->if_softc;
 
+	ifmedia_delete_instance(&sc->sc_im, IFM_INST_ANY);
 	carpdetach(ifp->if_softc);
 	ether_ifdetach(ifp);
 	if_detach(ifp);
@@ -2069,6 +2077,7 @@ carp_ioctl(struct ifnet *ifp, u_long cmd
 			sc->sc_if.if_flags |= IFF_UP;
 			carp_setrun(sc, 0);
 		}
+		carp_update_link_state(sc);
 		break;
 
 	case SIOCSVH:
@@ -2174,6 +2183,10 @@ carp_ioctl(struct ifnet *ifp, u_long cmd
 			error = 0;
 		break;
 
+        case SIOCGIFMEDIA:
+		error = ifmedia_ioctl(ifp, ifr, &sc->sc_im, cmd);
+		break;
+
 	default:
 		error = ether_ioctl(ifp, cmd, data);
 	}
@@ -2209,11 +2222,32 @@ carp_output(struct ifnet *ifp, struct mb
 	}
 }
 
+static int
+carp_mediachange(struct ifnet *ifp)
+{
+        return (0);
+}
+
+static void
+carp_mediastatus(struct ifnet *ifp, struct ifmediareq *imr)
+{
+        switch (ifp->if_link_state) {
+        case LINK_STATE_UP:
+                imr->ifm_status = IFM_AVALID | IFM_ACTIVE;
+                break;
+        case LINK_STATE_DOWN:
+                imr->ifm_status = IFM_AVALID;
+                break;
+        default:
+                imr->ifm_status = 0;
+                break;
+        }
+}
+
 static void
 carp_set_state(struct carp_softc *sc, int state)
 {
 	static const char *carp_states[] = { CARP_STATES };
-	int link_state;
 
 	if (sc->sc_state == state)
 		return;
@@ -2221,7 +2255,15 @@ carp_set_state(struct carp_softc *sc, in
 	CARP_LOG(sc, ("state transition from: %s -> to: %s", carp_states[sc->sc_state], carp_states[state]));
 
 	sc->sc_state = state;
-	switch (state) {
+	carp_update_link_state(sc);
+}
+
+static void
+carp_update_link_state(struct carp_softc *sc)
+{
+	int link_state;
+
+	switch (sc->sc_state) {
 	case BACKUP:
 		link_state = LINK_STATE_DOWN;
 		break;
@@ -2229,7 +2271,8 @@ carp_set_state(struct carp_softc *sc, in
 		link_state = LINK_STATE_UP;
 		break;
 	default:
-		link_state = LINK_STATE_UNKNOWN;
+		link_state = ((sc->sc_if.if_flags & IFF_ONLY_MASTER_UP) != 0)
+			     ? LINK_STATE_DOWN : LINK_STATE_UNKNOWN;
 		break;
 	}
 	/*

Index: src/sys/netinet/ip_carp.h
diff -u src/sys/netinet/ip_carp.h:1.10 src/sys/netinet/ip_carp.h:1.11
--- src/sys/netinet/ip_carp.h:1.10	Fri Sep 14 05:09:51 2018
+++ src/sys/netinet/ip_carp.h	Thu Jan 16 12:56:40 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_carp.h,v 1.10 2018/09/14 05:09:51 maxv Exp $	*/
+/*	$NetBSD: ip_carp.h,v 1.11 2020/01/16 12:56:40 kardel Exp $	*/
 /*	$OpenBSD: ip_carp.h,v 1.18 2005/04/20 23:00:41 mpf Exp $	*/
 
 /*
@@ -133,6 +133,9 @@ struct carpreq {
 	unsigned char	carpr_key[CARP_KEY_LEN];
 };
 
+/* enable link status up only for MASTER state */
+#define IFF_ONLY_MASTER_UP       IFF_LINK0
+
 /*
  * Names for CARP sysctl objects
  */

Reply via email to