diff --git a/net/quagga/distinfo b/net/quagga/distinfo index fb020e12b51f..eb91a05e133c 100644 --- a/net/quagga/distinfo +++ b/net/quagga/distinfo @@ -1,4 +1,4 @@ -$NetBSD: distinfo,v 1.32 2019/09/30 08:57:49 kardel Exp $ +$NetBSD: distinfo,v 1.33 2020/12/10 17:08:17 kardel Exp $ SHA1 (quagga-1.2.4.tar.gz) = 8e1471624f5baf54b53be6636e451824d3ef15f6 RMD160 (quagga-1.2.4.tar.gz) = 9d4b807ce150db9d3cec1f6bf9a3f836d4973428 @@ -8,4 +8,5 @@ SHA1 (patch-configure) = d3289b94f9aa871678398ccd78f655944277f03f SHA1 (patch-lib_thread.c) = 8e3cf21225a1ec5e94ac526b0b5a4e9e66ca4c93 SHA1 (patch-lib_thread.h) = 1afcc4c4a30dfa2f0e182310568b5e31acec21fb SHA1 (patch-solaris_quagga.init.in) = 47569aaffe2713809e21ebbb76164cf50b7f983f -SHA1 (patch-zebra_kernel__socket.c) = 82c1be406ec587d7bc4d6eec39f9daebbc34e999 +SHA1 (patch-zebra_ioctl.c) = b7fb1a543f9cce7d798fadb39ef465e8fc6c3eca +SHA1 (patch-zebra_kernel__socket.c) = 9f0bdc301e030ff9e988e4d20aa1d9e52e1b6ff6 diff --git a/net/quagga/patches/patch-zebra_ioctl.c b/net/quagga/patches/patch-zebra_ioctl.c new file mode 100644 index 000000000000..bc88a2a6e13b --- /dev/null +++ b/net/quagga/patches/patch-zebra_ioctl.c @@ -0,0 +1,115 @@ +$NetBSD: patch-zebra_ioctl.c,v 1.1 2020/12/10 17:08:17 kardel Exp $ + + use SIOCGIFDATA on NetBSD to fetch link status + instead of relying on SIOCGIFMEDIA + +--- zebra/ioctl.c.orig 2018-02-19 21:24:55.000000000 +0000 ++++ zebra/ioctl.c +@@ -348,9 +348,6 @@ if_get_flags (struct interface *ifp) + { + int ret; + struct ifreq ifreq; +-#ifdef HAVE_BSD_LINK_DETECT +- struct ifmediareq ifmr; +-#endif /* HAVE_BSD_LINK_DETECT */ + + ifreq_set_name (&ifreq, ifp); + +@@ -360,33 +357,74 @@ if_get_flags (struct interface *ifp) + zlog_err("if_ioctl(SIOCGIFFLAGS) failed: %s", safe_strerror(errno)); + return; + } +-#ifdef HAVE_BSD_LINK_DETECT /* Detect BSD link-state at start-up */ + +- /* Per-default, IFF_RUNNING is held high, unless link-detect says +- * otherwise - we abuse IFF_RUNNING inside zebra as a link-state flag, +- * following practice on Linux and Solaris kernels +- */ +- SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); +- +- if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) +- { +- (void) memset(&ifmr, 0, sizeof(ifmr)); +- strncpy (ifmr.ifm_name, ifp->name, IFNAMSIZ); +- +- /* Seems not all interfaces implement this ioctl */ +- if (if_ioctl(SIOCGIFMEDIA, (caddr_t) &ifmr) < 0) +- zlog_err("if_ioctl(SIOCGIFMEDIA) failed: %s", safe_strerror(errno)); +- else if (ifmr.ifm_status & IFM_AVALID) /* Link state is valid */ +- { +- if (ifmr.ifm_status & IFM_ACTIVE) +- SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); +- else +- UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING); ++ if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) ++ goto out; ++ ++#ifdef SIOCGIFDATA ++ /* ++ * BSD gets link state from ifi_link_link in struct if_data. ++ * All BSD's have this in getifaddrs(3) ifa_data for AF_LINK addresses. ++ * We can also access it via SIOCGIFDATA. ++ */ ++ ++#ifdef __NetBSD__ ++ struct ifdatareq ifdr = { .ifdr_data.ifi_link_state = 0 }; ++ struct if_data *ifdata = &ifdr.ifdr_data; ++ ++ strlcpy(ifdr.ifdr_name, ifp->name, sizeof(ifdr.ifdr_name)); ++ ret = if_ioctl(SIOCGIFDATA, (caddr_t)&ifdr); ++#else ++ struct if_data ifd = { .ifi_link_state = 0 }; ++ struct if_data *ifdata = &ifd; ++ ++ ifreq.ifr_data = (caddr_t)ifdata; ++ ret = if_ioctl(SIOCGIFDATA, (caddr_t)&ifreq); ++#endif ++ ++ if (ret == -1) ++ /* Very unlikely. Did the interface disappear? */ ++ zlog_err("if_ioctl(SIOCGIFDATA) failed: %s", ++ safe_strerror(errno)); ++ else { ++ if (ifdata->ifi_link_state >= LINK_STATE_UP) ++ SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); ++ else if (ifdata->ifi_link_state == LINK_STATE_UNKNOWN) ++ /* BSD traditionally treats UNKNOWN as UP */ ++ SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); ++ else ++ UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING); ++ } ++ ++#elif defined(HAVE_BSD_LINK_DETECT) ++ /* ++ * This is only needed for FreeBSD older than FreeBSD-13. ++ * Valid and active media generally means the link state is ++ * up, but this is not always the case. ++ * For example, some BSD's with a net80211 interface in MONITOR ++ * mode will treat the media as valid and active but the ++ * link state is down - because we cannot send anything. ++ * Also, virtual interfaces such as PPP, VLAN, etc generally ++ * don't support media at all, so the ioctl will just fail. ++ */ ++ struct ifmediareq ifmr = { .ifm_status = 0 }; ++ ++ strlcpy(ifmr.ifm_name, ifp->name, sizeof(ifmr.ifm_name)); ++ ++ if (if_ioctl(SIOCGIFMEDIA, (caddr_t)&ifmr) == -1) { ++ if (errno != EINVAL) ++ zlog_err("if_ioctl(SIOCGIFMEDIA) failed: %s", ++ safe_strerror(errno)); ++ } else if (ifmr.ifm_status & IFM_AVALID) { /* media state is valid */ ++ if (ifmr.ifm_status & IFM_ACTIVE) /* media is active */ ++ SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); ++ else ++ UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + } +- } + #endif /* HAVE_BSD_LINK_DETECT */ + +- if_flags_update (ifp, (ifreq.ifr_flags & 0x0000ffff)); ++out: ++ if_flags_update (ifp, (ifreq.ifr_flags & 0x0000ffff)); + } + + /* Set interface flags */ diff --git a/net/quagga/patches/patch-zebra_kernel__socket.c b/net/quagga/patches/patch-zebra_kernel__socket.c index c7528d92d097..38fb801b84c0 100644 --- a/net/quagga/patches/patch-zebra_kernel__socket.c +++ b/net/quagga/patches/patch-zebra_kernel__socket.c @@ -1,4 +1,6 @@ -$NetBSD: patch-zebra_kernel__socket.c,v 1.2 2017/10/08 15:25:45 gdt Exp $ +$NetBSD: patch-zebra_kernel__socket.c,v 1.3 2020/12/10 17:08:17 kardel Exp $ + + RTM_RESOLVE needs to be conditional --- zebra/kernel_socket.c.orig 2017-10-03 14:57:10.000000000 +0000 +++ zebra/kernel_socket.c