This commit is contained in:
purplerain 2025-02-05 06:25:40 +00:00
parent 54eb3e7d48
commit 55a56ce945
Signed by: purplerain
GPG key ID: F42C07F07E2E35B7
16 changed files with 572 additions and 110 deletions

View file

@ -2773,8 +2773,8 @@ install_sets() {
# Set default location to the first cdrom device if any are found.
[[ -n $_cddevs ]] && : ${_d:=cd0}
# In case none of the above applied, set HTTP as default location.
: ${_d:=http}
# In case none of the above applied, set disk as default location.
: ${_d:=disk}
# If the default location set so far is not one of the cdrom devices or
# is not in the list of valid locations, set a sane default.

View file

@ -3,5 +3,4 @@
# sh/ksh initialization
PATH=$HOME/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin
export PS1="\[\033[38;5;69m\]┌─(\[\033[38;5;15m\]\u\[\033[38;5;69m\]@\[\033[38;5;15m\]\h\[\033[38;5;69m\])\[\033[38;5;69m\]─[\[\033[38;5;69m\]\w\[\033[38;5;69m\]]\n\[\033[38;5;69m\]└─$\[$(tput sgr0)\] "
export PATH HOME TERM

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bn_recp.c,v 1.30 2025/01/22 12:53:16 tb Exp $ */
/* $OpenBSD: bn_recp.c,v 1.33 2025/02/04 20:22:20 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -104,34 +104,6 @@ BN_RECP_CTX_free(BN_RECP_CTX *recp)
freezero(recp, sizeof(*recp));
}
/* len is the expected size of the result
* We actually calculate with an extra word of precision, so
* we can do faster division if the remainder is not required.
*/
/* r := 2^len / m */
static int
BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx)
{
int ret = -1;
BIGNUM *t;
BN_CTX_start(ctx);
if ((t = BN_CTX_get(ctx)) == NULL)
goto err;
if (!BN_set_bit(t, len))
goto err;
if (!BN_div_ct(r, NULL, t, m, ctx))
goto err;
ret = len;
err:
BN_CTX_end(ctx);
return ret;
}
int
BN_div_reciprocal(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, BN_RECP_CTX *recp,
BN_CTX *ctx)
@ -139,34 +111,33 @@ BN_div_reciprocal(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, BN_RECP_CTX *recp,
int i, j, ret = 0;
BIGNUM *a, *b, *d, *r;
BN_CTX_start(ctx);
a = BN_CTX_get(ctx);
b = BN_CTX_get(ctx);
if (dv != NULL)
d = dv;
else
d = BN_CTX_get(ctx);
if (rem != NULL)
r = rem;
else
r = BN_CTX_get(ctx);
if (a == NULL || b == NULL || d == NULL || r == NULL)
goto err;
if (BN_ucmp(m, recp->N) < 0) {
BN_zero(d);
if (!bn_copy(r, m)) {
BN_CTX_end(ctx);
return 0;
}
BN_CTX_end(ctx);
if (dv != NULL)
BN_zero(dv);
if (rem != NULL)
return bn_copy(rem, m);
return 1;
}
/* We want the remainder
* Given input of ABCDEF / ab
* we need multiply ABCDEF by 3 digests of the reciprocal of ab
*
BN_CTX_start(ctx);
if ((a = BN_CTX_get(ctx)) == NULL)
goto err;
if ((b = BN_CTX_get(ctx)) == NULL)
goto err;
if ((d = dv) == NULL)
d = BN_CTX_get(ctx);
if (d == NULL)
goto err;
if ((r = rem) == NULL)
r = BN_CTX_get(ctx);
if (r == NULL)
goto err;
/*
* We want the remainder. Given input of ABCDEF / ab we need to
* multiply ABCDEF by 3 digits of the reciprocal of ab.
*/
/* i := max(BN_num_bits(m), 2*BN_num_bits(N)) */
@ -175,18 +146,21 @@ BN_div_reciprocal(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, BN_RECP_CTX *recp,
if (j > i)
i = j;
/* Nr := round(2^i / N) */
if (i != recp->shift)
recp->shift = BN_reciprocal(recp->Nr, recp->N, i, ctx);
/* Compute Nr := (1 << i) / N if necessary. */
if (i != recp->shift) {
BN_zero(recp->Nr);
if (!BN_set_bit(recp->Nr, i))
goto err;
if (!BN_div_ct(recp->Nr, NULL, recp->Nr, recp->N, ctx))
goto err;
recp->shift = i;
}
/* BN_reciprocal returns i, or -1 for an error */
if (recp->shift == -1)
goto err;
/* d := |round(round(m / 2^BN_num_bits(N)) * recp->Nr / 2^(i - BN_num_bits(N)))|
* = |round(round(m / 2^BN_num_bits(N)) * round(2^i / N) / 2^(i - BN_num_bits(N)))|
* <= |(m / 2^BN_num_bits(N)) * (2^i / N) * (2^BN_num_bits(N) / 2^i)|
* = |m/N|
/*
* d := |((m >> BN_num_bits(N)) * recp->Nr) >> (i - BN_num_bits(N))|
* = |((m >> BN_num_bits(N)) * (1 << i) / N) >> (i - BN_num_bits(N))|
* <= |(m / 2^BN_num_bits(N)) * (2^i / N) * 2^BN_num_bits(N) / 2^i |
* = |m / N|
*/
if (!BN_rshift(a, m, recp->num_bits))
goto err;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: evp_pkey.c,v 1.32 2024/08/31 10:25:38 tb Exp $ */
/* $OpenBSD: evp_pkey.c,v 1.33 2025/02/04 04:51:34 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@ -58,6 +58,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/x509.h>
@ -84,7 +85,8 @@ EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8)
if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) {
EVPerror(EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
i2t_ASN1_OBJECT(obj_tmp, 80, algoid);
if (i2t_ASN1_OBJECT(obj_tmp, sizeof(obj_tmp), algoid) == 0)
(void)strlcpy(obj_tmp, "unknown", sizeof(obj_tmp));
ERR_asprintf_error_data("TYPE=%s", obj_tmp);
goto error;
}

View file

@ -1,4 +1,4 @@
.\" $OpenBSD: SSL_CTX_set_alpn_select_cb.3,v 1.10 2024/07/11 13:50:44 tb Exp $
.\" $OpenBSD: SSL_CTX_set_alpn_select_cb.3,v 1.11 2025/02/04 14:00:05 tb Exp $
.\" OpenSSL 87b81496 Apr 19 12:38:27 2017 -0400
.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100
.\"
@ -49,7 +49,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd $Mdocdate: July 11 2024 $
.Dd $Mdocdate: February 4 2025 $
.Dt SSL_CTX_SET_ALPN_SELECT_CB 3
.Os
.Sh NAME
@ -215,7 +215,7 @@ variable.
.Pp
For example:
.Bd -literal
const unsigned char *vector = "\e6" "spdy/1" "\e8" "http/1.1";
const unsigned char *vector = "\ex06" "spdy/1" "\ex08" "http/1.1";
unsigned int length = strlen(vector);
.Ed
.Pp

View file

@ -1,4 +1,4 @@
/* $OpenBSD: tcpthread.c,v 1.3 2025/01/13 12:55:13 bluhm Exp $ */
/* $OpenBSD: tcpthread.c,v 1.4 2025/02/04 22:00:20 bluhm Exp $ */
/*
* Copyright (c) 2025 Alexander Bluhm <bluhm@openbsd.org>
@ -114,9 +114,15 @@ connect_socket(volatile int *connectp, struct sockaddr *addr)
IPPROTO_TCP);
if (sock < 0)
err(1, "%s: socket", __func__);
if (connect(sock, addr, addr->sa_len) < 0 &&
errno != EINPROGRESS) {
err(1, "%s: connect %d", __func__, sock);
if (connect(sock, addr, addr->sa_len) < 0) {
if (errno == EADDRNOTAVAIL) {
/* kernel did run out of ports, ignore error */
if (close(sock) < 0)
err(1, "%s: close %d", __func__, sock);
return 0;
}
if (errno != EINPROGRESS)
err(1, "%s: connect %d", __func__, sock);
}
if ((int)atomic_cas_uint(connectp, -1, sock) != -1) {
/* another thread has connect slot n */

View file

@ -1,4 +1,4 @@
/* $OpenBSD: if_iwm.c,v 1.417 2024/09/01 03:08:59 jsg Exp $ */
/* $OpenBSD: if_iwm.c,v 1.418 2025/02/04 09:15:04 stsp Exp $ */
/*
* Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@ -8529,7 +8529,7 @@ iwm_scan(struct iwm_softc *sc)
* The current mode might have been fixed during association.
* Ensure all channels get scanned.
*/
if (IFM_SUBTYPE(ic->ic_media.ifm_cur->ifm_media) == IFM_AUTO)
if (IFM_MODE(ic->ic_media.ifm_cur->ifm_media) == IFM_AUTO)
ieee80211_setmode(ic, IEEE80211_MODE_AUTO);
sc->sc_flags |= IWM_FLAG_SCANNING;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: if_iwn.c,v 1.263 2024/05/24 06:02:53 jsg Exp $ */
/* $OpenBSD: if_iwn.c,v 1.264 2025/02/04 09:15:04 stsp Exp $ */
/*-
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
@ -5356,7 +5356,7 @@ iwn_scan(struct iwn_softc *sc, uint16_t flags, int bgscan)
* The current mode might have been fixed during association.
* Ensure all channels get scanned.
*/
if (IFM_SUBTYPE(ic->ic_media.ifm_cur->ifm_media) == IFM_AUTO)
if (IFM_MODE(ic->ic_media.ifm_cur->ifm_media) == IFM_AUTO)
ieee80211_setmode(ic, IEEE80211_MODE_AUTO);
sc->sc_flags |= IWN_FLAG_SCANNING;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: if_iwx.c,v 1.188 2024/11/08 09:12:46 kettenis Exp $ */
/* $OpenBSD: if_iwx.c,v 1.189 2025/02/04 09:15:04 stsp Exp $ */
/*
* Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@ -7877,7 +7877,7 @@ iwx_scan(struct iwx_softc *sc)
* The current mode might have been fixed during association.
* Ensure all channels get scanned.
*/
if (IFM_SUBTYPE(ic->ic_media.ifm_cur->ifm_media) == IFM_AUTO)
if (IFM_MODE(ic->ic_media.ifm_cur->ifm_media) == IFM_AUTO)
ieee80211_setmode(ic, IEEE80211_MODE_AUTO);
sc->sc_flags |= IWX_FLAG_SCANNING;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bgpd.h,v 1.511 2025/01/31 13:40:23 claudio Exp $ */
/* $OpenBSD: bgpd.h,v 1.512 2025/02/04 18:16:56 denis Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -25,6 +25,7 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/if_ether.h>
#include <poll.h>
#include <stdarg.h>
@ -197,15 +198,33 @@ extern const struct aid aid_vals[];
{ AFI_IPv6, AF_INET6, SAFI_MPLSVPN, "IPv6 vpn" }, \
{ AFI_IPv4, AF_INET, SAFI_FLOWSPEC, "IPv4 flowspec" }, \
{ AFI_IPv6, AF_INET6, SAFI_FLOWSPEC, "IPv6 flowspec" }, \
{ AFI_L2VPN, AF_UNSPEC, SAFI_EVPN, "L2VPN evpn" } \
{ AFI_L2VPN, AF_UNSPEC, SAFI_EVPN, "EVPN" }, \
}
#define BGP_MPLS_BOS 0x01
#define ESI_ADDR_LEN 10
#define EVPN_ROUTE_TYPE_2 0x02
#define EVPN_ROUTE_TYPE_3 0x03
#define EVPN_ROUTE_TYPE_5 0x05
struct evpn_addr {
union {
struct in_addr v4;
struct in6_addr v6;
};
uint32_t ethtag;
uint8_t mac[ETHER_ADDR_LEN];
uint8_t esi[ESI_ADDR_LEN];
uint8_t aid;
uint8_t type;
};
struct bgpd_addr {
union {
struct in_addr v4;
struct in6_addr v6;
struct evpn_addr evpn;
/* maximum size for a prefix is 256 bits */
}; /* 128-bit address */
uint64_t rd; /* route distinguisher for VPN addrs */
@ -1578,6 +1597,8 @@ time_t getmonotime(void);
/* util.c */
char *ibuf_get_string(struct ibuf *, size_t);
const char *log_addr(const struct bgpd_addr *);
const char *log_evpnaddr(const struct bgpd_addr *, struct sockaddr *,
socklen_t);
const char *log_in6addr(const struct in6_addr *);
const char *log_sockaddr(struct sockaddr *, socklen_t);
const char *log_as(uint32_t);
@ -1605,6 +1626,7 @@ int nlri_get_vpn4(struct ibuf *, struct bgpd_addr *, uint8_t *,
int);
int nlri_get_vpn6(struct ibuf *, struct bgpd_addr *, uint8_t *,
int);
int nlri_get_evpn(struct ibuf *, struct bgpd_addr *, uint8_t *);
int prefix_compare(const struct bgpd_addr *,
const struct bgpd_addr *, int);
void inet4applymask(struct in_addr *, const struct in_addr *, int);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: kroute.c,v 1.312 2025/01/27 15:22:11 claudio Exp $ */
/* $OpenBSD: kroute.c,v 1.313 2025/02/04 16:07:46 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -1338,13 +1338,8 @@ ktable_postload(void)
if (kt->state == RECONF_DELETE) {
ktable_free(i - 1);
continue;
} else if (kt->state == RECONF_REINIT) {
if (kt->fib_sync != kt->fib_conf) {
kt->fib_sync = kt->fib_conf;
if (kt->fib_sync)
fetchtable(kt);
}
}
} else if (kt->state == RECONF_REINIT)
kt->fib_sync = kt->fib_conf;
/* cleanup old networks */
TAILQ_FOREACH_SAFE(n, &kt->krn, entry, xn) {

View file

@ -1,4 +1,4 @@
/* $OpenBSD: parse.y,v 1.478 2025/01/31 13:40:23 claudio Exp $ */
/* $OpenBSD: parse.y,v 1.479 2025/02/04 18:16:56 denis Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -267,7 +267,7 @@ typedef struct {
%token PREPEND_SELF PREPEND_PEER PFTABLE WEIGHT RTLABEL ORIGIN PRIORITY
%token ERROR INCLUDE
%token IPSEC ESP AH SPI IKE
%token IPV4 IPV6
%token IPV4 IPV6 EVPN
%token QUALIFY VIA
%token NE LE GE XRANGE LONGER MAXLEN MAX
%token <v.string> STRING
@ -1970,6 +1970,12 @@ peeropts : REMOTEAS as4number {
curpeer->conf.capabilities.mp[aid] = 1;
}
}
| ANNOUNCE EVPN enforce {
if ($3)
curpeer->conf.capabilities.mp[AID_EVPN] = 2;
else
curpeer->conf.capabilities.mp[AID_EVPN] = 1;
}
| ANNOUNCE REFRESH yesnoenforce {
curpeer->conf.capabilities.refresh = $3;
}
@ -3546,6 +3552,7 @@ lookup(char *s)
/* this has to be sorted always */
static const struct keywords keywords[] = {
{ "AS", AS },
{ "EVPN", EVPN },
{ "IPv4", IPV4 },
{ "IPv6", IPV6 },
{ "add-path", ADDPATH },

View file

@ -1,4 +1,4 @@
/* $OpenBSD: rde.c,v 1.650 2025/01/27 15:22:11 claudio Exp $ */
/* $OpenBSD: rde.c,v 1.651 2025/02/04 18:16:56 denis Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -1596,6 +1596,16 @@ rde_update_dispatch(struct rde_peer *peer, struct ibuf *buf)
goto done;
}
break;
case AID_EVPN:
if (nlri_get_evpn(&unreachbuf,
&prefix, &prefixlen) == -1) {
log_peer_warnx(&peer->conf,
"bad EVPN withdraw prefix");
rde_update_err(peer, ERR_UPDATE,
ERR_UPD_OPTATTR, &unreachbuf);
goto done;
}
break;
case AID_FLOWSPECv4:
case AID_FLOWSPECv6:
/* ignore flowspec for now */
@ -1790,6 +1800,16 @@ rde_update_dispatch(struct rde_peer *peer, struct ibuf *buf)
goto done;
}
break;
case AID_EVPN:
if (nlri_get_evpn(&reachbuf,
&prefix, &prefixlen) == -1) {
log_peer_warnx(&peer->conf,
"bad EVPN nlri prefix");
rde_update_err(peer, ERR_UPDATE,
ERR_UPD_OPTATTR, &reachbuf);
goto done;
}
break;
case AID_FLOWSPECv4:
case AID_FLOWSPECv6:
/* ignore flowspec for now */
@ -2517,6 +2537,36 @@ rde_get_mp_nexthop(struct ibuf *buf, uint8_t aid,
}
}
break;
case AID_EVPN:
switch (nhlen) {
case 4:
if (ibuf_get_h32(&nhbuf, &nexthop.v4.s_addr) == -1)
return (-1);
nexthop.aid = AID_INET;
break;
case 16:
case 32:
if (ibuf_get(&nhbuf, &nexthop.v6,
sizeof(nexthop.v6)) == -1)
return (-1);
nexthop.aid = AID_INET6;
if (IN6_IS_ADDR_LINKLOCAL(&nexthop.v6)) {
if (peer->local_if_scope != 0) {
nexthop.scope_id = peer->local_if_scope;
} else {
log_peer_warnx(&peer->conf,
"unexpected link-local nexthop: %s",
log_addr(&nexthop));
return (-1);
}
}
break;
default:
log_peer_warnx(&peer->conf, "bad %s nexthop, "
"bad size %d", aid2str(aid), nhlen);
return (-1);
}
break;
case AID_FLOWSPECv4:
case AID_FLOWSPECv6:
/* nexthop must be 0 and ignored for flowspec */

