From 62ccfe7163433acb4a0730d55b128c2d5306369b Mon Sep 17 00:00:00 2001 From: purplerain Date: Mon, 13 Jan 2025 18:23:20 +0000 Subject: [PATCH] sync with OpenBSD -current --- libexec/security/security | 7 +- regress/sys/netinet/tcpthread/tcpthread.c | 6 +- .../usr.sbin/bgpd/integrationtests/Makefile | 7 +- .../integrationtests/bgpd.extnh.rdomain1.conf | 23 ++++ .../bgpd.extnh.rdomain2_1.conf | 21 ++++ .../bgpd.extnh.rdomain2_2.conf | 23 ++++ .../usr.sbin/bgpd/integrationtests/extnh.sh | 91 ++++++++++++++++ .../bgpd/integrationtests/extnh.test1.ok | 20 ++++ sys/arch/arm64/stand/efiboot/efiboot.c | 4 +- sys/dev/i2c/ihidev.c | 6 +- sys/dev/usb/utvfu.c | 10 +- sys/dev/usb/utvfu.h | 3 +- sys/dev/usb/uvideo.c | 67 ++++++------ sys/dev/usb/uvideo.h | 20 +++- sys/kern/kern_task.c | 6 +- sys/kern/kern_timeout.c | 5 +- sys/ntfs/ntfs_ihash.c | 16 ++- sys/ntfs/ntfs_ihash.h | 5 +- sys/ntfs/ntfs_subr.c | 27 ++--- usr.bin/tmux/cmd-parse.y | 12 +- usr.bin/tmux/popup.c | 10 +- usr.bin/tmux/tty.c | 4 +- usr.sbin/bgpd/bgpd.8 | 14 ++- usr.sbin/bgpd/bgpd.conf.5 | 23 +++- usr.sbin/bgpd/bgpd.h | 4 +- usr.sbin/bgpd/parse.y | 6 +- usr.sbin/bgpd/printconf.c | 7 +- usr.sbin/bgpd/rde.c | 11 +- usr.sbin/bgpd/rde_peer.c | 4 +- usr.sbin/bgpd/rde_update.c | 12 +- usr.sbin/bgpd/session.c | 103 ++++++++++++++++-- 31 files changed, 463 insertions(+), 114 deletions(-) create mode 100644 regress/usr.sbin/bgpd/integrationtests/bgpd.extnh.rdomain1.conf create mode 100644 regress/usr.sbin/bgpd/integrationtests/bgpd.extnh.rdomain2_1.conf create mode 100644 regress/usr.sbin/bgpd/integrationtests/bgpd.extnh.rdomain2_2.conf create mode 100644 regress/usr.sbin/bgpd/integrationtests/extnh.sh create mode 100644 regress/usr.sbin/bgpd/integrationtests/extnh.test1.ok diff --git a/libexec/security/security b/libexec/security/security index ed40d4d66..7683ae76c 100644 --- a/libexec/security/security +++ b/libexec/security/security @@ -1,6 +1,6 @@ #!/usr/bin/perl -T -# $OpenBSD: security,v 1.45 2025/01/10 10:16:48 schwarze Exp $ +# $OpenBSD: security,v 1.46 2025/01/12 00:18:15 schwarze Exp $ # # Copyright (c) 2011, 2012, 2014, 2015 Ingo Schwarze # Copyright (c) 2011 Andrew Fresh @@ -256,7 +256,8 @@ sub check_sh { $umaskset ||= check_umask($filename); nag !(open my $fh, '-|', qw(/bin/sh -c), - ". $filename; echo ENV=\$ENV; echo PATH=\$PATH"), + ". $filename > /dev/null; " . + "echo ENV=\$ENV; echo PATH=\$PATH"), "cannot spawn /bin/sh: $!" and next; my @output = <$fh>; @@ -290,7 +291,7 @@ sub check_ksh { check_umask($filename); nag !(open my $fh, '-|', qw(/bin/ksh -c), - ". $filename; echo PATH=\$PATH"), + ". $filename > /dev/null; echo PATH=\$PATH"), "cannot spawn /bin/ksh: $!" and next; my @output = <$fh>; diff --git a/regress/sys/netinet/tcpthread/tcpthread.c b/regress/sys/netinet/tcpthread/tcpthread.c index 8221f6bd6..4adbc29e7 100644 --- a/regress/sys/netinet/tcpthread/tcpthread.c +++ b/regress/sys/netinet/tcpthread/tcpthread.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcpthread.c,v 1.2 2025/01/06 22:25:38 bluhm Exp $ */ +/* $OpenBSD: tcpthread.c,v 1.3 2025/01/13 12:55:13 bluhm Exp $ */ /* * Copyright (c) 2025 Alexander Bluhm @@ -183,6 +183,10 @@ accept_socket(volatile int *acceptp, int *listens, /* no connection to accept */ continue; } + if (errno == ECONNABORTED) { + /* accepted socket was disconnected */ + continue; + } err(1, "%s: accept %d", __func__, listens[i]); } sa = &addrs[i].su_sa; diff --git a/regress/usr.sbin/bgpd/integrationtests/Makefile b/regress/usr.sbin/bgpd/integrationtests/Makefile index 48e201282..d683910c6 100644 --- a/regress/usr.sbin/bgpd/integrationtests/Makefile +++ b/regress/usr.sbin/bgpd/integrationtests/Makefile @@ -1,8 +1,8 @@ -# $OpenBSD: Makefile,v 1.25 2024/09/25 14:42:39 claudio Exp $ +# $OpenBSD: Makefile,v 1.26 2025/01/13 14:18:07 claudio Exp $ REGRESS_TARGETS = network_statement md5 ovs capa policy pftable \ mrt maxprefix maxprefixout maxcomm maxattr \ - l3vpn ixp lladdr \ + l3vpn ixp lladdr extnh \ as0 med eval_all attr BGPD ?= /usr/sbin/bgpd @@ -54,6 +54,9 @@ ixp: lladdr: ${SUDO} ksh ${.CURDIR}/$@.sh ${BGPD} ${.CURDIR} 11 12 pair11 pair12 +extnh: + ${SUDO} ksh ${.CURDIR}/$@.sh ${BGPD} ${.CURDIR} 11 12 pair11 pair12 + .if ! exists(/usr/local/bin/exabgp) as0: # install exabgp from ports for additional tests diff --git a/regress/usr.sbin/bgpd/integrationtests/bgpd.extnh.rdomain1.conf b/regress/usr.sbin/bgpd/integrationtests/bgpd.extnh.rdomain1.conf new file mode 100644 index 000000000..31ec8f4a2 --- /dev/null +++ b/regress/usr.sbin/bgpd/integrationtests/bgpd.extnh.rdomain1.conf @@ -0,0 +1,23 @@ +AS 4200000001 +router-id 10.12.57.1 +fib-update no + +log updates + +neighbor 2001:db8:57::2 { + descr "RDOMAIN2_1" + remote-as 4200000002 + + announce extended nexthop yes + announce IPv4 unicast +} +neighbor 2001:db8:57::3 { + descr "RDOMAIN2_2" + remote-as 4200000003 + + announce extended nexthop yes + announce IPv4 unicast +} + +allow from any +allow to any diff --git a/regress/usr.sbin/bgpd/integrationtests/bgpd.extnh.rdomain2_1.conf b/regress/usr.sbin/bgpd/integrationtests/bgpd.extnh.rdomain2_1.conf new file mode 100644 index 000000000..93ff98807 --- /dev/null +++ b/regress/usr.sbin/bgpd/integrationtests/bgpd.extnh.rdomain2_1.conf @@ -0,0 +1,21 @@ +AS 4200000002 +router-id 10.12.57.2 +fib-update no + +log updates + +listen on 2001:db8:57::2 + +network 192.168.1.0/24 + +neighbor 2001:db8:57::1 { + descr "RDOMAIN1" + remote-as 4200000001 + local-address 2001:db8:57::2 + + announce extended nexthop yes + announce IPv4 unicast +} + +allow from any +allow to any diff --git a/regress/usr.sbin/bgpd/integrationtests/bgpd.extnh.rdomain2_2.conf b/regress/usr.sbin/bgpd/integrationtests/bgpd.extnh.rdomain2_2.conf new file mode 100644 index 000000000..e7d759f80 --- /dev/null +++ b/regress/usr.sbin/bgpd/integrationtests/bgpd.extnh.rdomain2_2.conf @@ -0,0 +1,23 @@ +AS 4200000003 +router-id 10.12.57.3 +fib-update no + +log updates + +listen on 2001:db8:57::3 + +socket "/var/run/bgpd.sock.12_2" + +network 192.168.2.0/24 + +neighbor 2001:db8:57::1 { + descr "RDOMAIN1" + remote-as 4200000001 + local-address 2001:db8:57::3 + + announce extended nexthop yes + announce IPv4 unicast +} + +allow from any +allow to any diff --git a/regress/usr.sbin/bgpd/integrationtests/extnh.sh b/regress/usr.sbin/bgpd/integrationtests/extnh.sh new file mode 100644 index 000000000..aff62f3ca --- /dev/null +++ b/regress/usr.sbin/bgpd/integrationtests/extnh.sh @@ -0,0 +1,91 @@ +#!/bin/ksh +# $OpenBSD: extnh.sh,v 1.1 2025/01/13 14:18:07 claudio Exp $ + +set -e + +BGPD=$1 +BGPDCONFIGDIR=$2 +RDOMAIN1=$3 +RDOMAIN2=$4 +PAIR1=$5 +PAIR2=$6 + +RDOMAINS="${RDOMAIN1} ${RDOMAIN2}" +PAIRS="${PAIR1} ${PAIR2}" +PAIR1IP6=2001:db8:57::1 +PAIR2IP6=2001:db8:57::2 +PAIR2IP6_2=2001:db8:57::3 + +error_notify() { + echo cleanup + pkill -T ${RDOMAIN1} bgpd || true + pkill -T ${RDOMAIN2} bgpd || true + sleep 1 + ifconfig ${PAIR2} destroy || true + ifconfig ${PAIR1} destroy || true + route -qn -T ${RDOMAIN1} flush || true + route -qn -T ${RDOMAIN2} flush || true + ifconfig lo${RDOMAIN1} destroy || true + ifconfig lo${RDOMAIN2} destroy || true + if [ $1 -ne 0 ]; then + echo FAILED + exit 1 + else + echo SUCCESS + fi +} + +if [ "$(id -u)" -ne 0 ]; then + echo need root privileges >&2 + exit 1 +fi + +trap 'error_notify $?' EXIT + +echo check if rdomains are busy +for n in ${RDOMAINS}; do + if /sbin/ifconfig | grep -v "^lo${n}:" | grep " rdomain ${n} "; then + echo routing domain ${n} is already used >&2 + exit 1 + fi +done + +echo check if interfaces are busy +for n in ${PAIRS}; do + /sbin/ifconfig "${n}" >/dev/null 2>&1 && \ + ( echo interface ${n} is already used >&2; exit 1 ) +done + +set -x + +echo setup +ifconfig ${PAIR1} rdomain ${RDOMAIN1} up +ifconfig ${PAIR2} rdomain ${RDOMAIN2} up +ifconfig ${PAIR1} inet6 ${PAIR1IP6}/64 +ifconfig ${PAIR2} inet6 ${PAIR2IP6}/64 +ifconfig ${PAIR2} inet6 ${PAIR2IP6_2}/128 +ifconfig ${PAIR1} patch ${PAIR2} +ifconfig lo${RDOMAIN1} inet 127.0.0.1/8 +ifconfig lo${RDOMAIN2} inet 127.0.0.1/8 + +echo run bgpds +route -T ${RDOMAIN1} exec ${BGPD} \ + -v -f ${BGPDCONFIGDIR}/bgpd.extnh.rdomain1.conf +sleep 2 +route -T ${RDOMAIN2} exec ${BGPD} \ + -v -f ${BGPDCONFIGDIR}/bgpd.extnh.rdomain2_1.conf +route -T ${RDOMAIN2} exec ${BGPD} \ + -v -f ${BGPDCONFIGDIR}/bgpd.extnh.rdomain2_2.conf +sleep 5 + +echo test +echo "router 1 in rdomain ${RDOMAIN1}" > extnh.test1.out +route -T ${RDOMAIN1} exec bgpctl show rib | tee -a extnh.test1.out +echo "router 2_1 in rdomain ${RDOMAIN2}" >> extnh.test1.out +route -T ${RDOMAIN2} exec bgpctl show rib | tee -a extnh.test1.out + +echo check results +diff -u ${BGPDCONFIGDIR}/extnh.test1.ok extnh.test1.out +echo OK + +exit 0 diff --git a/regress/usr.sbin/bgpd/integrationtests/extnh.test1.ok b/regress/usr.sbin/bgpd/integrationtests/extnh.test1.ok new file mode 100644 index 000000000..aa0173415 --- /dev/null +++ b/regress/usr.sbin/bgpd/integrationtests/extnh.test1.ok @@ -0,0 +1,20 @@ +router 1 in rdomain 11 +flags: * = Valid, > = Selected, I = via IBGP, A = Announced, + S = Stale, E = Error, F = Filtered +origin validation state: N = not-found, V = valid, ! = invalid +aspa validation state: ? = unknown, V = valid, ! = invalid +origin: i = IGP, e = EGP, ? = Incomplete + +flags vs destination gateway lpref med aspath origin +*> N-? 192.168.1.0/24 2001:db8:57::2 100 0 4200000002 i +*> N-? 192.168.2.0/24 2001:db8:57::3 100 0 4200000003 i +router 2_1 in rdomain 12 +flags: * = Valid, > = Selected, I = via IBGP, A = Announced, + S = Stale, E = Error, F = Filtered +origin validation state: N = not-found, V = valid, ! = invalid +aspa validation state: ? = unknown, V = valid, ! = invalid +origin: i = IGP, e = EGP, ? = Incomplete + +flags vs destination gateway lpref med aspath origin +AI*> N-? 192.168.1.0/24 0.0.0.0 100 0 i +*> N-? 192.168.2.0/24 2001:db8:57::3 100 0 4200000001 4200000003 i diff --git a/sys/arch/arm64/stand/efiboot/efiboot.c b/sys/arch/arm64/stand/efiboot/efiboot.c index 288a9f1b9..0f8196330 100644 --- a/sys/arch/arm64/stand/efiboot/efiboot.c +++ b/sys/arch/arm64/stand/efiboot/efiboot.c @@ -1,4 +1,4 @@ -/* $OpenBSD: efiboot.c,v 1.62 2024/11/12 20:49:42 tobhe Exp $ */ +/* $OpenBSD: efiboot.c,v 1.63 2025/01/13 16:58:09 kirill Exp $ */ /* * Copyright (c) 2015 YASUOKA Masahiko @@ -1134,6 +1134,8 @@ struct smbios_dtb { /* Keep the list below sorted by vendor */ { "ASUS", "ASUS Vivobook S 15 S5507", "qcom/x1e80100-asus-vivobook-s15.dtb" }, + { "HONOR", "MRO-XXX", + "qcom/x1e80100-honor-magicbook-art-14.dtb" }, { "HP", "HP OmniBook X Laptop 14-fe0xxx", "qcom/x1e80100-hp-omnibook-x14.dtb" }, { "LENOVO", "21BX", diff --git a/sys/dev/i2c/ihidev.c b/sys/dev/i2c/ihidev.c index 6a97cdde5..9d77f55aa 100644 --- a/sys/dev/i2c/ihidev.c +++ b/sys/dev/i2c/ihidev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ihidev.c,v 1.38 2025/01/07 23:13:56 kirill Exp $ */ +/* $OpenBSD: ihidev.c,v 1.39 2025/01/13 15:33:34 kirill Exp $ */ /* * HID-over-i2c driver * @@ -577,8 +577,6 @@ ihidev_hid_command(struct ihidev_softc *sc, int hidcmd, void *arg) int ihidev_poweron(struct ihidev_softc *sc) { - DPRINTF(("%s: resetting\n", sc->sc_dev.dv_xname)); - if (ihidev_hid_command(sc, I2C_HID_CMD_SET_POWER, &I2C_HID_POWER_ON)) { printf("%s: failed to power on\n", sc->sc_dev.dv_xname); return (1); @@ -593,6 +591,8 @@ ihidev_poweron(struct ihidev_softc *sc) int ihidev_reset(struct ihidev_softc *sc) { + DPRINTF(("%s: resetting\n", sc->sc_dev.dv_xname)); + if (ihidev_poweron(sc)) return (1); diff --git a/sys/dev/usb/utvfu.c b/sys/dev/usb/utvfu.c index 6ccc41f3c..56ba9b0ab 100644 --- a/sys/dev/usb/utvfu.c +++ b/sys/dev/usb/utvfu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: utvfu.c,v 1.20 2024/05/23 03:21:09 jsg Exp $ */ +/* $OpenBSD: utvfu.c,v 1.21 2025/01/12 16:39:39 mglocker Exp $ */ /* * Copyright (c) 2013 Lubomir Rintel * Copyright (c) 2013 Federico Simoncelli @@ -50,23 +50,21 @@ #include #include #include -#include -#include #include #include -#include #include #include #include #include #include #include -#include +#include -#include "utvfu.h" +#include +#include #ifdef UTVFU_DEBUG int utvfu_debug = 1; diff --git a/sys/dev/usb/utvfu.h b/sys/dev/usb/utvfu.h index c17dc98f8..04ab073df 100644 --- a/sys/dev/usb/utvfu.h +++ b/sys/dev/usb/utvfu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: utvfu.h,v 1.5 2021/11/24 22:03:05 mglocker Exp $ */ +/* $OpenBSD: utvfu.h,v 1.6 2025/01/12 16:39:39 mglocker Exp $ */ /* * Copyright (c) 2013 Lubomir Rintel * All rights reserved. @@ -42,6 +42,7 @@ #include #include +#include #include /* Hardware. */ diff --git a/sys/dev/usb/uvideo.c b/sys/dev/usb/uvideo.c index 25f68ba48..0b3a1a75d 100644 --- a/sys/dev/usb/uvideo.c +++ b/sys/dev/usb/uvideo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvideo.c,v 1.233 2025/01/01 11:42:07 kirill Exp $ */ +/* $OpenBSD: uvideo.c,v 1.234 2025/01/13 15:32:36 kirill Exp $ */ /* * Copyright (c) 2008 Robert Nagy @@ -383,6 +383,18 @@ const struct uvideo_devs { #define uvideo_lookup(v, p) \ ((const struct uvideo_devs *)usb_lookup(uvideo_devs, v, p)) +const struct uvideo_map_fmts { + uint8_t guidFormat[16]; + uint32_t pixelformat; +} uvideo_map_fmts[] = { + { UVIDEO_FORMAT_GUID_YUY2, V4L2_PIX_FMT_YUYV }, + { UVIDEO_FORMAT_GUID_YV12, V4L2_PIX_FMT_YVU420 }, + { UVIDEO_FORMAT_GUID_I420, V4L2_PIX_FMT_YUV420 }, + { UVIDEO_FORMAT_GUID_Y800, V4L2_PIX_FMT_GREY }, + { UVIDEO_FORMAT_GUID_Y8, V4L2_PIX_FMT_GREY }, + { UVIDEO_FORMAT_GUID_KSMEDIA_L8_IR, V4L2_PIX_FMT_GREY }, +}; + int uvideo_open(void *addr, int flags, int *size, uint8_t *buffer, void (*intr)(void *), void *arg) @@ -1048,8 +1060,7 @@ uvideo_vs_parse_desc_format_uncompressed(struct uvideo_softc *sc, const usb_descriptor_t *desc) { struct usb_video_format_uncompressed_desc *d; - uint8_t guid_8bit_ir[16] = UVIDEO_FORMAT_GUID_KSMEDIA_L8_IR; - int i; + int i, j, nent; d = (struct usb_video_format_uncompressed_desc *)(uint8_t *)desc; @@ -1074,19 +1085,23 @@ uvideo_vs_parse_desc_format_uncompressed(struct uvideo_softc *sc, sc->sc_fmtgrp[sc->sc_fmtgrp_idx].format_dfidx = d->bDefaultFrameIndex; } + i = sc->sc_fmtgrp_idx; - if (!strcmp(sc->sc_fmtgrp[i].format->u.uc.guidFormat, "YUY2")) { - sc->sc_fmtgrp[i].pixelformat = V4L2_PIX_FMT_YUYV; - } else if (!strcmp(sc->sc_fmtgrp[i].format->u.uc.guidFormat, "NV12")) { - sc->sc_fmtgrp[i].pixelformat = V4L2_PIX_FMT_NV12; - } else if (!strcmp(sc->sc_fmtgrp[i].format->u.uc.guidFormat, "UYVY")) { - sc->sc_fmtgrp[i].pixelformat = V4L2_PIX_FMT_UYVY; - } else if (!memcmp(sc->sc_fmtgrp[i].format->u.uc.guidFormat, - guid_8bit_ir, 16)) { - sc->sc_fmtgrp[i].pixelformat = V4L2_PIX_FMT_GREY; - } else { - sc->sc_fmtgrp[i].pixelformat = 0; + + /* map GUID to pixel format if a matching entry is found */ + for (j = 0, nent = nitems(uvideo_map_fmts); j < nent; j++) { + if (!memcmp(sc->sc_fmtgrp[i].format->u.uc.guidFormat, + uvideo_map_fmts[j].guidFormat, 16)) { + sc->sc_fmtgrp[i].pixelformat = + uvideo_map_fmts[j].pixelformat; + break; + } } + /* default to using GUID start as the pixel format */ + if (j == nent) + memcpy(&sc->sc_fmtgrp[i].pixelformat, + sc->sc_fmtgrp[i].format->u.uc.guidFormat, + sizeof(uint32_t)); if (sc->sc_fmtgrp_cur == NULL) /* set UNCOMPRESSED format */ @@ -2992,26 +3007,10 @@ uvideo_enum_fmt(void *v, struct v4l2_fmtdesc *fmtdesc) break; case UDESCSUB_VS_FORMAT_UNCOMPRESSED: fmtdesc->flags = 0; - if (sc->sc_fmtgrp[idx].pixelformat == - V4L2_PIX_FMT_YUYV) { - (void)strlcpy(fmtdesc->description, "YUYV", - sizeof(fmtdesc->description)); - fmtdesc->pixelformat = V4L2_PIX_FMT_YUYV; - } else if (sc->sc_fmtgrp[idx].pixelformat == - V4L2_PIX_FMT_NV12) { - (void)strlcpy(fmtdesc->description, "NV12", - sizeof(fmtdesc->description)); - fmtdesc->pixelformat = V4L2_PIX_FMT_NV12; - } else if (sc->sc_fmtgrp[idx].pixelformat == - V4L2_PIX_FMT_UYVY) { - (void)strlcpy(fmtdesc->description, "UYVY", - sizeof(fmtdesc->description)); - fmtdesc->pixelformat = V4L2_PIX_FMT_UYVY; - } else { - (void)strlcpy(fmtdesc->description, "Unknown UC Format", - sizeof(fmtdesc->description)); - fmtdesc->pixelformat = 0; - } + fmtdesc->pixelformat = sc->sc_fmtgrp[idx].pixelformat; + (void)strlcpy(fmtdesc->description, + (char *) &fmtdesc->pixelformat, + sizeof(fmtdesc->description)); bzero(fmtdesc->reserved, sizeof(fmtdesc->reserved)); break; default: diff --git a/sys/dev/usb/uvideo.h b/sys/dev/usb/uvideo.h index ce5d25db7..3c89e3814 100644 --- a/sys/dev/usb/uvideo.h +++ b/sys/dev/usb/uvideo.h @@ -1,4 +1,4 @@ -/* $OpenBSD: uvideo.h,v 1.61 2024/12/22 20:30:04 kirill Exp $ */ +/* $OpenBSD: uvideo.h,v 1.62 2025/01/13 15:32:36 kirill Exp $ */ /* * Copyright (c) 2007 Robert Nagy @@ -297,15 +297,23 @@ struct usb_video_probe_commit { */ /* Table 2-1: Compression Formats */ #define UVIDEO_FORMAT_GUID_YUY2 { \ - 0x59, 0x55, 0x59, 0x32, 0x00, 0x00, 0x10, 0x00, \ + 'Y', 'U', 'Y', '2', '\0', 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } -#define UVIDEO_FORMAT_GUID_NV12 { \ - 0x4e, 0x56, 0x31, 0x32, 0x00, 0x00, 0x10, 0x00, \ +#define UVIDEO_FORMAT_GUID_YV12 { \ + 'Y', 'V', '1', '2', '\0', 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } -#define UVIDEO_FORMAT_GUID_UYVY { \ - 0x55, 0x59, 0x56, 0x59, 0x00, 0x00, 0x10, 0x00, \ +#define UVIDEO_FORMAT_GUID_I420 { \ + 'I', '4', '2', '0', '\0', 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } + +#define UVIDEO_FORMAT_GUID_Y800 { \ + 'Y', '8', '0', '0', '\0', 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } + +#define UVIDEO_FORMAT_GUID_Y8 { \ + 'Y', '8', ' ', ' ', '\0', 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } #define UVIDEO_FORMAT_GUID_KSMEDIA_L8_IR { \ diff --git a/sys/kern/kern_task.c b/sys/kern/kern_task.c index c3dcc5f48..759b9688e 100644 --- a/sys/kern/kern_task.c +++ b/sys/kern/kern_task.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_task.c,v 1.35 2024/05/14 08:26:13 jsg Exp $ */ +/* $OpenBSD: kern_task.c,v 1.36 2025/01/13 03:21:10 mvs Exp $ */ /* * Copyright (c) 2013 David Gwynne @@ -333,9 +333,7 @@ taskq_del_barrier(struct taskq *tq, struct task *t) { WITNESS_CHECKORDER(&tq->tq_lock_object, LOP_NEWORDER, NULL); - if (task_del(tq, t)) - return; - + task_del(tq, t); taskq_do_barrier(tq); } diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c index 18e1cbb61..d7ad87262 100644 --- a/sys/kern/kern_timeout.c +++ b/sys/kern/kern_timeout.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_timeout.c,v 1.100 2024/11/07 16:02:29 miod Exp $ */ +/* $OpenBSD: kern_timeout.c,v 1.101 2025/01/13 03:21:10 mvs Exp $ */ /* * Copyright (c) 2001 Thomas Nordin * Copyright (c) 2000-2001 Artur Grabowski @@ -457,8 +457,7 @@ timeout_del_barrier(struct timeout *to) timeout_sync_order(ISSET(to->to_flags, TIMEOUT_PROC)); removed = timeout_del(to); - if (!removed) - timeout_barrier(to); + timeout_barrier(to); return removed; } diff --git a/sys/ntfs/ntfs_ihash.c b/sys/ntfs/ntfs_ihash.c index b166360f3..f5623f40e 100644 --- a/sys/ntfs/ntfs_ihash.c +++ b/sys/ntfs/ntfs_ihash.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ntfs_ihash.c,v 1.21 2021/03/11 13:31:35 jsg Exp $ */ +/* $OpenBSD: ntfs_ihash.c,v 1.22 2025/01/13 13:58:41 claudio Exp $ */ /* $NetBSD: ntfs_ihash.c,v 1.1 2002/12/23 17:38:32 jdolecek Exp $ */ /* @@ -54,7 +54,6 @@ static LIST_HEAD(nthashhead, ntnode) *ntfs_nthashtbl; static SIPHASH_KEY ntfs_nthashkey; static u_long ntfs_nthash; /* size of hash table - 1 */ #define NTNOHASH(device, inum) ntfs_hash((device), (inum)) -struct rwlock ntfs_hashlock = RWLOCK_INITIALIZER("ntfs_nthashlock"); /* * Initialize inode hash table. @@ -115,16 +114,25 @@ ntfs_nthashlookup(dev_t dev, ntfsino_t inum) /* * Insert the ntnode into the hash table. */ -void +int ntfs_nthashins(struct ntnode *ip) { struct nthashhead *ipp; + struct ntnode *curip; /* XXXLOCKING lock hash list? */ ipp = &ntfs_nthashtbl[NTNOHASH(ip->i_dev, ip->i_number)]; - LIST_INSERT_HEAD(ipp, ip, i_hash); + LIST_FOREACH(curip, ipp, i_hash) { + if (ip->i_number == curip->i_number && + ip->i_dev == curip->i_dev) + return (EEXIST); + } + ip->i_flag |= IN_HASHED; + LIST_INSERT_HEAD(ipp, ip, i_hash); /* XXXLOCKING unlock hash list? */ + + return (0); } /* diff --git a/sys/ntfs/ntfs_ihash.h b/sys/ntfs/ntfs_ihash.h index 0f432782f..0ced0cebc 100644 --- a/sys/ntfs/ntfs_ihash.h +++ b/sys/ntfs/ntfs_ihash.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ntfs_ihash.h,v 1.6 2016/08/10 16:12:13 natano Exp $ */ +/* $OpenBSD: ntfs_ihash.h,v 1.7 2025/01/13 13:58:41 claudio Exp $ */ /* $NetBSD: ntfs_ihash.h,v 1.1 2002/12/23 17:38:32 jdolecek Exp $ */ /*- @@ -29,8 +29,7 @@ * Id: ntfs_ihash.h,v 1.3 1999/05/12 09:42:59 semenu Exp */ -extern struct rwlock ntfs_hashlock; void ntfs_nthashinit(void); struct ntnode *ntfs_nthashlookup(dev_t, ntfsino_t); -void ntfs_nthashins(struct ntnode *); +int ntfs_nthashins(struct ntnode *); void ntfs_nthashrem(struct ntnode *); diff --git a/sys/ntfs/ntfs_subr.c b/sys/ntfs/ntfs_subr.c index 5b2b63858..33de5702e 100644 --- a/sys/ntfs/ntfs_subr.c +++ b/sys/ntfs/ntfs_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ntfs_subr.c,v 1.52 2022/01/11 03:13:59 jsg Exp $ */ +/* $OpenBSD: ntfs_subr.c,v 1.53 2025/01/13 13:58:41 claudio Exp $ */ /* $NetBSD: ntfs_subr.c,v 1.4 2003/04/10 21:37:32 jdolecek Exp $ */ /*- @@ -388,15 +388,14 @@ ntfs_ntlookup(struct ntfsmount *ntmp, ntfsino_t ino, struct ntnode **ipp) DPRINTF("ntfs_ntlookup: looking for ntnode %u\n", ino); - do { - if ((ip = ntfs_nthashlookup(ntmp->ntm_dev, ino)) != NULL) { - ntfs_ntget(ip); - DPRINTF("ntfs_ntlookup: ntnode %u: %p, usecount: %d\n", - ino, ip, ip->i_usecount); - *ipp = ip; - return (0); - } - } while (rw_enter(&ntfs_hashlock, RW_WRITE | RW_SLEEPFAIL)); + retry: + if ((ip = ntfs_nthashlookup(ntmp->ntm_dev, ino)) != NULL) { + ntfs_ntget(ip); + DPRINTF("ntfs_ntlookup: ntnode %u: %p, usecount: %d\n", + ino, ip, ip->i_usecount); + *ipp = ip; + return (0); + } ip = malloc(sizeof(*ip), M_NTFSNTNODE, M_WAITOK | M_ZERO); DDPRINTF("ntfs_ntlookup: allocating ntnode: %u: %p\n", ino, ip); @@ -408,15 +407,17 @@ ntfs_ntlookup(struct ntfsmount *ntmp, ntfsino_t ino, struct ntnode **ipp) ip->i_mp = ntmp; LIST_INIT(&ip->i_fnlist); + LIST_INIT(&ip->i_valist); vref(ip->i_devvp); /* init lock and lock the newborn ntnode */ rw_init(&ip->i_lock, "ntnode"); ntfs_ntget(ip); - ntfs_nthashins(ip); - - rw_exit(&ntfs_hashlock); + if (ntfs_nthashins(ip) != 0) { + ntfs_ntput(ip); + goto retry; + } *ipp = ip; diff --git a/usr.bin/tmux/cmd-parse.y b/usr.bin/tmux/cmd-parse.y index c519e22a5..54c3b5ccb 100644 --- a/usr.bin/tmux/cmd-parse.y +++ b/usr.bin/tmux/cmd-parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-parse.y,v 1.52 2024/11/18 08:29:35 nicm Exp $ */ +/* $OpenBSD: cmd-parse.y,v 1.53 2025/01/13 08:58:34 nicm Exp $ */ /* * Copyright (c) 2019 Nicholas Marriott @@ -1627,6 +1627,7 @@ yylex_token_tilde(char **buf, size_t *len) static char * yylex_token(int ch) { + struct cmd_parse_state *ps = &parse_state; char *buf; size_t len; enum { START, @@ -1650,9 +1651,12 @@ yylex_token(int ch) ch = '\r'; } } - if (state == NONE && ch == '\n') { - log_debug("%s: end at EOL", __func__); - break; + if (ch == '\n') { + if (state == NONE) { + log_debug("%s: end at EOL", __func__); + break; + } + ps->input->line++; } /* Whitespace or ; or } ends a token unless inside quotes. */ diff --git a/usr.bin/tmux/popup.c b/usr.bin/tmux/popup.c index dbbbb570a..05391841f 100644 --- a/usr.bin/tmux/popup.c +++ b/usr.bin/tmux/popup.c @@ -1,4 +1,4 @@ -/* $OpenBSD: popup.c,v 1.56 2024/11/25 08:36:46 nicm Exp $ */ +/* $OpenBSD: popup.c,v 1.57 2025/01/12 14:36:28 nicm Exp $ */ /* * Copyright (c) 2020 Nicholas Marriott @@ -353,9 +353,11 @@ popup_make_pane(struct popup_data *pd, enum layout_type type) new_wp = window_add_pane(wp->window, NULL, hlimit, 0); layout_assign_pane(lc, new_wp, 0); - new_wp->fd = job_transfer(pd->job, &new_wp->pid, new_wp->tty, - sizeof new_wp->tty); - pd->job = NULL; + if (pd->job != NULL) { + new_wp->fd = job_transfer(pd->job, &new_wp->pid, new_wp->tty, + sizeof new_wp->tty); + pd->job = NULL; + } screen_set_title(&pd->s, new_wp->base.title); screen_free(&new_wp->base); diff --git a/usr.bin/tmux/tty.c b/usr.bin/tmux/tty.c index bd306e156..e5ed2ea27 100644 --- a/usr.bin/tmux/tty.c +++ b/usr.bin/tmux/tty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty.c,v 1.440 2024/10/25 19:36:38 nicm Exp $ */ +/* $OpenBSD: tty.c,v 1.441 2025/01/12 14:20:49 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -2758,6 +2758,8 @@ tty_check_fg(struct tty *tty, struct colour_palette *palette, gc->fg &= 7; if (colours >= 16) gc->fg += 90; + else if (gc->fg == 0 && gc->bg == 0) + gc->fg = 7; } } return; diff --git a/usr.sbin/bgpd/bgpd.8 b/usr.sbin/bgpd/bgpd.8 index c9e256b67..82cf5a6f3 100644 --- a/usr.sbin/bgpd/bgpd.8 +++ b/usr.sbin/bgpd/bgpd.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: bgpd.8,v 1.82 2025/01/07 12:00:36 claudio Exp $ +.\" $OpenBSD: bgpd.8,v 1.83 2025/01/13 13:50:34 claudio Exp $ .\" .\" Copyright (c) 2003, 2004 Henning Brauer .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: January 7 2025 $ +.Dd $Mdocdate: January 13 2025 $ .Dt BGPD 8 .Os .Sh NAME @@ -536,6 +536,16 @@ has been started. .Re .Pp .Rs +.%A S. Litkowski +.%A S. Agrawal +.%A K. Ananthamurthy +.%A K. Patel +.%D November 2020 +.%R RFC 8950 +.%T Advertising IPv4 Network Layer Reachability Information (NLRI) with an IPv6 Next Hop +.Re +.Pp +.Rs .%A C. Loibl .%A S. Hares .%A R. Raszuk diff --git a/usr.sbin/bgpd/bgpd.conf.5 b/usr.sbin/bgpd/bgpd.conf.5 index 830c3f1a6..791c3d43b 100644 --- a/usr.sbin/bgpd/bgpd.conf.5 +++ b/usr.sbin/bgpd/bgpd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: bgpd.conf.5,v 1.247 2025/01/09 15:57:31 claudio Exp $ +.\" $OpenBSD: bgpd.conf.5,v 1.248 2025/01/13 13:50:34 claudio Exp $ .\" .\" Copyright (c) 2004 Claudio Jeker .\" Copyright (c) 2003, 2004 Henning Brauer @@ -16,7 +16,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: January 9 2025 $ +.Dd $Mdocdate: January 13 2025 $ .Dt BGPD.CONF 5 .Os .Sh NAME @@ -1119,6 +1119,25 @@ The default is .Ic no . .Pp .It Xo +.Ic announce extended nexthop +.Pq Ic yes Ns | Ns Ic no Ns | Ns Ic enforce +.Xc +If set to +.Ic yes , +the extended nexthop encoding capability is announced. +If negotiated, +.Ic IPv4 unicast +and +.Ic vpn +sessions can send paths with a IPv6 nexthop. +If +.Ic enforce +is set, the session will only be established if the neighbor also announces +the capability. +The default is +.Ic no . +.Pp +.It Xo .Ic announce graceful notification .Pq Ic yes Ns | Ns Ic no .Xc diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index c2c59ddd4..c9b54516b 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.508 2025/01/09 12:16:21 claudio Exp $ */ +/* $OpenBSD: bgpd.h,v 1.509 2025/01/13 13:50:34 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -415,7 +415,7 @@ struct capabilities { } grestart; int8_t mp[AID_MAX]; /* multiprotocol extensions, RFC 4760 */ int8_t add_path[AID_MAX]; /* ADD_PATH, RFC 7911 */ - int8_t ext_nexthop[AID_MAX]; /* Ext Nexthop Encoding, RFC 8950 */ + int8_t ext_nh[AID_MAX]; /* Ext Nexthop Encoding, RFC 8950 */ int8_t refresh; /* route refresh, RFC 2918 */ int8_t as4byte; /* 4-byte ASnum, RFC 4893 */ int8_t enhanced_rr; /* enhanced route refresh, RFC 7313 */ diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y index f7ad98fd3..c6d0550b6 100644 --- a/usr.sbin/bgpd/parse.y +++ b/usr.sbin/bgpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.475 2025/01/09 15:57:31 claudio Exp $ */ +/* $OpenBSD: parse.y,v 1.476 2025/01/13 13:50:34 claudio Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer @@ -2033,6 +2033,10 @@ peeropts : REMOTEAS as4number { | ANNOUNCE EXTENDED MESSAGE yesnoenforce { curpeer->conf.capabilities.ext_msg = $4; } + | ANNOUNCE EXTENDED NEXTHOP yesnoenforce { + curpeer->conf.capabilities.ext_nh[AID_VPN_IPv4] = + curpeer->conf.capabilities.ext_nh[AID_INET] = $4; + } | ROLE STRING { if (strcmp($2, "provider") == 0) { curpeer->conf.role = ROLE_PROVIDER; diff --git a/usr.sbin/bgpd/printconf.c b/usr.sbin/bgpd/printconf.c index 4b1b83154..b80cf6f71 100644 --- a/usr.sbin/bgpd/printconf.c +++ b/usr.sbin/bgpd/printconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printconf.c,v 1.179 2025/01/09 15:57:31 claudio Exp $ */ +/* $OpenBSD: printconf.c,v 1.180 2025/01/13 13:50:34 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -973,6 +973,11 @@ print_announce(struct peer_config *p, const char *c) else if (p->capabilities.ext_msg == 1) printf("%s\tannounce extended message yes\n", c); + if (p->capabilities.ext_nh[AID_INET] == 2) + printf("%s\tannounce extended nexthop enforce\n", c); + else if (p->capabilities.ext_nh[AID_INET] == 1) + printf("%s\tannounce extended nexthop yes\n", c); + if (p->capabilities.add_path[AID_MIN] & CAPA_AP_RECV_ENFORCE) printf("%s\tannounce add-path recv enforce\n", c); else if (p->capabilities.add_path[AID_MIN] & CAPA_AP_RECV) diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c index d6754a379..90dac53af 100644 --- a/usr.sbin/bgpd/rde.c +++ b/usr.sbin/bgpd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.648 2025/01/09 12:16:21 claudio Exp $ */ +/* $OpenBSD: rde.c,v 1.649 2025/01/13 13:50:34 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -3345,6 +3345,10 @@ rde_send_kroute(struct rib *rib, struct prefix *new, struct prefix *old) switch (kf.prefix.aid) { case AID_VPN_IPv4: + /* XXX FIB can not handle non-IPv4 nexthop */ + if (kf.nexthop.aid != AID_INET) + type = IMSG_KROUTE_DELETE; + /* FALLTHROUGH */ case AID_VPN_IPv6: if (!(rib->flags & F_RIB_LOCAL)) /* not Loc-RIB, no update for VPNs */ @@ -3361,6 +3365,11 @@ rde_send_kroute(struct rib *rib, struct prefix *new, struct prefix *old) __LINE__); } break; + case AID_INET: + /* XXX FIB can not handle non-IPv4 nexthop */ + if (kf.nexthop.aid != AID_INET) + type = IMSG_KROUTE_DELETE; + /* FALLTHROUGH */ default: if (imsg_compose(ibuf_main, type, rib->rtableid, 0, -1, &kf, sizeof(kf)) == -1) diff --git a/usr.sbin/bgpd/rde_peer.c b/usr.sbin/bgpd/rde_peer.c index e53fef721..dd16d6bf5 100644 --- a/usr.sbin/bgpd/rde_peer.c +++ b/usr.sbin/bgpd/rde_peer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_peer.c,v 1.44 2025/01/09 12:16:21 claudio Exp $ */ +/* $OpenBSD: rde_peer.c,v 1.45 2025/01/13 13:50:34 claudio Exp $ */ /* * Copyright (c) 2019 Claudio Jeker @@ -68,7 +68,7 @@ peer_has_ext_nexthop(struct rde_peer *peer, uint8_t aid) { if (aid >= AID_MAX) return 0; - return peer->capa.ext_nexthop[aid]; + return peer->capa.ext_nh[aid]; } int diff --git a/usr.sbin/bgpd/rde_update.c b/usr.sbin/bgpd/rde_update.c index e76a261d7..2639cb7be 100644 --- a/usr.sbin/bgpd/rde_update.c +++ b/usr.sbin/bgpd/rde_update.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_update.c,v 1.173 2025/01/09 12:16:21 claudio Exp $ */ +/* $OpenBSD: rde_update.c,v 1.174 2025/01/13 13:50:34 claudio Exp $ */ /* * Copyright (c) 2004 Claudio Jeker @@ -467,7 +467,10 @@ up_get_nexthop(struct rde_peer *peer, struct filterstate *state, uint8_t aid) switch (aid) { case AID_INET: case AID_VPN_IPv4: - if (peer->local_v4_addr.aid == AID_INET) + if (peer_has_ext_nexthop(peer, aid) && + peer->remote_addr.aid == AID_INET6) + peer_local = &peer->local_v6_addr; + else if (peer->local_v4_addr.aid == AID_INET) peer_local = &peer->local_v4_addr; break; case AID_INET6: @@ -625,6 +628,11 @@ up_generate_attr(struct ibuf *buf, struct rde_peer *peer, case AID_INET: if (nh == NULL) return -1; + if (nh->exit_nexthop.aid != AID_INET) { + if (peer_has_ext_nexthop(peer, aid)) + break; + return -1; + } if (attr_writebuf(buf, ATTR_WELL_KNOWN, ATTR_NEXTHOP, &nh->exit_nexthop.v4, sizeof(nh->exit_nexthop.v4)) == -1) diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c index dbe8d4074..47b590ae1 100644 --- a/usr.sbin/bgpd/session.c +++ b/usr.sbin/bgpd/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.506 2025/01/03 12:57:49 claudio Exp $ */ +/* $OpenBSD: session.c,v 1.507 2025/01/13 13:50:34 claudio Exp $ */ /* * Copyright (c) 2003, 2004, 2005 Henning Brauer @@ -67,8 +67,6 @@ void session_accept(int); int session_connect(struct peer *); void session_tcp_established(struct peer *); int session_capa_add(struct ibuf *, uint8_t, uint8_t); -int session_capa_add_mp(struct ibuf *, uint8_t); -int session_capa_add_afi(struct ibuf *, uint8_t, uint8_t); struct ibuf *session_newmsg(enum msg_type, uint16_t); void session_sendmsg(struct ibuf *, struct peer *, enum msg_type); void session_open(struct peer *); @@ -1364,7 +1362,7 @@ session_capa_add(struct ibuf *opb, uint8_t capa_code, uint8_t capa_len) return (errs); } -int +static int session_capa_add_mp(struct ibuf *buf, uint8_t aid) { uint16_t afi; @@ -1383,10 +1381,10 @@ session_capa_add_mp(struct ibuf *buf, uint8_t aid) return (errs); } -int +static int session_capa_add_afi(struct ibuf *b, uint8_t aid, uint8_t flags) { - u_int errs = 0; + int errs = 0; uint16_t afi; uint8_t safi; @@ -1402,6 +1400,25 @@ session_capa_add_afi(struct ibuf *b, uint8_t aid, uint8_t flags) return (errs); } +static int +session_capa_add_ext_nh(struct ibuf *b, uint8_t aid) +{ + int errs = 0; + uint16_t afi; + uint8_t safi; + + if (aid2afi(aid, &afi, &safi)) { + log_warn("%s: bad AID", __func__); + return (-1); + } + + errs += ibuf_add_n16(b, afi); + errs += ibuf_add_n16(b, safi); + errs += ibuf_add_n16(b, AFI_IPv6); + + return (errs); +} + struct ibuf * session_newmsg(enum msg_type msgtype, uint16_t len) { @@ -1517,7 +1534,22 @@ session_open(struct peer *p) if (p->capa.ann.refresh) /* no data */ errs += session_capa_add(opb, CAPA_REFRESH, 0); - /* extended message support, RFC8654 */ + /* extended nexthop encoding, RFC 8950 */ + if (p->capa.ann.ext_nh[AID_INET]) { + uint8_t enhlen = 0; + + if (p->capa.ann.mp[AID_INET]) + enhlen += 6; + if (p->capa.ann.mp[AID_VPN_IPv4]) + enhlen += 6; + errs += session_capa_add(opb, CAPA_EXT_NEXTHOP, enhlen); + if (p->capa.ann.mp[AID_INET]) + errs += session_capa_add_ext_nh(opb, AID_INET); + if (p->capa.ann.mp[AID_VPN_IPv4]) + errs += session_capa_add_ext_nh(opb, AID_VPN_IPv4); + } + + /* extended message support, RFC 8654 */ if (p->capa.ann.ext_msg) /* no data */ errs += session_capa_add(opb, CAPA_EXT_MSG, 0); @@ -2540,7 +2572,7 @@ int parse_capabilities(struct peer *peer, struct ibuf *buf, uint32_t *as) { struct ibuf capabuf; - uint16_t afi, gr_header; + uint16_t afi, nhafi, tmp16, gr_header; uint8_t capa_code, capa_len; uint8_t safi, aid, role, flags; @@ -2582,6 +2614,38 @@ parse_capabilities(struct peer *peer, struct ibuf *buf, uint32_t *as) case CAPA_REFRESH: peer->capa.peer.refresh = 1; break; + case CAPA_EXT_NEXTHOP: + while (ibuf_size(&capabuf) > 0) { + if (ibuf_get_n16(&capabuf, &afi) == -1 || + ibuf_get_n16(&capabuf, &tmp16) == -1 || + ibuf_get_n16(&capabuf, &nhafi) == -1) { + log_peer_warnx(&peer->conf, + "Received bad %s capability", + log_capability(CAPA_EXT_NEXTHOP)); + memset(peer->capa.peer.ext_nh, 0, + sizeof(peer->capa.peer.ext_nh)); + break; + } + if (afi2aid(afi, tmp16, &aid) == -1 || + !(aid == AID_INET || aid == AID_VPN_IPv4)) { + log_peer_warnx(&peer->conf, + "Received %s capability: " + " unsupported AFI %u, safi %u pair", + log_capability(CAPA_EXT_NEXTHOP), + afi, safi); + continue; + } + if (nhafi != AFI_IPv6) { + log_peer_warnx(&peer->conf, + "Received %s capability: " + " unsupported nexthop AFI %u", + log_capability(CAPA_EXT_NEXTHOP), + nhafi); + continue; + } + peer->capa.peer.ext_nh[aid] = 1; + } + break; case CAPA_EXT_MSG: peer->capa.peer.ext_msg = 1; break; @@ -2798,6 +2862,16 @@ capa_neg_calc(struct peer *p) (p->capa.ann.grestart.grnotification && p->capa.peer.grestart.grnotification) != 0; + /* RFC 8950 extended nexthop encoding: both sides need to agree */ + memset(p->capa.neg.add_path, 0, sizeof(p->capa.neg.add_path)); + for (i = AID_MIN; i < AID_MAX; i++) { + if (p->capa.neg.mp[i] == 0) + continue; + if (p->capa.ann.ext_nh[i] && p->capa.peer.ext_nh[i]) { + p->capa.neg.ext_nh[i] = 1; + } + } + /* * ADD-PATH: set only those bits where both sides agree. * For this compare our send bit with the recv bit from the peer @@ -2929,6 +3003,17 @@ capa_neg_calc(struct peer *p) } } + for (i = AID_MIN; i < AID_MAX; i++) { + if (p->capa.neg.mp[i] == 0) + continue; + if (p->capa.ann.ext_nh[i] == 2 && + p->capa.neg.ext_nh[i] == 0) { + capa_code = CAPA_EXT_NEXTHOP; + capa_len = 6; + capa_aid = i; + goto fail; + } + } return (0); fail: @@ -2940,6 +3025,8 @@ capa_neg_calc(struct peer *p) session_capa_add_mp(ebuf, capa_aid); else if (capa_code == CAPA_ADD_PATH) session_capa_add_afi(ebuf, capa_aid, 0); + else if (capa_code == CAPA_EXT_NEXTHOP) + session_capa_add_ext_nh(ebuf, capa_aid); else if (capa_len > 0) ibuf_add_zero(ebuf, capa_len);