Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/netinet Provide SIOCGIFMEDIA ioctl to deliver link status.



details:   https://anonhg.NetBSD.org/src/rev/f56fd4b11cf7
branches:  trunk
changeset: 968425:f56fd4b11cf7
user:      kardel <kardel%NetBSD.org@localhost>
date:      Thu Jan 16 12:56:39 2020 +0000

description:
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).

diffstat:

 share/man/man4/carp.4 |  18 +++++++++++++++-
 sys/netinet/ip_carp.c |  53 ++++++++++++++++++++++++++++++++++++++++++++++----
 sys/netinet/ip_carp.h |   5 +++-
 3 files changed, 68 insertions(+), 8 deletions(-)

diffs (199 lines):

diff -r 97f7b39fcec1 -r f56fd4b11cf7 share/man/man4/carp.4
--- a/share/man/man4/carp.4     Thu Jan 16 12:54:16 2020 +0000
+++ b/share/man/man4/carp.4     Thu Jan 16 12:56:39 2020 +0000
@@ -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 @@
 .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
diff -r 97f7b39fcec1 -r f56fd4b11cf7 sys/netinet/ip_carp.c
--- a/sys/netinet/ip_carp.c     Thu Jan 16 12:54:16 2020 +0000
+++ b/sys/netinet/ip_carp.c     Thu Jan 16 12:56:39 2020 +0000
@@ -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 @@
 #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 @@
 #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_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 @@
 
                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 @@
 {
        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 @@
                        sc->sc_if.if_flags |= IFF_UP;
                        carp_setrun(sc, 0);
                }
+               carp_update_link_state(sc);
                break;
 
        case SIOCSVH:
@@ -2174,6 +2183,10 @@
                        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 @@
        }
 }
 
+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_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 @@
                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;
        }
        /*
diff -r 97f7b39fcec1 -r f56fd4b11cf7 sys/netinet/ip_carp.h
--- a/sys/netinet/ip_carp.h     Thu Jan 16 12:54:16 2020 +0000
+++ b/sys/netinet/ip_carp.h     Thu Jan 16 12:56:39 2020 +0000
@@ -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 @@
        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
  */



Home | Main Index | Thread Index | Old Index