View file

@ -1,4 +1,4 @@
/* $OpenBSD: rde_prefix.c,v 1.56 2024/12/30 17:14:02 denis Exp $ */
/* $OpenBSD: rde_prefix.c,v 1.57 2025/02/04 18:16:56 denis Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@ -95,6 +95,26 @@ struct pt_entry_vpn6 {
uint8_t pad2;
};
struct pt_entry_evpn {
RB_ENTRY(pt_entry) pt_e;
uint8_t aid;
uint8_t prefixlen;
uint16_t len;
uint32_t refcnt;
uint64_t rd;
uint32_t ethtag;
uint8_t esi[ESI_ADDR_LEN];
uint8_t mac[ETHER_ADDR_LEN];
uint8_t labelstack[6];
uint8_t labellen;
uint8_t type;
uint8_t vpnaid;
union {
struct in_addr prefix4;
struct in6_addr prefix6;
};
};
struct pt_entry_flow {
RB_ENTRY(pt_entry) pt_e;
uint8_t aid;
@ -130,6 +150,7 @@ void
pt_getaddr(struct pt_entry *pte, struct bgpd_addr *addr)
{
struct pt_entry_flow *pflow;
struct pt_entry_evpn *evpn;
memset(addr, 0, sizeof(struct bgpd_addr));
addr->aid = pte->aid;
@ -157,6 +178,25 @@ pt_getaddr(struct pt_entry *pte, struct bgpd_addr *addr)
((struct pt_entry_vpn6 *)pte)->labelstack,
addr->labellen);
break;
case AID_EVPN:
evpn = (struct pt_entry_evpn *)pte;
addr->evpn.type = evpn->type;
addr->rd = evpn->rd;
addr->evpn.ethtag = evpn->ethtag;
addr->labellen = evpn->labellen;
addr->evpn.aid = evpn->vpnaid;
memcpy(addr->labelstack, evpn->labelstack, addr->labellen);
memcpy(addr->evpn.esi, evpn->esi, sizeof(evpn->esi));
memcpy(addr->evpn.mac, evpn->mac, sizeof(evpn->mac));
switch (evpn->vpnaid) {
case AID_INET:
addr->evpn.v4 = evpn->prefix4;
break;
case AID_INET6:
addr->evpn.v6 = evpn->prefix6;
break;
}
break;
case AID_FLOWSPECv4:
case AID_FLOWSPECv6:
pflow = (struct pt_entry_flow *)pte;
@ -192,6 +232,7 @@ pt_fill(struct bgpd_addr *prefix, int prefixlen)
static struct pt_entry6 pte6;
static struct pt_entry_vpn4 pte_vpn4;
static struct pt_entry_vpn6 pte_vpn6;
static struct pt_entry_evpn pte_evpn;
switch (prefix->aid) {
case AID_INET:
@ -242,6 +283,37 @@ pt_fill(struct bgpd_addr *prefix, int prefixlen)
memcpy(pte_vpn6.labelstack, prefix->labelstack,
prefix->labellen);
return ((struct pt_entry *)&pte_vpn6);
case AID_EVPN:
memset(&pte_evpn, 0, sizeof(pte_evpn));
pte_evpn.len = sizeof(pte_evpn);
pte_evpn.refcnt = UINT32_MAX;
switch (prefix->evpn.aid) {
case AID_UNSPEC:
/* See rfc7432 section 7.2 */
break;
case AID_INET:
pte_evpn.prefix4 = prefix->evpn.v4;
break;
case AID_INET6:
pte_evpn.prefix6 = prefix->evpn.v6;
break;
default:
fatalx("pt_fill: bad EVPN prefixlen");
}
pte_evpn.aid = prefix->aid;
pte_evpn.vpnaid = prefix->evpn.aid;
pte_evpn.prefixlen = prefixlen;
pte_evpn.type = prefix->evpn.type;
pte_evpn.rd = prefix->rd;
pte_evpn.ethtag = prefix->evpn.ethtag;
pte_evpn.labellen = prefix->labellen;
memcpy(pte_evpn.labelstack, prefix->labelstack,
pte_evpn.labellen);
memcpy(pte_evpn.esi, prefix->evpn.esi,
sizeof(prefix->evpn.esi));
memcpy(pte_evpn.mac, prefix->evpn.mac,
sizeof(prefix->evpn.mac));
return ((struct pt_entry *)&pte_evpn);
default:
fatalx("pt_fill: unknown af");
}
@ -357,6 +429,7 @@ pt_prefix_cmp(const struct pt_entry *a, const struct pt_entry *b)
const struct pt_entry_vpn4 *va4, *vb4;
const struct pt_entry_vpn6 *va6, *vb6;
const struct pt_entry_flow *af, *bf;
const struct pt_entry_evpn *ea, *eb;
int i;
if (a->aid > b->aid)
@ -425,6 +498,47 @@ pt_prefix_cmp(const struct pt_entry *a, const struct pt_entry *b)
if (va6->prefixlen < vb6->prefixlen)
return (-1);
return (0);
case AID_EVPN:
/* XXXX Need different comparator for different types */
ea = (const struct pt_entry_evpn *)a;
eb = (const struct pt_entry_evpn *)b;
if (ea->ethtag > eb->ethtag)
return (1);
if (ea->ethtag < eb->ethtag)
return (-1);
/* MAC length is always 48 */
i = memcmp(&ea->mac, &eb->mac, sizeof(ea->mac));
if (i > 0)
return (1);
if (i < 0)
return (-1);
if (ea->prefixlen > eb->prefixlen)
return (1);
if (ea->prefixlen < eb->prefixlen)
return (-1);
switch (ea->vpnaid) {
case AID_UNSPEC:
break;
case AID_INET:
i = memcmp(&ea->prefix4, &eb->prefix4,
sizeof(struct in_addr));
if (i > 0)
return (1);
if (i < 0)
return (-1);
break;
case AID_INET6:
i = memcmp(&ea->prefix6, &eb->prefix6,
sizeof(struct in6_addr));
if (i > 0)
return (1);
if (i < 0)
return (-1);
break;
default:
fatalx("pt_prefix_cmp: unknown evpn af %d", ea->vpnaid);
}
return (0);
case AID_FLOWSPECv4:
case AID_FLOWSPECv6:
af = (const struct pt_entry_flow *)a;
@ -433,7 +547,7 @@ pt_prefix_cmp(const struct pt_entry *a, const struct pt_entry *b)
bf->flow, bf->len - PT_FLOW_SIZE,
a->aid == AID_FLOWSPECv6);
default:
fatalx("pt_prefix_cmp: unknown af");
fatalx("pt_prefix_cmp: unknown af %d", a->aid);
}
return (-1);
}
@ -474,9 +588,10 @@ pt_writebuf(struct ibuf *buf, struct pt_entry *pte, int withdraw,
struct pt_entry_vpn4 *pvpn4 = (struct pt_entry_vpn4 *)pte;
struct pt_entry_vpn6 *pvpn6 = (struct pt_entry_vpn6 *)pte;
struct pt_entry_flow *pflow = (struct pt_entry_flow *)pte;
struct pt_entry_evpn *pevpn = (struct pt_entry_evpn *)pte;
struct ibuf *tmp;
int flowlen, psize;
uint8_t plen;
uint16_t plen;
if ((tmp = ibuf_dynamic(32, UINT16_MAX)) == NULL)
goto fail;
@ -549,6 +664,80 @@ pt_writebuf(struct ibuf *buf, struct pt_entry *pte, int withdraw,
ibuf_add(tmp, &pvpn6->prefix6, psize) == -1)
goto fail;
break;
case AID_EVPN:
if (ibuf_add_n8(tmp, pevpn->type) == -1)
goto fail;
switch (pevpn->type) {
case EVPN_ROUTE_TYPE_2:
plen = sizeof(pevpn->rd) * 8;
plen += sizeof(pevpn->esi) * 8;
plen += sizeof(pevpn->ethtag) * 8;
plen += 8; /* MAC length */
plen += sizeof(pevpn->mac) * 8;
plen += 8; /* IP length */
plen += pevpn->prefixlen;
plen += pevpn->labellen * 8;
if (ibuf_add_n8(tmp, PREFIX_SIZE(plen) - 1) == -1)
goto fail;
if (ibuf_add_h64(tmp, pevpn->rd) == -1 ||
ibuf_add(tmp, pevpn->esi,
sizeof(pevpn->esi)) == -1 ||
ibuf_add_h32(tmp, pevpn->ethtag) == -1)
goto fail;
if (ibuf_add_n8(tmp, sizeof(pevpn->mac) * 8) == -1 ||
ibuf_add(tmp, pevpn->mac, sizeof(pevpn->mac)) == -1)
goto fail;
if (ibuf_add_n8(tmp, pevpn->prefixlen) == -1)
goto fail;
switch(pevpn->vpnaid) {
case AID_UNSPEC:
/* See rfc7432 section 7.2 */
break;
case AID_INET:
if (ibuf_add(tmp, &pevpn->prefix4,
sizeof(pevpn->prefix4)) == -1)
goto fail;
break;
case AID_INET6:
if (ibuf_add(tmp, &pevpn->prefix6,
sizeof(pevpn->prefix6)) == -1)
goto fail;
break;
default:
goto fail;
}
if (ibuf_add(tmp, pevpn->labelstack,
pevpn->labellen) == -1)
goto fail;
break;
case EVPN_ROUTE_TYPE_3:
plen = sizeof(pevpn->rd) * 8;
plen += sizeof(pevpn->ethtag) * 8;
plen += 8; /* IP length */
plen += pevpn->prefixlen;
if (ibuf_add_n8(tmp, PREFIX_SIZE(plen) - 1) == -1)
goto fail;
if (ibuf_add_h64(tmp, pevpn->rd) == -1 ||
ibuf_add_h32(tmp, pevpn->ethtag) == -1)
goto fail;
if (ibuf_add_n8(tmp, pevpn->prefixlen) == -1)
goto fail;
switch(pevpn->vpnaid) {
case AID_INET:
if (ibuf_add(tmp, &pevpn->prefix4,
sizeof(pevpn->prefix4)) == -1)
goto fail;
break;
case AID_INET6:
if (ibuf_add(tmp, &pevpn->prefix6,
sizeof(pevpn->prefix6)) == -1)
goto fail;
break;
default:
goto fail;
}
}
break;
case AID_FLOWSPECv4:
case AID_FLOWSPECv6:
flowlen = pflow->len - PT_FLOW_SIZE;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: rde_update.c,v 1.174 2025/01/13 13:50:34 claudio Exp $ */
/* $OpenBSD: rde_update.c,v 1.175 2025/02/04 18:16:56 denis Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@ -478,6 +478,12 @@ up_get_nexthop(struct rde_peer *peer, struct filterstate *state, uint8_t aid)
if (peer->local_v6_addr.aid == AID_INET6)
peer_local = &peer->local_v6_addr;
break;
case AID_EVPN:
if (peer->local_v4_addr.aid == AID_INET)
peer_local = &peer->local_v4_addr;
else if (peer->local_v6_addr.aid == AID_INET6)
peer_local = &peer->local_v6_addr;
break;
case AID_FLOWSPECv4:
case AID_FLOWSPECv6:
/* flowspec has no nexthop */
@ -946,6 +952,24 @@ up_generate_mp_reach(struct ibuf *buf, struct rde_peer *peer,
if (ibuf_add(buf, &nexthop->v6, sizeof(nexthop->v6)) == -1)
return -1;
break;
case AID_EVPN:
if (nh == NULL)
return -1;
nexthop = &nh->exit_nexthop;
if (nexthop->aid == AID_INET) {
if (ibuf_add(buf, &nexthop->v4,
sizeof(nexthop->v4)) == -1)
return -1;
break;
} else if (nexthop->aid == AID_INET6) {
if (ibuf_add(buf, &nexthop->v6,
sizeof(nexthop->v6)) == -1)
return -1;
} else {
/* can't encode nexthop, give up and withdraw prefix */
return -1;
}
break;
case AID_FLOWSPECv4:
case AID_FLOWSPECv6:
/* no NH */

View file

@ -1,4 +1,4 @@
/* $OpenBSD: util.c,v 1.92 2025/01/27 15:22:11 claudio Exp $ */
/* $OpenBSD: util.c,v 1.93 2025/02/04 18:16:56 denis Exp $ */
/*
* Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
@ -49,10 +49,78 @@ log_addr(const struct bgpd_addr *addr)
snprintf(buf, sizeof(buf), "%s %s", log_rd(addr->rd),
log_sockaddr(sa, len));
return (buf);
case AID_EVPN:
return log_evpnaddr(addr, sa, len);
break;
}
return ("???");
}
static const char *
log_mac(const uint8_t mac[ETHER_ADDR_LEN])
{
static char buf[18];
snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x", mac[0],
mac[1], mac[2], mac[3], mac[4], mac[5]);
return (buf);
}
static const uint8_t zero_esi[ESI_ADDR_LEN];
static const char *
log_esi(const uint8_t esi[ESI_ADDR_LEN])
{
static char buf[30];
if (memcmp(esi, zero_esi, sizeof(zero_esi)) == 0)
return ("");
snprintf(buf, sizeof(buf),
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", esi[0],
esi[1], esi[2], esi[3], esi[4], esi[5], esi[6], esi[7], esi[8],
esi[9]);
return (buf);
}
const char *
log_evpnaddr(const struct bgpd_addr *addr, struct sockaddr *sa,
socklen_t salen)
{
static char buf[138];
uint32_t vni;
uint8_t len;
switch(addr->evpn.type) {
case EVPN_ROUTE_TYPE_2:
memcpy(&vni, addr->labelstack, addr->labellen);
snprintf(buf, sizeof(buf), "[2]:[%s]:[%s]:[%d]:[48]:[%s]",
log_rd(addr->rd),log_esi(addr->evpn.esi), htonl(vni)>>8,
log_mac(addr->evpn.mac));
if (sa != NULL) {
len = strlen(buf);
snprintf(buf+len, sizeof(buf)-len, ":[%d]:[%s]",
sa->sa_family == AF_INET ? 32 : 128,
log_sockaddr(sa, salen));
}
break;
case EVPN_ROUTE_TYPE_3:
if (sa != NULL) {
memcpy(&vni, addr->labelstack, addr->labellen);
snprintf(buf, sizeof(buf), "[3]:[%s]:[%d]:[%s]",
log_rd(addr->rd),
sa->sa_family == AF_INET ? 32 : 128,
log_sockaddr(sa, salen));
}
break;
default:
break;
}
return (buf);
}
const char *
log_in6addr(const struct in6_addr *addr)
{
@ -818,6 +886,108 @@ nlri_get_vpn6(struct ibuf *buf, struct bgpd_addr *prefix,
return (0);
}
int
nlri_get_evpn(struct ibuf *buf, struct bgpd_addr *prefix,
uint8_t *prefixlen)
{
struct ibuf evpnbuf;
uint8_t nlrilen, type, pfxlen = 0, maclen = 0;
if (ibuf_get_n8(buf, &type) == -1)
return (-1);
if (ibuf_get_n8(buf, &nlrilen) == -1)
return (-1);
memset(prefix, 0, sizeof(struct bgpd_addr));
prefix->aid = AID_EVPN;
switch (type) {
case EVPN_ROUTE_TYPE_2:
if (ibuf_get_ibuf(buf, nlrilen, &evpnbuf) == -1)
return (-1);
prefix->evpn.type = EVPN_ROUTE_TYPE_2;
/* RD */
if (ibuf_get_h64(&evpnbuf, &prefix->rd) == -1)
return (-1);
/* ESI */
if (ibuf_get(&evpnbuf, &prefix->evpn.esi,
sizeof(prefix->evpn.esi)) == -1)
return (-1);
/* Ethernet Tag */
if (ibuf_get_h32(&evpnbuf, &prefix->evpn.ethtag) == -1)
return (-1);
/* MAC length */
if (ibuf_get_n8(&evpnbuf, &maclen) == -1)
return (-1);
if (maclen != 48)
return (-1);
/* MAC address */
if (ibuf_get(&evpnbuf, &prefix->evpn.mac,
sizeof(prefix->evpn.mac)) == -1)
return (-1);
/* Prefix length */
if (ibuf_get_n8(&evpnbuf, &pfxlen) == -1)
return (-1);
/* Destination */
if (pfxlen == 0) {
/* nothing */
} else if (pfxlen == 32) {
prefix->evpn.aid = AID_INET;
if (ibuf_get(&evpnbuf, &prefix->evpn.v4,
sizeof(prefix->evpn.v4)) == -1)
return (-1);
} else if (pfxlen == 128) {
prefix->evpn.aid = AID_INET6;
if (ibuf_get(&evpnbuf, &prefix->evpn.v6,
sizeof(prefix->evpn.v6)) == -1)
return (-1);
} else
return (-1);
/* VNI */
if (ibuf_size(&evpnbuf) != 3 && ibuf_size(&evpnbuf) != 6)
return (-1);
prefix->labellen = ibuf_size(&evpnbuf);
if (ibuf_get(&evpnbuf, prefix->labelstack,
prefix->labellen) == -1)
return (-1);
break;
case EVPN_ROUTE_TYPE_3:
if (ibuf_get_ibuf(buf, nlrilen, &evpnbuf) == -1)
return (-1);
prefix->evpn.type = EVPN_ROUTE_TYPE_3;
/* RD */
if (ibuf_get_h64(&evpnbuf, &prefix->rd) == -1)
return (-1);
/* Ethernet Tag */
if (ibuf_get_h32(&evpnbuf, &prefix->evpn.ethtag) == -1)
return (-1);
/* Prefix length */
if (ibuf_get_n8(&evpnbuf, &pfxlen) == -1)
return (-1);
/* Destination */
if (pfxlen == 32) {
prefix->evpn.aid = AID_INET;
if (ibuf_get(&evpnbuf, &prefix->evpn.v4,
sizeof(prefix->evpn.v4)) == -1)
return (-1);
} else if (pfxlen == 128) {
prefix->evpn.aid = AID_INET6;
if (ibuf_get(&evpnbuf, &prefix->evpn.v6,
sizeof(prefix->evpn.v6)) == -1)
return (-1);
} else
return (-1);
if (ibuf_size(&evpnbuf) != 0)
return (-1);
break;
default:
return (-1);
}
*prefixlen = pfxlen;
return (0);
}
static in_addr_t
prefixlen2mask(uint8_t prefixlen)
{
@ -1003,6 +1173,26 @@ af2aid(sa_family_t af, uint8_t safi, uint8_t *aid)
return (-1);
}
static socklen_t
addr2sa_in6(struct sockaddr_in6 *sin6, struct in6_addr in6, uint16_t port,
uint32_t scope_id)
{
sin6->sin6_family = AF_INET6;
memcpy(&sin6->sin6_addr, &in6, sizeof(sin6->sin6_addr));
sin6->sin6_port = htons(port);
sin6->sin6_scope_id = scope_id;
return (sizeof(struct sockaddr_in6));
}
static socklen_t
addr2sa_in(struct sockaddr_in *sin, struct in_addr in, uint16_t port)
{
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = in.s_addr;
sin->sin_port = htons(port);
return (sizeof(struct sockaddr_in));
}
/*
* Convert a struct bgpd_addr into a struct sockaddr. For VPN addresses
* the included label stack is ignored and needs to be handled by the caller.
@ -1021,22 +1211,26 @@ addr2sa(const struct bgpd_addr *addr, uint16_t port, socklen_t *len)
switch (addr->aid) {
case AID_INET:
case AID_VPN_IPv4:
sa_in->sin_family = AF_INET;
sa_in->sin_addr.s_addr = addr->v4.s_addr;
sa_in->sin_port = htons(port);
*len = sizeof(struct sockaddr_in);
*len = addr2sa_in(sa_in, addr->v4, port);
break;
case AID_INET6:
case AID_VPN_IPv6:
sa_in6->sin6_family = AF_INET6;
memcpy(&sa_in6->sin6_addr, &addr->v6,
sizeof(sa_in6->sin6_addr));
sa_in6->sin6_port = htons(port);
sa_in6->sin6_scope_id = addr->scope_id;
*len = sizeof(struct sockaddr_in6);
*len = addr2sa_in6(sa_in6, addr->v6, port, addr->scope_id);
break;
case AID_EVPN:
if (addr->evpn.aid == AID_INET)
*len = addr2sa_in(sa_in, addr->evpn.v4, port);
else if (addr->evpn.aid == AID_INET6)
*len = addr2sa_in6(sa_in6, addr->evpn.v6, port,
addr->scope_id);
else {
*len = 0;
return (NULL);
}
break;
case AID_FLOWSPECv4:
case AID_FLOWSPECv6:
default:
return (NULL);
}