sync with OpenBSD -current

This commit is contained in:
purplerain 2024-01-25 20:43:37 +00:00
parent 125fcc4eee
commit df63e3891f
Signed by: purplerain
GPG Key ID: F42C07F07E2E35B7
24 changed files with 3451 additions and 650 deletions

View File

@ -1,4 +1,4 @@
/* $OpenBSD: crypto_init.c,v 1.17 2024/01/13 17:04:29 tb Exp $ */ /* $OpenBSD: crypto_init.c,v 1.18 2024/01/25 12:22:31 tb Exp $ */
/* /*
* Copyright (c) 2018 Bob Beck <beck@openbsd.org> * Copyright (c) 2018 Bob Beck <beck@openbsd.org>
* *
@ -81,7 +81,6 @@ OPENSSL_cleanup(void)
CRYPTO_cleanup_all_ex_data(); CRYPTO_cleanup_all_ex_data();
EVP_cleanup(); EVP_cleanup();
X509V3_EXT_cleanup();
X509_VERIFY_PARAM_table_cleanup(); X509_VERIFY_PARAM_table_cleanup();
x509_issuer_cache_free(); x509_issuer_cache_free();

View File

@ -1,4 +1,4 @@
/* $OpenBSD: p12_add.c,v 1.22 2023/02/16 08:38:17 tb Exp $ */ /* $OpenBSD: p12_add.c,v 1.23 2024/01/25 13:44:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999. * project 1999.
*/ */
@ -124,11 +124,15 @@ LCRYPTO_ALIAS(PKCS12_pack_p7data);
STACK_OF(PKCS12_SAFEBAG) * STACK_OF(PKCS12_SAFEBAG) *
PKCS12_unpack_p7data(PKCS7 *p7) PKCS12_unpack_p7data(PKCS7 *p7)
{ {
ASN1_OCTET_STRING *aos;
if (!PKCS7_type_is_data(p7)) { if (!PKCS7_type_is_data(p7)) {
PKCS12error(PKCS12_R_CONTENT_TYPE_NOT_DATA); PKCS12error(PKCS12_R_CONTENT_TYPE_NOT_DATA);
return NULL; return NULL;
} }
return ASN1_item_unpack(p7->d.data, &PKCS12_SAFEBAGS_it); if ((aos = PKCS7_get_octet_string(p7)) == NULL)
return NULL;
return ASN1_item_unpack(aos, &PKCS12_SAFEBAGS_it);
} }
LCRYPTO_ALIAS(PKCS12_unpack_p7data); LCRYPTO_ALIAS(PKCS12_unpack_p7data);
@ -182,11 +186,16 @@ LCRYPTO_ALIAS(PKCS12_pack_p7encdata);
STACK_OF(PKCS12_SAFEBAG) * STACK_OF(PKCS12_SAFEBAG) *
PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, int passlen) PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, int passlen)
{ {
PKCS7_ENC_CONTENT *content;
if (!PKCS7_type_is_encrypted(p7)) if (!PKCS7_type_is_encrypted(p7))
return NULL; return NULL;
return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm, if (p7->d.encrypted == NULL)
&PKCS12_SAFEBAGS_it, pass, passlen, return NULL;
p7->d.encrypted->enc_data->enc_data, 1); if ((content = p7->d.encrypted->enc_data) == NULL)
return NULL;
return PKCS12_item_decrypt_d2i(content->algorithm, &PKCS12_SAFEBAGS_it,
pass, passlen, content->enc_data, 1);
} }
LCRYPTO_ALIAS(PKCS12_unpack_p7encdata); LCRYPTO_ALIAS(PKCS12_unpack_p7encdata);
@ -210,11 +219,14 @@ LCRYPTO_ALIAS(PKCS12_pack_authsafes);
STACK_OF(PKCS7) * STACK_OF(PKCS7) *
PKCS12_unpack_authsafes(const PKCS12 *p12) PKCS12_unpack_authsafes(const PKCS12 *p12)
{ {
ASN1_OCTET_STRING *aos;
if (!PKCS7_type_is_data(p12->authsafes)) { if (!PKCS7_type_is_data(p12->authsafes)) {
PKCS12error(PKCS12_R_CONTENT_TYPE_NOT_DATA); PKCS12error(PKCS12_R_CONTENT_TYPE_NOT_DATA);
return NULL; return NULL;
} }
return ASN1_item_unpack(p12->authsafes->d.data, if ((aos = PKCS7_get_octet_string(p12->authsafes)) == NULL)
&PKCS12_AUTHSAFES_it); return NULL;
return ASN1_item_unpack(aos, &PKCS12_AUTHSAFES_it);
} }
LCRYPTO_ALIAS(PKCS12_unpack_authsafes); LCRYPTO_ALIAS(PKCS12_unpack_authsafes);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: p12_mutl.c,v 1.35 2023/02/16 08:38:17 tb Exp $ */ /* $OpenBSD: p12_mutl.c,v 1.36 2024/01/25 13:44:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999. * project 1999.
*/ */
@ -115,6 +115,7 @@ PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
{ {
const EVP_MD *md_type; const EVP_MD *md_type;
HMAC_CTX *hmac = NULL; HMAC_CTX *hmac = NULL;
ASN1_OCTET_STRING *aos;
unsigned char key[EVP_MAX_MD_SIZE], *salt; unsigned char key[EVP_MAX_MD_SIZE], *salt;
int saltlen, iter; int saltlen, iter;
int md_size; int md_size;
@ -124,6 +125,10 @@ PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
PKCS12error(PKCS12_R_CONTENT_TYPE_NOT_DATA); PKCS12error(PKCS12_R_CONTENT_TYPE_NOT_DATA);
goto err; goto err;
} }
if ((aos = PKCS7_get_octet_string(p12->authsafes)) == NULL) {
PKCS12error(PKCS12_R_DECODE_ERROR);
goto err;
}
salt = p12->mac->salt->data; salt = p12->mac->salt->data;
saltlen = p12->mac->salt->length; saltlen = p12->mac->salt->length;
@ -155,8 +160,7 @@ PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
goto err; goto err;
if (!HMAC_Init_ex(hmac, key, md_size, md_type, NULL)) if (!HMAC_Init_ex(hmac, key, md_size, md_type, NULL))
goto err; goto err;
if (!HMAC_Update(hmac, p12->authsafes->d.data->data, if (!HMAC_Update(hmac, aos->data, aos->length))
p12->authsafes->d.data->length))
goto err; goto err;
if (!HMAC_Final(hmac, mac, maclen)) if (!HMAC_Final(hmac, mac, maclen))
goto err; goto err;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: p12_npas.c,v 1.18 2023/02/16 08:38:17 tb Exp $ */ /* $OpenBSD: p12_npas.c,v 1.27 2024/01/25 15:33:35 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999. * project 1999.
*/ */
@ -68,130 +68,68 @@
/* PKCS#12 password change routine */ /* PKCS#12 password change routine */
static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass);
static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass,
const char *newpass);
static int newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass,
const char *newpass);
static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen);
/*
* Change the password on a PKCS#12 structure.
*/
int
PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass)
{
/* Check for NULL PKCS12 structure */
if (!p12) {
PKCS12error(PKCS12_R_INVALID_NULL_PKCS12_POINTER);
return 0;
}
/* Check the mac */
if (!PKCS12_verify_mac(p12, oldpass, -1)) {
PKCS12error(PKCS12_R_MAC_VERIFY_FAILURE);
return 0;
}
if (!newpass_p12(p12, oldpass, newpass)) {
PKCS12error(PKCS12_R_PARSE_ERROR);
return 0;
}
return 1;
}
LCRYPTO_ALIAS(PKCS12_newpass);
/* Parse the outer PKCS#12 structure */
static int static int
newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass) alg_get(X509_ALGOR *alg, int *nid, int *iter, int *salt_len)
{ {
STACK_OF(PKCS7) *asafes, *newsafes; const ASN1_OBJECT *aobj;
STACK_OF(PKCS12_SAFEBAG) *bags; int param_type;
int i, bagnid, pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0; const void *param;
PKCS7 *p7, *p7new; PBEPARAM *pbe = NULL;
ASN1_OCTET_STRING *p12_data_tmp = NULL, *macnew = NULL; int ret = 0;
unsigned char mac[EVP_MAX_MD_SIZE];
unsigned int maclen;
if (!(asafes = PKCS12_unpack_authsafes(p12))) *nid = *iter = *salt_len = 0;
return 0;
if (!(newsafes = sk_PKCS7_new_null())) X509_ALGOR_get0(&aobj, &param_type, &param, alg);
return 0; if (param_type != V_ASN1_SEQUENCE)
for (i = 0; i < sk_PKCS7_num(asafes); i++) {
p7 = sk_PKCS7_value(asafes, i);
bagnid = OBJ_obj2nid(p7->type);
if (bagnid == NID_pkcs7_data) {
bags = PKCS12_unpack_p7data(p7);
} else if (bagnid == NID_pkcs7_encrypted) {
bags = PKCS12_unpack_p7encdata(p7, oldpass, -1);
if (!alg_get(p7->d.encrypted->enc_data->algorithm,
&pbe_nid, &pbe_iter, &pbe_saltlen)) {
sk_PKCS12_SAFEBAG_pop_free(bags,
PKCS12_SAFEBAG_free);
bags = NULL;
}
} else
continue;
if (bags == NULL)
goto err; goto err;
if (!newpass_bags(bags, oldpass, newpass)) { if ((pbe = ASN1_item_unpack(param, &PBEPARAM_it)) == NULL)
sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
goto err; goto err;
}
/* Repack bag in same form with new password */
if (bagnid == NID_pkcs7_data)
p7new = PKCS12_pack_p7data(bags);
else
p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1,
NULL, pbe_saltlen, pbe_iter, bags);
sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
if (p7new == NULL)
goto err;
if (sk_PKCS7_push(newsafes, p7new) == 0)
goto err;
}
sk_PKCS7_pop_free(asafes, PKCS7_free);
/* Repack safe: save old safe in case of error */ /* XXX - can we validate these somehow? */
*nid = OBJ_obj2nid(alg->algorithm);
*iter = ASN1_INTEGER_get(pbe->iter);
*salt_len = pbe->salt->length;
p12_data_tmp = p12->authsafes->d.data; ret = 1;
if (!(p12->authsafes->d.data = ASN1_OCTET_STRING_new())) {
p12->authsafes->d.data = p12_data_tmp;
goto err;
}
if (!PKCS12_pack_authsafes(p12, newsafes))
goto saferr;
if (!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen)) err:
goto saferr; PBEPARAM_free(pbe);
if (!(macnew = ASN1_OCTET_STRING_new()))
goto saferr;
if (!ASN1_OCTET_STRING_set(macnew, mac, maclen))
goto saferr;
ASN1_OCTET_STRING_free(p12->mac->dinfo->digest);
p12->mac->dinfo->digest = macnew;
ASN1_OCTET_STRING_free(p12_data_tmp);
return 1; return ret;
saferr:
/* Restore old safe */
ASN1_OCTET_STRING_free(p12->authsafes->d.data);
ASN1_OCTET_STRING_free(macnew);
p12->authsafes->d.data = p12_data_tmp;
return 0;
err:
sk_PKCS7_pop_free(asafes, PKCS7_free);
sk_PKCS7_pop_free(newsafes, PKCS7_free);
return 0;
} }
/* Change password of safebag: only needs handle shrouded keybags */
static int
newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass, const char *newpass)
{
PKCS8_PRIV_KEY_INFO *p8 = NULL;
X509_SIG *keybag;
int nid, salt_len, iter;
int ret = 0;
if (OBJ_obj2nid(bag->type) != NID_pkcs8ShroudedKeyBag)
goto done;
if ((p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1)) == NULL)
goto err;
if (!alg_get(bag->value.shkeybag->algor, &nid, &iter, &salt_len))
goto err;
if ((keybag = PKCS8_encrypt(nid, NULL, newpass, -1, NULL, salt_len,
iter, p8)) == NULL)
goto err;
X509_SIG_free(bag->value.shkeybag);
bag->value.shkeybag = keybag;
done:
ret = 1;
err:
PKCS8_PRIV_KEY_INFO_free(p8);
return ret;
}
static int static int
newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass, newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass,
@ -200,50 +138,163 @@ newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass,
int i; int i;
for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
if (!newpass_bag(sk_PKCS12_SAFEBAG_value(bags, i), PKCS12_SAFEBAG *bag = sk_PKCS12_SAFEBAG_value(bags, i);
oldpass, newpass))
if (!newpass_bag(bag, oldpass, newpass))
return 0; return 0;
} }
return 1;
}
/* Change password of safebag: only needs handle shrouded keybags */
static int
newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass, const char *newpass)
{
PKCS8_PRIV_KEY_INFO *p8;
X509_SIG *p8new;
int p8_nid, p8_saltlen, p8_iter;
if (OBJ_obj2nid(bag->type) != NID_pkcs8ShroudedKeyBag)
return 1;
if (!(p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1)))
return 0;
if (!alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter,
&p8_saltlen))
return 0;
if (!(p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen,
p8_iter, p8))) return 0;
X509_SIG_free(bag->value.shkeybag);
bag->value.shkeybag = p8new;
return 1; return 1;
} }
static int static int
alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen) pkcs7_repack_data(PKCS7 *pkcs7, STACK_OF(PKCS7) *safes, const char *oldpass,
const char *newpass)
{ {
PBEPARAM *pbe; STACK_OF(PKCS12_SAFEBAG) *bags;
const unsigned char *p; PKCS7 *data = NULL;
int ret = 0;
p = alg->parameter->value.sequence->data; if ((bags = PKCS12_unpack_p7data(pkcs7)) == NULL)
pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length); goto err;
if (!pbe) if (!newpass_bags(bags, oldpass, newpass))
return 0; goto err;
*pnid = OBJ_obj2nid(alg->algorithm); if ((data = PKCS12_pack_p7data(bags)) == NULL)
*piter = ASN1_INTEGER_get(pbe->iter); goto err;
*psaltlen = pbe->salt->length; if (sk_PKCS7_push(safes, data) == 0)
PBEPARAM_free(pbe); goto err;
return 1; data = NULL;
ret = 1;
err:
sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
PKCS7_free(data);
return ret;
} }
static int
pkcs7_repack_encdata(PKCS7 *pkcs7, STACK_OF(PKCS7) *safes, const char *oldpass,
const char *newpass)
{
STACK_OF(PKCS12_SAFEBAG) *bags;
int nid, iter, salt_len;
PKCS7 *data = NULL;
int ret = 0;
if ((bags = PKCS12_unpack_p7encdata(pkcs7, oldpass, -1)) == NULL)
goto err;
if (!alg_get(pkcs7->d.encrypted->enc_data->algorithm, &nid,
&iter, &salt_len))
goto err;
if (!newpass_bags(bags, oldpass, newpass))
goto err;
if ((data = PKCS12_pack_p7encdata(nid, newpass, -1, NULL, salt_len,
iter, bags)) == NULL)
goto err;
if (!sk_PKCS7_push(safes, data))
goto err;
data = NULL;
ret = 1;
err:
sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
PKCS7_free(data);
return ret;
}
static int
pkcs12_repack_authsafes(PKCS12 *pkcs12, STACK_OF(PKCS7) *safes,
const char *newpass)
{
ASN1_OCTET_STRING *old_data;
ASN1_OCTET_STRING *new_mac = NULL;
unsigned char mac[EVP_MAX_MD_SIZE];
unsigned int mac_len;
int ret = 0;
if ((old_data = pkcs12->authsafes->d.data) == NULL)
goto err;
if ((pkcs12->authsafes->d.data = ASN1_OCTET_STRING_new()) == NULL)
goto err;
if (!PKCS12_pack_authsafes(pkcs12, safes))
goto err;
if (!PKCS12_gen_mac(pkcs12, newpass, -1, mac, &mac_len))
goto err;
if ((new_mac = ASN1_OCTET_STRING_new()) == NULL)
goto err;
if (!ASN1_OCTET_STRING_set(new_mac, mac, mac_len))
goto err;
ASN1_OCTET_STRING_free(pkcs12->mac->dinfo->digest);
pkcs12->mac->dinfo->digest = new_mac;
new_mac = NULL;
ASN1_OCTET_STRING_free(old_data);
old_data = NULL;
ret = 1;
err:
if (old_data != NULL) {
ASN1_OCTET_STRING_free(pkcs12->authsafes->d.data);
pkcs12->authsafes->d.data = old_data;
}
explicit_bzero(mac, sizeof(mac));
ASN1_OCTET_STRING_free(new_mac);
return ret;
}
int
PKCS12_newpass(PKCS12 *pkcs12, const char *oldpass, const char *newpass)
{
STACK_OF(PKCS7) *authsafes = NULL, *safes = NULL;
int i;
int ret = 0;
if (pkcs12 == NULL) {
PKCS12error(PKCS12_R_INVALID_NULL_PKCS12_POINTER);
goto err;
}
if (!PKCS12_verify_mac(pkcs12, oldpass, -1)) {
PKCS12error(PKCS12_R_MAC_VERIFY_FAILURE);
goto err;
}
if ((authsafes = PKCS12_unpack_authsafes(pkcs12)) == NULL)
goto err;
if ((safes = sk_PKCS7_new_null()) == NULL)
goto err;
for (i = 0; i < sk_PKCS7_num(authsafes); i++) {
PKCS7 *pkcs7 = sk_PKCS7_value(authsafes, i);
switch (OBJ_obj2nid(pkcs7->type)) {
case NID_pkcs7_data:
if (pkcs7_repack_data(pkcs7, safes, oldpass, newpass))
goto err;
break;
case NID_pkcs7_encrypted:
if (pkcs7_repack_encdata(pkcs7, safes, oldpass, newpass))
goto err;
break;
}
}
if (!pkcs12_repack_authsafes(pkcs12, safes, newpass))
goto err;
ret = 1;
err:
sk_PKCS7_pop_free(authsafes, PKCS7_free);
sk_PKCS7_pop_free(safes, PKCS7_free);
return ret;
}
LCRYPTO_ALIAS(PKCS12_newpass);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: pkcs12_local.h,v 1.3 2022/11/26 17:23:18 tb Exp $ */ /* $OpenBSD: pkcs12_local.h,v 1.4 2024/01/25 13:44:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999. * project 1999.
*/ */
@ -96,6 +96,9 @@ struct pkcs12_bag_st {
} value; } value;
}; };
/* XXX - should go into pkcs7_local.h. */
ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7);
__END_HIDDEN_DECLS __END_HIDDEN_DECLS
#endif /* !HEADER_PKCS12_LOCAL_H */ #endif /* !HEADER_PKCS12_LOCAL_H */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: pk7_doit.c,v 1.54 2023/11/15 00:55:43 tb Exp $ */ /* $OpenBSD: pk7_doit.c,v 1.55 2024/01/25 13:44:08 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved. * All rights reserved.
* *
@ -92,7 +92,7 @@ PKCS7_type_is_other(PKCS7* p7)
} }
static ASN1_OCTET_STRING * ASN1_OCTET_STRING *
PKCS7_get_octet_string(PKCS7 *p7) PKCS7_get_octet_string(PKCS7 *p7)
{ {
if (PKCS7_type_is_data(p7)) if (PKCS7_type_is_data(p7))

View File

@ -1,4 +1,4 @@
/* $OpenBSD: pk7_mime.c,v 1.19 2023/05/02 09:56:12 tb Exp $ */ /* $OpenBSD: pk7_mime.c,v 1.20 2024/01/25 13:44:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project. * project.
*/ */
@ -89,8 +89,11 @@ SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
STACK_OF(X509_ALGOR) *mdalgs = NULL; STACK_OF(X509_ALGOR) *mdalgs = NULL;
int ctype_nid; int ctype_nid;
if ((ctype_nid = OBJ_obj2nid(p7->type)) == NID_pkcs7_signed) if ((ctype_nid = OBJ_obj2nid(p7->type)) == NID_pkcs7_signed) {
if (p7->d.sign == NULL)
return 0;
mdalgs = p7->d.sign->md_algs; mdalgs = p7->d.sign->md_algs;
}
flags ^= SMIME_OLDMIME; flags ^= SMIME_OLDMIME;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: x509_lib.c,v 1.14 2023/04/25 10:56:58 tb Exp $ */ /* $OpenBSD: x509_lib.c,v 1.16 2024/01/25 15:09:22 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999. * project 1999.
*/ */
@ -65,8 +65,6 @@
#include "x509_local.h" #include "x509_local.h"
static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL;
extern const X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku; extern const X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku;
extern const X509V3_EXT_METHOD v3_pkey_usage_period, v3_info, v3_sinfo; extern const X509V3_EXT_METHOD v3_pkey_usage_period, v3_info, v3_sinfo;
extern const X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id; extern const X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id;
@ -80,10 +78,6 @@ extern const X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp;
extern const X509V3_EXT_METHOD v3_addr, v3_asid; extern const X509V3_EXT_METHOD v3_addr, v3_asid;
extern const X509V3_EXT_METHOD v3_ct_scts[3]; extern const X509V3_EXT_METHOD v3_ct_scts[3];
/*
* This table needs to be sorted by increasing ext_nid values for OBJ_bsearch_.
*/
static const X509V3_EXT_METHOD *standard_exts[] = { static const X509V3_EXT_METHOD *standard_exts[] = {
&v3_nscert, &v3_nscert,
&v3_ns_ia5_list[0], &v3_ns_ia5_list[0],
@ -142,62 +136,17 @@ static const X509V3_EXT_METHOD *standard_exts[] = {
#define STANDARD_EXTENSION_COUNT (sizeof(standard_exts) / sizeof(standard_exts[0])) #define STANDARD_EXTENSION_COUNT (sizeof(standard_exts) / sizeof(standard_exts[0]))
static int
ext_cmp(const X509V3_EXT_METHOD * const *a, const X509V3_EXT_METHOD * const *b)
{
return ((*a)->ext_nid - (*b)->ext_nid);
}
int
X509V3_EXT_add(X509V3_EXT_METHOD *ext)
{
if (!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_cmp))) {
X509V3error(ERR_R_MALLOC_FAILURE);
return 0;
}
if (!sk_X509V3_EXT_METHOD_push(ext_list, ext)) {
X509V3error(ERR_R_MALLOC_FAILURE);
return 0;
}
return 1;
}
LCRYPTO_ALIAS(X509V3_EXT_add);
static int
ext_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)
{
const X509V3_EXT_METHOD * const *a = a_;
const X509V3_EXT_METHOD * const *b = b_;
return ext_cmp(a, b);
}
static const X509V3_EXT_METHOD **
OBJ_bsearch_ext(const X509V3_EXT_METHOD **key,
const X509V3_EXT_METHOD *const *base, int num)
{
return (const X509V3_EXT_METHOD **)OBJ_bsearch_(key, base, num,
sizeof(const X509V3_EXT_METHOD *), ext_cmp_BSEARCH_CMP_FN);
}
const X509V3_EXT_METHOD * const X509V3_EXT_METHOD *
X509V3_EXT_get_nid(int nid) X509V3_EXT_get_nid(int nid)
{ {
X509V3_EXT_METHOD tmp; size_t i;
const X509V3_EXT_METHOD *t = &tmp, * const *ret;
int idx; for (i = 0; i < STANDARD_EXTENSION_COUNT; i++) {
if (standard_exts[i]->ext_nid == nid)
return standard_exts[i];
}
if (nid < 0)
return NULL; return NULL;
tmp.ext_nid = nid;
ret = OBJ_bsearch_ext(&t, standard_exts, STANDARD_EXTENSION_COUNT);
if (ret)
return *ret;
if (!ext_list)
return NULL;
idx = sk_X509V3_EXT_METHOD_find(ext_list, &tmp);
if (idx == -1)
return NULL;
return sk_X509V3_EXT_METHOD_value(ext_list, idx);
} }
LCRYPTO_ALIAS(X509V3_EXT_get_nid); LCRYPTO_ALIAS(X509V3_EXT_get_nid);
@ -212,56 +161,6 @@ X509V3_EXT_get(X509_EXTENSION *ext)
} }
LCRYPTO_ALIAS(X509V3_EXT_get); LCRYPTO_ALIAS(X509V3_EXT_get);
int
X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist)
{
for (; extlist->ext_nid!=-1; extlist++)
if (!X509V3_EXT_add(extlist))
return 0;
return 1;
}
LCRYPTO_ALIAS(X509V3_EXT_add_list);
int
X509V3_EXT_add_alias(int nid_to, int nid_from)
{
const X509V3_EXT_METHOD *ext;
X509V3_EXT_METHOD *tmpext;
if (!(ext = X509V3_EXT_get_nid(nid_from))) {
X509V3error(X509V3_R_EXTENSION_NOT_FOUND);
return 0;
}
if (!(tmpext = malloc(sizeof(X509V3_EXT_METHOD)))) {
X509V3error(ERR_R_MALLOC_FAILURE);
return 0;
}
*tmpext = *ext;
tmpext->ext_nid = nid_to;
tmpext->ext_flags |= X509V3_EXT_DYNAMIC;
if (!X509V3_EXT_add(tmpext)) {
free(tmpext);
return 0;
}
return 1;
}
LCRYPTO_ALIAS(X509V3_EXT_add_alias);
static void
ext_list_free(X509V3_EXT_METHOD *ext)
{
if (ext->ext_flags & X509V3_EXT_DYNAMIC)
free(ext);
}
void
X509V3_EXT_cleanup(void)
{
sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free);
ext_list = NULL;
}
LCRYPTO_ALIAS(X509V3_EXT_cleanup);
int int
X509V3_add_standard_extensions(void) X509V3_add_standard_extensions(void)
{ {
@ -434,3 +333,37 @@ err:
return 0; return 0;
} }
LCRYPTO_ALIAS(X509V3_add1_i2d); LCRYPTO_ALIAS(X509V3_add1_i2d);
/*
* XXX - remove all the functions below in the next major bump.
*/
int
X509V3_EXT_add(X509V3_EXT_METHOD *ext)
{
X509V3error(ERR_R_DISABLED);
return 0;
}
LCRYPTO_ALIAS(X509V3_EXT_add);
int
X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist)
{
X509V3error(ERR_R_DISABLED);
return 0;
}
LCRYPTO_ALIAS(X509V3_EXT_add_list);
int
X509V3_EXT_add_alias(int nid_to, int nid_from)
{
X509V3error(ERR_R_DISABLED);
return 0;
}
LCRYPTO_ALIAS(X509V3_EXT_add_alias);
void
X509V3_EXT_cleanup(void)
{
}
LCRYPTO_ALIAS(X509V3_EXT_cleanup);

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $OpenBSD: qwxreg.h,v 1.1 2023/12/28 17:36:29 stsp Exp $ */ /* $OpenBSD: qwxreg.h,v 1.2 2024/01/25 10:11:04 stsp Exp $ */
/* /*
* Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc.
@ -2911,7 +2911,7 @@ struct wmi_vdev_start_req_arg {
}; };
struct peer_create_params { struct peer_create_params {
const uint8_t *peer_addr; uint8_t *peer_addr;
uint32_t peer_type; uint32_t peer_type;
uint32_t vdev_id; uint32_t vdev_id;
}; };
@ -8257,6 +8257,85 @@ struct hal_reo_cmd_hdr {
uint32_t info0; uint32_t info0;
} __packed; } __packed;
#define HAL_SRNG_DESC_LOOP_CNT 0xf0000000
#define HAL_REO_CMD_FLG_NEED_STATUS BIT(0)
#define HAL_REO_CMD_FLG_STATS_CLEAR BIT(1)
#define HAL_REO_CMD_FLG_FLUSH_BLOCK_LATER BIT(2)
#define HAL_REO_CMD_FLG_FLUSH_RELEASE_BLOCKING BIT(3)
#define HAL_REO_CMD_FLG_FLUSH_NO_INVAL BIT(4)
#define HAL_REO_CMD_FLG_FLUSH_FWD_ALL_MPDUS BIT(5)
#define HAL_REO_CMD_FLG_FLUSH_ALL BIT(6)
#define HAL_REO_CMD_FLG_UNBLK_RESOURCE BIT(7)
#define HAL_REO_CMD_FLG_UNBLK_CACHE BIT(8)
/* Should be matching with HAL_REO_UPD_RX_QUEUE_INFO0_UPD_* feilds */
#define HAL_REO_CMD_UPD0_RX_QUEUE_NUM BIT(8)
#define HAL_REO_CMD_UPD0_VLD BIT(9)
#define HAL_REO_CMD_UPD0_ALDC BIT(10)
#define HAL_REO_CMD_UPD0_DIS_DUP_DETECTION BIT(11)
#define HAL_REO_CMD_UPD0_SOFT_REORDER_EN BIT(12)
#define HAL_REO_CMD_UPD0_AC BIT(13)
#define HAL_REO_CMD_UPD0_BAR BIT(14)
#define HAL_REO_CMD_UPD0_RETRY BIT(15)
#define HAL_REO_CMD_UPD0_CHECK_2K_MODE BIT(16)
#define HAL_REO_CMD_UPD0_OOR_MODE BIT(17)
#define HAL_REO_CMD_UPD0_BA_WINDOW_SIZE BIT(18)
#define HAL_REO_CMD_UPD0_PN_CHECK BIT(19)
#define HAL_REO_CMD_UPD0_EVEN_PN BIT(20)
#define HAL_REO_CMD_UPD0_UNEVEN_PN BIT(21)
#define HAL_REO_CMD_UPD0_PN_HANDLE_ENABLE BIT(22)
#define HAL_REO_CMD_UPD0_PN_SIZE BIT(23)
#define HAL_REO_CMD_UPD0_IGNORE_AMPDU_FLG BIT(24)
#define HAL_REO_CMD_UPD0_SVLD BIT(25)
#define HAL_REO_CMD_UPD0_SSN BIT(26)
#define HAL_REO_CMD_UPD0_SEQ_2K_ERR BIT(27)
#define HAL_REO_CMD_UPD0_PN_ERR BIT(28)
#define HAL_REO_CMD_UPD0_PN_VALID BIT(29)
#define HAL_REO_CMD_UPD0_PN BIT(30)
/* Should be matching with HAL_REO_UPD_RX_QUEUE_INFO1_* feilds */
#define HAL_REO_CMD_UPD1_VLD BIT(16)
#define HAL_REO_CMD_UPD1_ALDC GENMASK(18, 17)
#define HAL_REO_CMD_UPD1_DIS_DUP_DETECTION BIT(19)
#define HAL_REO_CMD_UPD1_SOFT_REORDER_EN BIT(20)
#define HAL_REO_CMD_UPD1_AC GENMASK(22, 21)
#define HAL_REO_CMD_UPD1_BAR BIT(23)
#define HAL_REO_CMD_UPD1_RETRY BIT(24)
#define HAL_REO_CMD_UPD1_CHECK_2K_MODE BIT(25)
#define HAL_REO_CMD_UPD1_OOR_MODE BIT(26)
#define HAL_REO_CMD_UPD1_PN_CHECK BIT(27)
#define HAL_REO_CMD_UPD1_EVEN_PN BIT(28)
#define HAL_REO_CMD_UPD1_UNEVEN_PN BIT(29)
#define HAL_REO_CMD_UPD1_PN_HANDLE_ENABLE BIT(30)
#define HAL_REO_CMD_UPD1_IGNORE_AMPDU_FLG BIT(31)
/* Should be matching with HAL_REO_UPD_RX_QUEUE_INFO2_* feilds */
#define HAL_REO_CMD_UPD2_SVLD BIT(10)
#define HAL_REO_CMD_UPD2_SSN GENMASK(22, 11)
#define HAL_REO_CMD_UPD2_SEQ_2K_ERR BIT(23)
#define HAL_REO_CMD_UPD2_PN_ERR BIT(24)
#define HAL_REO_DEST_RING_CTRL_HASH_RING_MAP GENMASK(31, 8)
struct ath11k_hal_reo_cmd {
uint32_t addr_lo;
uint32_t flag;
uint32_t upd0;
uint32_t upd1;
uint32_t upd2;
uint32_t pn[4];
uint16_t rx_queue_num;
uint16_t min_rel;
uint16_t min_fwd;
uint8_t addr_hi;
uint8_t ac_list;
uint8_t blocking_idx;
uint16_t ba_window_size;
uint8_t pn_size;
};
#define HAL_REO_GET_QUEUE_STATS_INFO0_QUEUE_ADDR_HI GENMASK(7, 0) #define HAL_REO_GET_QUEUE_STATS_INFO0_QUEUE_ADDR_HI GENMASK(7, 0)
#define HAL_REO_GET_QUEUE_STATS_INFO0_CLEAR_STATS BIT(8) #define HAL_REO_GET_QUEUE_STATS_INFO0_CLEAR_STATS BIT(8)
@ -9862,6 +9941,11 @@ struct hal_reo_desc_thresh_reached_status {
* entries into this Ring has looped around the ring. * entries into this Ring has looped around the ring.
*/ */
#define REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_0 0xDDBEEF
#define REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_1 0xADBEEF
#define REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_2 0xBDBEEF
#define REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_3 0xCDBEEF
#define HAL_TX_ADDRX_EN 1 #define HAL_TX_ADDRX_EN 1
#define HAL_TX_ADDRY_EN 2 #define HAL_TX_ADDRY_EN 2

View File

@ -1,4 +1,4 @@
/* $OpenBSD: qwxvar.h,v 1.1 2023/12/28 17:36:29 stsp Exp $ */ /* $OpenBSD: qwxvar.h,v 1.5 2024/01/25 17:00:21 stsp Exp $ */
/* /*
* Copyright (c) 2018-2019 The Linux Foundation. * Copyright (c) 2018-2019 The Linux Foundation.
@ -69,12 +69,12 @@ struct ath11k_hw_ring_mask {
#define ATH11K_FW_DIR "qwx" #define ATH11K_FW_DIR "qwx"
#define ATH11K_BOARD_MAGIC "QCA-ATH11K-BOARD" #define ATH11K_BOARD_MAGIC "QCA-ATH11K-BOARD"
#define ATH11K_BOARD_API2_FILE "board-2.bin" #define ATH11K_BOARD_API2_FILE "board-2"
#define ATH11K_DEFAULT_BOARD_FILE "board.bin" #define ATH11K_DEFAULT_BOARD_FILE "board"
#define ATH11K_DEFAULT_CAL_FILE "caldata.bin" #define ATH11K_DEFAULT_CAL_FILE "caldata"
#define ATH11K_AMSS_FILE "amss.bin" #define ATH11K_AMSS_FILE "amss"
#define ATH11K_M3_FILE "m3.bin" #define ATH11K_M3_FILE "m3"
#define ATH11K_REGDB_FILE "regdb.bin" #define ATH11K_REGDB_FILE "regdb"
#define QWX_FW_BUILD_ID_MASK "QC_IMAGE_VERSION_STRING=" #define QWX_FW_BUILD_ID_MASK "QC_IMAGE_VERSION_STRING="
@ -214,9 +214,9 @@ struct ath11k_hw_ops {
#endif #endif
void (*wmi_init_config)(struct qwx_softc *sc, void (*wmi_init_config)(struct qwx_softc *sc,
struct target_resource_config *config); struct target_resource_config *config);
#if notyet
int (*mac_id_to_pdev_id)(struct ath11k_hw_params *hw, int mac_id); int (*mac_id_to_pdev_id)(struct ath11k_hw_params *hw, int mac_id);
int (*mac_id_to_srng_id)(struct ath11k_hw_params *hw, int mac_id); int (*mac_id_to_srng_id)(struct ath11k_hw_params *hw, int mac_id);
#if notyet
void (*tx_mesh_enable)(struct ath11k_base *ab, void (*tx_mesh_enable)(struct ath11k_base *ab,
struct hal_tcl_data_cmd *tcl_cmd); struct hal_tcl_data_cmd *tcl_cmd);
bool (*rx_desc_get_first_msdu)(struct hal_rx_desc *desc); bool (*rx_desc_get_first_msdu)(struct hal_rx_desc *desc);
@ -645,6 +645,13 @@ struct ath11k_hal {
#endif #endif
}; };
enum hal_pn_type {
HAL_PN_TYPE_NONE,
HAL_PN_TYPE_WPA,
HAL_PN_TYPE_WAPI_EVEN,
HAL_PN_TYPE_WAPI_UNEVEN,
};
enum hal_ce_desc { enum hal_ce_desc {
HAL_CE_DESC_SRC, HAL_CE_DESC_SRC,
HAL_CE_DESC_DST, HAL_CE_DESC_DST,
@ -839,8 +846,9 @@ struct qwx_hp_update_timer {
struct dp_rx_tid { struct dp_rx_tid {
uint8_t tid; uint8_t tid;
struct qwx_dmamem *mem;
uint32_t *vaddr; uint32_t *vaddr;
bus_addr_t paddr; uint64_t paddr;
uint32_t size; uint32_t size;
uint32_t ba_win_sz; uint32_t ba_win_sz;
int active; int active;
@ -1267,6 +1275,177 @@ struct dp_rxdma_ring {
int bufs_max; int bufs_max;
}; };
enum hal_rx_mon_status {
HAL_RX_MON_STATUS_PPDU_NOT_DONE,
HAL_RX_MON_STATUS_PPDU_DONE,
HAL_RX_MON_STATUS_BUF_DONE,
};
struct hal_rx_user_status {
uint32_t mcs:4,
nss:3,
ofdma_info_valid:1,
dl_ofdma_ru_start_index:7,
dl_ofdma_ru_width:7,
dl_ofdma_ru_size:8;
uint32_t ul_ofdma_user_v0_word0;
uint32_t ul_ofdma_user_v0_word1;
uint32_t ast_index;
uint32_t tid;
uint16_t tcp_msdu_count;
uint16_t udp_msdu_count;
uint16_t other_msdu_count;
uint16_t frame_control;
uint8_t frame_control_info_valid;
uint8_t data_sequence_control_info_valid;
uint16_t first_data_seq_ctrl;
uint32_t preamble_type;
uint16_t ht_flags;
uint16_t vht_flags;
uint16_t he_flags;
uint8_t rs_flags;
uint32_t mpdu_cnt_fcs_ok;
uint32_t mpdu_cnt_fcs_err;
uint32_t mpdu_fcs_ok_bitmap[8];
uint32_t mpdu_ok_byte_count;
uint32_t mpdu_err_byte_count;
};
#define HAL_INVALID_PEERID 0xffff
#define VHT_SIG_SU_NSS_MASK 0x7
#define HAL_RX_MAX_MCS 12
#define HAL_RX_MAX_NSS 8
#define HAL_TLV_STATUS_PPDU_NOT_DONE HAL_RX_MON_STATUS_PPDU_NOT_DONE
#define HAL_TLV_STATUS_PPDU_DONE HAL_RX_MON_STATUS_PPDU_DONE
#define HAL_TLV_STATUS_BUF_DONE HAL_RX_MON_STATUS_BUF_DONE
struct hal_rx_mon_ppdu_info {
uint32_t ppdu_id;
uint32_t ppdu_ts;
uint32_t num_mpdu_fcs_ok;
uint32_t num_mpdu_fcs_err;
uint32_t preamble_type;
uint16_t chan_num;
uint16_t tcp_msdu_count;
uint16_t tcp_ack_msdu_count;
uint16_t udp_msdu_count;
uint16_t other_msdu_count;
uint16_t peer_id;
uint8_t rate;
uint8_t mcs;
uint8_t nss;
uint8_t bw;
uint8_t vht_flag_values1;
uint8_t vht_flag_values2;
uint8_t vht_flag_values3[4];
uint8_t vht_flag_values4;
uint8_t vht_flag_values5;
uint16_t vht_flag_values6;
uint8_t is_stbc;
uint8_t gi;
uint8_t ldpc;
uint8_t beamformed;
uint8_t rssi_comb;
uint8_t rssi_chain_pri20[HAL_RX_MAX_NSS];
uint8_t tid;
uint16_t ht_flags;
uint16_t vht_flags;
uint16_t he_flags;
uint16_t he_mu_flags;
uint8_t dcm;
uint8_t ru_alloc;
uint8_t reception_type;
uint64_t tsft;
uint64_t rx_duration;
uint16_t frame_control;
uint32_t ast_index;
uint8_t rs_fcs_err;
uint8_t rs_flags;
uint8_t cck_flag;
uint8_t ofdm_flag;
uint8_t ulofdma_flag;
uint8_t frame_control_info_valid;
uint16_t he_per_user_1;
uint16_t he_per_user_2;
uint8_t he_per_user_position;
uint8_t he_per_user_known;
uint16_t he_flags1;
uint16_t he_flags2;
uint8_t he_RU[4];
uint16_t he_data1;
uint16_t he_data2;
uint16_t he_data3;
uint16_t he_data4;
uint16_t he_data5;
uint16_t he_data6;
uint32_t ppdu_len;
uint32_t prev_ppdu_id;
uint32_t device_id;
uint16_t first_data_seq_ctrl;
uint8_t monitor_direct_used;
uint8_t data_sequence_control_info_valid;
uint8_t ltf_size;
uint8_t rxpcu_filter_pass;
char rssi_chain[8][8];
struct hal_rx_user_status userstats;
};
enum dp_mon_status_buf_state {
/* PPDU id matches in dst ring and status ring */
DP_MON_STATUS_MATCH,
/* status ring dma is not done */
DP_MON_STATUS_NO_DMA,
/* status ring is lagging, reap status ring */
DP_MON_STATUS_LAG,
/* status ring is leading, reap dst ring and drop */
DP_MON_STATUS_LEAD,
/* replinish monitor status ring */
DP_MON_STATUS_REPLINISH,
};
struct qwx_pdev_mon_stats {
uint32_t status_ppdu_state;
uint32_t status_ppdu_start;
uint32_t status_ppdu_end;
uint32_t status_ppdu_compl;
uint32_t status_ppdu_start_mis;
uint32_t status_ppdu_end_mis;
uint32_t status_ppdu_done;
uint32_t dest_ppdu_done;
uint32_t dest_mpdu_done;
uint32_t dest_mpdu_drop;
uint32_t dup_mon_linkdesc_cnt;
uint32_t dup_mon_buf_cnt;
uint32_t dest_mon_stuck;
uint32_t dest_mon_not_reaped;
};
struct qwx_mon_data {
struct dp_link_desc_bank link_desc_banks[DP_LINK_DESC_BANKS_MAX];
struct hal_rx_mon_ppdu_info mon_ppdu_info;
uint32_t mon_ppdu_status;
uint32_t mon_last_buf_cookie;
uint64_t mon_last_linkdesc_paddr;
uint16_t chan_noise_floor;
bool hold_mon_dst_ring;
enum dp_mon_status_buf_state buf_state;
bus_addr_t mon_status_paddr;
struct dp_full_mon_mpdu *mon_mpdu;
#ifdef notyet
struct hal_sw_mon_ring_entries sw_mon_entries;
#endif
struct qwx_pdev_mon_stats rx_mon_stats;
#ifdef notyet
/* lock for monitor data */
spinlock_t mon_lock;
struct sk_buff_head rx_status_q;
#endif
};
#define MAX_RXDMA_PER_PDEV 2 #define MAX_RXDMA_PER_PDEV 2
struct qwx_pdev_dp { struct qwx_pdev_dp {
@ -1285,8 +1464,8 @@ struct qwx_pdev_dp {
struct dp_rxdma_ring rx_mon_status_refill_ring[MAX_RXDMA_PER_PDEV]; struct dp_rxdma_ring rx_mon_status_refill_ring[MAX_RXDMA_PER_PDEV];
#if 0 #if 0
struct ieee80211_rx_status rx_status; struct ieee80211_rx_status rx_status;
struct ath11k_mon_data mon_data;
#endif #endif
struct qwx_mon_data mon_data;
}; };
struct qwx_vif { struct qwx_vif {
@ -1341,8 +1520,8 @@ struct qwx_vif {
bool wpaie_present; bool wpaie_present;
bool bcca_zero_sent; bool bcca_zero_sent;
bool do_not_send_tmpl; bool do_not_send_tmpl;
struct ieee80211_channel *chan;
#if 0 #if 0
struct ieee80211_chanctx_conf chanctx;
struct ath11k_arp_ns_offload arp_ns_offload; struct ath11k_arp_ns_offload arp_ns_offload;
struct ath11k_rekey_data rekey_data; struct ath11k_rekey_data rekey_data;
#endif #endif
@ -1359,6 +1538,22 @@ struct qwx_survey_info {
uint64_t time_busy; uint64_t time_busy;
}; };
#define ATH11K_IRQ_NUM_MAX 52
#define ATH11K_EXT_IRQ_NUM_MAX 16
struct qwx_ext_irq_grp {
struct qwx_softc *sc;
uint32_t irqs[ATH11K_EXT_IRQ_NUM_MAX];
uint32_t num_irq;
uint32_t grp_id;
uint64_t timestamp;
#if 0
bool napi_enabled;
struct napi_struct napi;
struct net_device napi_ndev;
#endif
};
struct qwx_softc { struct qwx_softc {
struct device sc_dev; struct device sc_dev;
struct ieee80211com sc_ic; struct ieee80211com sc_ic;
@ -1410,6 +1605,8 @@ struct qwx_softc {
enum ath11k_crypt_mode crypto_mode; enum ath11k_crypt_mode crypto_mode;
enum ath11k_hw_txrx_mode frame_mode; enum ath11k_hw_txrx_mode frame_mode;
struct qwx_ext_irq_grp ext_irq_grp[ATH11K_EXT_IRQ_GRP_NUM_MAX];
uint16_t qmi_txn_id; uint16_t qmi_txn_id;
int qmi_cal_done; int qmi_cal_done;
struct qwx_qmi_ce_cfg qmi_ce_cfg; struct qwx_qmi_ce_cfg qmi_ce_cfg;
@ -1426,6 +1623,9 @@ struct qwx_softc {
uint32_t allocated_vdev_map; uint32_t allocated_vdev_map;
uint32_t free_vdev_map; uint32_t free_vdev_map;
int num_peers; int num_peers;
int peer_mapped;
int peer_delete_done;
int vdev_setup_done;
struct qwx_dbring_cap *db_caps; struct qwx_dbring_cap *db_caps;
uint32_t num_db_cap; uint32_t num_db_cap;
@ -1443,7 +1643,7 @@ struct qwx_softc {
uint32_t pdev_id; uint32_t pdev_id;
} target_pdev_ids[MAX_RADIOS]; } target_pdev_ids[MAX_RADIOS];
uint8_t target_pdev_count; uint8_t target_pdev_count;
struct qwx_pdev *pdevs_active[MAX_RADIOS]; uint32_t pdevs_active;
int pdevs_macaddr_valid; int pdevs_macaddr_valid;
struct ath11k_hal_reg_capabilities_ext hal_reg_cap[MAX_RADIOS]; struct ath11k_hal_reg_capabilities_ext hal_reg_cap[MAX_RADIOS];
@ -1470,15 +1670,19 @@ struct qwx_softc {
enum ath11k_hw_rev sc_hw_rev; enum ath11k_hw_rev sc_hw_rev;
struct qwx_device_id id; struct qwx_device_id id;
char sc_bus_str[4]; /* "pci" or "ahb" */ char sc_bus_str[4]; /* "pci" or "ahb" */
int num_msivec;
uint32_t msi_addr_lo; uint32_t msi_addr_lo;
uint32_t msi_addr_hi; uint32_t msi_addr_hi;
uint32_t msi_data_start; uint32_t msi_data_start;
const struct qwx_msi_config *msi_cfg; const struct qwx_msi_config *msi_cfg;
uint32_t msi_ce_irqmask;
struct qmi_wlanfw_request_mem_ind_msg_v01 *sc_req_mem_ind; struct qmi_wlanfw_request_mem_ind_msg_v01 *sc_req_mem_ind;
}; };
int qwx_intr(struct qwx_softc *); int qwx_ce_intr(void *);
int qwx_ext_intr(void *);
int qwx_dp_service_srng(struct qwx_softc *, int);
int qwx_init_hw_params(struct qwx_softc *); int qwx_init_hw_params(struct qwx_softc *);
int qwx_attach(struct qwx_softc *); int qwx_attach(struct qwx_softc *);
@ -1495,8 +1699,46 @@ void qwx_init_task(void *);
int qwx_newstate(struct ieee80211com *, enum ieee80211_state, int); int qwx_newstate(struct ieee80211com *, enum ieee80211_state, int);
void qwx_newstate_task(void *); void qwx_newstate_task(void *);
struct ath11k_peer {
#if 0
struct list_head list;
struct ieee80211_sta *sta;
#endif
int vdev_id;
#if 0
u8 addr[ETH_ALEN];
#endif
int peer_id;
uint16_t ast_hash;
uint8_t pdev_id;
uint16_t hw_peer_id;
#if 0
/* protected by ab->data_lock */
struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1];
#endif
struct dp_rx_tid rx_tid[IEEE80211_NUM_TID + 1];
#if 0
/* peer id based rhashtable list pointer */
struct rhash_head rhash_id;
/* peer addr based rhashtable list pointer */
struct rhash_head rhash_addr;
/* Info used in MMIC verification of
* RX fragments
*/
struct crypto_shash *tfm_mmic;
u8 mcast_keyidx;
u8 ucast_keyidx;
u16 sec_type;
u16 sec_type_grp;
bool is_authorized;
bool dp_setup_done;
#endif
};
struct qwx_node { struct qwx_node {
struct ieee80211_node ni; struct ieee80211_node ni;
struct ath11k_peer peer;
}; };
struct ieee80211_node *qwx_node_alloc(struct ieee80211com *); struct ieee80211_node *qwx_node_alloc(struct ieee80211com *);
@ -1506,6 +1748,7 @@ void qwx_qrtr_recv_msg(struct qwx_softc *, struct mbuf *);
int qwx_hal_srng_init(struct qwx_softc *); int qwx_hal_srng_init(struct qwx_softc *);
int qwx_ce_alloc_pipes(struct qwx_softc *); int qwx_ce_alloc_pipes(struct qwx_softc *);
void qwx_ce_free_pipes(struct qwx_softc *);
void qwx_ce_rx_post_buf(struct qwx_softc *); void qwx_ce_rx_post_buf(struct qwx_softc *);
void qwx_ce_get_shadow_config(struct qwx_softc *, uint32_t **, uint32_t *); void qwx_ce_get_shadow_config(struct qwx_softc *, uint32_t **, uint32_t *);
@ -1521,3 +1764,11 @@ qwx_ce_get_attr_flags(struct qwx_softc *sc, int ce_id)
KASSERT(ce_id < sc->hw_params.ce_count); KASSERT(ce_id < sc->hw_params.ce_count);
return sc->hw_params.host_ce_config[ce_id].flags; return sc->hw_params.host_ce_config[ce_id].flags;
} }
static inline enum ieee80211_edca_ac qwx_tid_to_ac(uint32_t tid)
{
return (((tid == 0) || (tid == 3)) ? EDCA_AC_BE :
((tid == 1) || (tid == 2)) ? EDCA_AC_BK :
((tid == 4) || (tid == 5)) ? EDCA_AC_VI :
EDCA_AC_VO);
}

View File

@ -3653,10 +3653,12 @@ int amdgpu_device_init(struct amdgpu_device *adev,
adev->rmmio_base = pci_resource_start(adev->pdev, 2); adev->rmmio_base = pci_resource_start(adev->pdev, 2);
adev->rmmio_size = pci_resource_len(adev->pdev, 2); adev->rmmio_size = pci_resource_len(adev->pdev, 2);
} }
#endif
for (i = 0; i < AMD_IP_BLOCK_TYPE_NUM; i++) for (i = 0; i < AMD_IP_BLOCK_TYPE_NUM; i++)
atomic_set(&adev->pm.pwr_state[i], POWER_STATE_UNKNOWN); atomic_set(&adev->pm.pwr_state[i], POWER_STATE_UNKNOWN);
#ifdef __linux__
adev->rmmio = ioremap(adev->rmmio_base, adev->rmmio_size); adev->rmmio = ioremap(adev->rmmio_base, adev->rmmio_size);
if (!adev->rmmio) if (!adev->rmmio)
return -ENOMEM; return -ENOMEM;

View File

@ -3478,63 +3478,9 @@ amdgpu_attachhook(struct device *self)
struct drm_gem_object *obj; struct drm_gem_object *obj;
struct amdgpu_bo *rbo; struct amdgpu_bo *rbo;
/* from amdgpu_driver_load_kms() */ r = amdgpu_driver_load_kms(adev, adev->flags);
if (r)
/* amdgpu_device_init should report only fatal error
* like memory allocation failure or iomapping failure,
* or memory manager initialization failure, it must
* properly initialize the GPU MC controller and permit
* VRAM allocation
*/
r = amdgpu_device_init(adev, adev->flags);
if (r) {
dev_err(&dev->pdev->dev, "Fatal error during GPU init\n");
goto out; goto out;
}
adev->pm.rpm_mode = AMDGPU_RUNPM_NONE;
if (amdgpu_device_supports_px(dev) &&
(amdgpu_runtime_pm != 0)) { /* enable PX as runtime mode */
adev->pm.rpm_mode = AMDGPU_RUNPM_PX;
dev_info(adev->dev, "Using ATPX for runtime pm\n");
} else if (amdgpu_device_supports_boco(dev) &&
(amdgpu_runtime_pm != 0)) { /* enable boco as runtime mode */
adev->pm.rpm_mode = AMDGPU_RUNPM_BOCO;
dev_info(adev->dev, "Using BOCO for runtime pm\n");
} else if (amdgpu_device_supports_baco(dev) &&
(amdgpu_runtime_pm != 0)) {
switch (adev->asic_type) {
case CHIP_VEGA20:
case CHIP_ARCTURUS:
/* enable BACO as runpm mode if runpm=1 */
if (amdgpu_runtime_pm > 0)
adev->pm.rpm_mode = AMDGPU_RUNPM_BACO;
break;
case CHIP_VEGA10:
/* enable BACO as runpm mode if noretry=0 */
if (!adev->gmc.noretry)
adev->pm.rpm_mode = AMDGPU_RUNPM_BACO;
break;
default:
/* enable BACO as runpm mode on CI+ */
adev->pm.rpm_mode = AMDGPU_RUNPM_BACO;
break;
}
if (adev->pm.rpm_mode == AMDGPU_RUNPM_BACO)
dev_info(adev->dev, "Using BACO for runtime pm\n");
}
/* Call ACPI methods: require modeset init
* but failure is not fatal
*/
acpi_status = amdgpu_acpi_init(adev);
if (acpi_status)
dev_dbg(dev->dev, "Error during ACPI methods call\n");
if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DRV_LOAD))
DRM_WARN("smart shift update failed\n");
/* /*
* 1. don't init fbdev on hw without DCE * 1. don't init fbdev on hw without DCE

View File

@ -69,7 +69,6 @@ void amdgpu_unregister_gpu_instance(struct amdgpu_device *adev)
mutex_unlock(&mgpu_info.mutex); mutex_unlock(&mgpu_info.mutex);
} }
#ifdef __linux__
/** /**
* amdgpu_driver_unload_kms - Main unload function for KMS. * amdgpu_driver_unload_kms - Main unload function for KMS.
* *
@ -96,7 +95,6 @@ void amdgpu_driver_unload_kms(struct drm_device *dev)
amdgpu_acpi_fini(adev); amdgpu_acpi_fini(adev);
amdgpu_device_fini_hw(adev); amdgpu_device_fini_hw(adev);
} }
#endif /* __linux__ */
void amdgpu_register_gpu_instance(struct amdgpu_device *adev) void amdgpu_register_gpu_instance(struct amdgpu_device *adev)
{ {
@ -123,7 +121,6 @@ void amdgpu_register_gpu_instance(struct amdgpu_device *adev)
mutex_unlock(&mgpu_info.mutex); mutex_unlock(&mgpu_info.mutex);
} }
#ifdef __linux__
/** /**
* amdgpu_driver_load_kms - Main load function for KMS. * amdgpu_driver_load_kms - Main load function for KMS.
* *
@ -202,7 +199,6 @@ out:
return r; return r;
} }
#endif /* __linux__ */
static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info, static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info,
struct drm_amdgpu_query_fw *query_fw, struct drm_amdgpu_query_fw *query_fw,

View File

@ -1,4 +1,4 @@
/* $OpenBSD: if_qwx_pci.c,v 1.2 2024/01/11 09:52:19 stsp Exp $ */ /* $OpenBSD: if_qwx_pci.c,v 1.4 2024/01/25 17:00:21 stsp Exp $ */
/* /*
* Copyright 2023 Stefan Sperling <stsp@openbsd.org> * Copyright 2023 Stefan Sperling <stsp@openbsd.org>
@ -330,6 +330,8 @@ struct qwx_mhi_newstate {
int queued; int queued;
}; };
#define QWX_NUM_MSI_VEC 32
struct qwx_pci_softc { struct qwx_pci_softc {
struct qwx_softc sc_sc; struct qwx_softc sc_sc;
pci_chipset_tag_t sc_pc; pci_chipset_tag_t sc_pc;
@ -337,7 +339,10 @@ struct qwx_pci_softc {
int sc_cap_off; int sc_cap_off;
int sc_msi_off; int sc_msi_off;
pcireg_t sc_msi_cap; pcireg_t sc_msi_cap;
void *sc_ih; void *sc_ih[QWX_NUM_MSI_VEC];
char sc_ivname[QWX_NUM_MSI_VEC][16];
struct qwx_ext_irq_grp ext_irq_grp[ATH11K_EXT_IRQ_GRP_NUM_MAX];
int mhi_irq[2];
bus_space_tag_t sc_st; bus_space_tag_t sc_st;
bus_space_handle_t sc_sh; bus_space_handle_t sc_sh;
bus_addr_t sc_map; bus_addr_t sc_map;
@ -414,6 +419,7 @@ void qwx_pcic_write32(struct qwx_softc *, uint32_t, uint32_t);
void qwx_pcic_ext_irq_enable(struct qwx_softc *); void qwx_pcic_ext_irq_enable(struct qwx_softc *);
void qwx_pcic_ext_irq_disable(struct qwx_softc *); void qwx_pcic_ext_irq_disable(struct qwx_softc *);
int qwx_pcic_config_irq(struct qwx_softc *, struct pci_attach_args *);
int qwx_pci_start(struct qwx_softc *); int qwx_pci_start(struct qwx_softc *);
void qwx_pci_stop(struct qwx_softc *); void qwx_pci_stop(struct qwx_softc *);
@ -475,6 +481,8 @@ void qwx_pci_intr_data_event_tx(struct qwx_pci_softc *,
struct qwx_mhi_ring_element *); struct qwx_mhi_ring_element *);
int qwx_pci_intr_data_event(struct qwx_pci_softc *, int qwx_pci_intr_data_event(struct qwx_pci_softc *,
struct qwx_pci_event_ring *); struct qwx_pci_event_ring *);
int qwx_pci_intr_mhi_ctrl(void *);
int qwx_pci_intr_mhi_data(void *);
int qwx_pci_intr(void *); int qwx_pci_intr(void *);
struct qwx_pci_ops { struct qwx_pci_ops {
@ -555,6 +563,89 @@ const struct qwx_msi_config qwx_msi_config_one_msi = {
}, },
}; };
const struct qwx_msi_config qwx_msi_config[] = {
{
.total_vectors = 32,
.total_users = 4,
.users = (struct qwx_msi_user[]) {
{ .name = "MHI", .num_vectors = 3, .base_vector = 0 },
{ .name = "CE", .num_vectors = 10, .base_vector = 3 },
{ .name = "WAKE", .num_vectors = 1, .base_vector = 13 },
{ .name = "DP", .num_vectors = 18, .base_vector = 14 },
},
.hw_rev = ATH11K_HW_QCA6390_HW20,
},
{
.total_vectors = 16,
.total_users = 3,
.users = (struct qwx_msi_user[]) {
{ .name = "MHI", .num_vectors = 3, .base_vector = 0 },
{ .name = "CE", .num_vectors = 5, .base_vector = 3 },
{ .name = "DP", .num_vectors = 8, .base_vector = 8 },
},
.hw_rev = ATH11K_HW_QCN9074_HW10,
},
{
.total_vectors = 32,
.total_users = 4,
.users = (struct qwx_msi_user[]) {
{ .name = "MHI", .num_vectors = 3, .base_vector = 0 },
{ .name = "CE", .num_vectors = 10, .base_vector = 3 },
{ .name = "WAKE", .num_vectors = 1, .base_vector = 13 },
{ .name = "DP", .num_vectors = 18, .base_vector = 14 },
},
.hw_rev = ATH11K_HW_WCN6855_HW20,
},
{
.total_vectors = 32,
.total_users = 4,
.users = (struct qwx_msi_user[]) {
{ .name = "MHI", .num_vectors = 3, .base_vector = 0 },
{ .name = "CE", .num_vectors = 10, .base_vector = 3 },
{ .name = "WAKE", .num_vectors = 1, .base_vector = 13 },
{ .name = "DP", .num_vectors = 18, .base_vector = 14 },
},
.hw_rev = ATH11K_HW_WCN6855_HW21,
},
{
.total_vectors = 28,
.total_users = 2,
.users = (struct qwx_msi_user[]) {
{ .name = "CE", .num_vectors = 10, .base_vector = 0 },
{ .name = "DP", .num_vectors = 18, .base_vector = 10 },
},
.hw_rev = ATH11K_HW_WCN6750_HW10,
},
};
int
qwx_pcic_init_msi_config(struct qwx_softc *sc)
{
const struct qwx_msi_config *msi_config;
int i;
if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, sc->sc_flags)) {
sc->msi_cfg = &qwx_msi_config_one_msi;
return 0;
}
for (i = 0; i < nitems(qwx_msi_config); i++) {
msi_config = &qwx_msi_config[i];
if (msi_config->hw_rev == sc->sc_hw_rev)
break;
}
if (i == nitems(qwx_msi_config)) {
printf("%s: failed to fetch msi config, "
"unsupported hw version: 0x%x\n",
sc->sc_dev.dv_xname, sc->sc_hw_rev);
return EINVAL;
}
sc->msi_cfg = msi_config;
return 0;
}
int int
qwx_pci_alloc_msi(struct qwx_softc *sc) qwx_pci_alloc_msi(struct qwx_softc *sc)
{ {
@ -562,11 +653,6 @@ qwx_pci_alloc_msi(struct qwx_softc *sc)
uint64_t addr; uint64_t addr;
pcireg_t data; pcireg_t data;
/*
* OpenBSD only supports one MSI vector at present.
* Mulitple vectors are only supported with MSI-X.
*/
if (psc->sc_msi_cap & PCI_MSI_MC_C64) { if (psc->sc_msi_cap & PCI_MSI_MC_C64) {
uint64_t addr_hi; uint64_t addr_hi;
pcireg_t addr_lo; pcireg_t addr_lo;
@ -592,7 +678,6 @@ qwx_pci_alloc_msi(struct qwx_softc *sc)
DPRINTF("%s: MSI addr: 0x%llx MSI data: 0x%x\n", sc->sc_dev.dv_xname, DPRINTF("%s: MSI addr: 0x%llx MSI data: 0x%x\n", sc->sc_dev.dv_xname,
addr, data); addr, data);
sc->msi_cfg = &qwx_msi_config_one_msi;
return 0; return 0;
} }
@ -661,6 +746,7 @@ qwx_pcic_get_user_msi_vector(struct qwx_softc *sc, char *user_name,
DPRINTF("%s: Failed to find MSI assignment for %s\n", DPRINTF("%s: Failed to find MSI assignment for %s\n",
sc->sc_dev.dv_xname, user_name); sc->sc_dev.dv_xname, user_name);
return EINVAL; return EINVAL;
} }
@ -732,15 +818,31 @@ qwx_pci_attach(struct device *parent, struct device *self, void *aux)
sc->mem = psc->sc_map; sc->mem = psc->sc_map;
if (pci_intr_map_msi(pa, &ih)) { sc->num_msivec = 32;
if (pci_intr_enable_msivec(pa, sc->num_msivec) != 0) {
sc->num_msivec = 1;
if (pci_intr_map_msi(pa, &ih) != 0) {
printf(": can't map interrupt\n"); printf(": can't map interrupt\n");
return; return;
} }
clear_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, sc->sc_flags);
} else {
if (pci_intr_map_msivec(pa, 0, &ih) != 0 &&
pci_intr_map_msi(pa, &ih) != 0) {
printf(": can't map interrupt\n");
return;
}
set_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, sc->sc_flags);
psc->mhi_irq[MHI_ER_CTRL] = 1;
psc->mhi_irq[MHI_ER_DATA] = 2;
}
intrstr = pci_intr_string(psc->sc_pc, ih); intrstr = pci_intr_string(psc->sc_pc, ih);
psc->sc_ih = pci_intr_establish(psc->sc_pc, ih, IPL_NET, snprintf(psc->sc_ivname[0], sizeof(psc->sc_ivname[0]), "%s:bhi",
qwx_pci_intr, psc, sc->sc_dev.dv_xname); sc->sc_dev.dv_xname);
if (psc->sc_ih == NULL) { psc->sc_ih[0] = pci_intr_establish(psc->sc_pc, ih, IPL_NET,
qwx_pci_intr, psc, psc->sc_ivname[0]);
if (psc->sc_ih[0] == NULL) {
printf(": can't establish interrupt"); printf(": can't establish interrupt");
if (intrstr != NULL) if (intrstr != NULL)
printf(" at %s", intrstr); printf(" at %s", intrstr);
@ -749,6 +851,46 @@ qwx_pci_attach(struct device *parent, struct device *self, void *aux)
} }
printf(": %s\n", intrstr); printf(": %s\n", intrstr);
if (test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, sc->sc_flags)) {
int msivec;
msivec = psc->mhi_irq[MHI_ER_CTRL];
if (pci_intr_map_msivec(pa, msivec, &ih) != 0 &&
pci_intr_map_msi(pa, &ih) != 0) {
printf(": can't map interrupt\n");
return;
}
snprintf(psc->sc_ivname[msivec],
sizeof(psc->sc_ivname[msivec]),
"%s:mhic", sc->sc_dev.dv_xname);
psc->sc_ih[msivec] = pci_intr_establish(psc->sc_pc, ih,
IPL_NET, qwx_pci_intr_mhi_ctrl, psc,
psc->sc_ivname[msivec]);
if (psc->sc_ih[msivec] == NULL) {
printf("%s: can't establish interrupt\n",
sc->sc_dev.dv_xname);
return;
}
msivec = psc->mhi_irq[MHI_ER_DATA];
if (pci_intr_map_msivec(pa, msivec, &ih) != 0 &&
pci_intr_map_msi(pa, &ih) != 0) {
printf(": can't map interrupt\n");
return;
}
snprintf(psc->sc_ivname[msivec],
sizeof(psc->sc_ivname[msivec]),
"%s:mhid", sc->sc_dev.dv_xname);
psc->sc_ih[msivec] = pci_intr_establish(psc->sc_pc, ih,
IPL_NET, qwx_pci_intr_mhi_data, psc,
psc->sc_ivname[msivec]);
if (psc->sc_ih[msivec] == NULL) {
printf("%s: can't establish interrupt\n",
sc->sc_dev.dv_xname);
return;
}
}
pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0); pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0);
switch (PCI_PRODUCT(pa->pa_id)) { switch (PCI_PRODUCT(pa->pa_id)) {
@ -810,16 +952,10 @@ unsupported_wcn6855_soc:
/* register PCI ops */ /* register PCI ops */
psc->sc_pci_ops = pci_ops; psc->sc_pci_ops = pci_ops;
/* init MSI config */ error = qwx_pcic_init_msi_config(sc);
clear_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, sc->sc_flags); if (error)
#if notyet
ret = ath11k_pcic_init_msi_config(ab);
if (ret) {
ath11k_err(ab, "failed to init msi config: %d\n", ret);
goto err_pci_free_region; goto err_pci_free_region;
}
#endif
error = qwx_pci_alloc_msi(sc); error = qwx_pci_alloc_msi(sc);
if (error) { if (error) {
printf("%s: failed to enable msi: %d\n", sc->sc_dev.dv_xname, printf("%s: failed to enable msi: %d\n", sc->sc_dev.dv_xname,
@ -891,17 +1027,17 @@ unsupported_wcn6855_soc:
sc->sc_nswq = taskq_create("qwxns", 1, IPL_NET, 0); sc->sc_nswq = taskq_create("qwxns", 1, IPL_NET, 0);
if (sc->sc_nswq == NULL) if (sc->sc_nswq == NULL)
goto err_hal_srng_deinit; goto err_ce_free;
qwx_pci_init_qmi_ce_config(sc); qwx_pci_init_qmi_ce_config(sc);
#if notyet error = qwx_pcic_config_irq(sc, pa);
ret = ath11k_pcic_config_irq(ab); if (error) {
if (ret) { printf("%s: failed to config irq: %d\n",
ath11k_err(ab, "failed to config irq: %d\n", ret); sc->sc_dev.dv_xname, error);
goto err_ce_free; goto err_ce_free;
} }
#if notyet
ret = ath11k_pci_set_irq_affinity_hint(ab_pci, cpumask_of(0)); ret = ath11k_pci_set_irq_affinity_hint(ab_pci, cpumask_of(0));
if (ret) { if (ret) {
ath11k_err(ab, "failed to set irq affinity %d\n", ret); ath11k_err(ab, "failed to set irq affinity %d\n", ret);
@ -978,6 +1114,8 @@ unsupported_wcn6855_soc:
config_mountroot(self, qwx_pci_attach_hook); config_mountroot(self, qwx_pci_attach_hook);
return; return;
err_ce_free:
qwx_ce_free_pipes(sc);
err_hal_srng_deinit: err_hal_srng_deinit:
err_mhi_unregister: err_mhi_unregister:
err_pci_free_cmd_ring: err_pci_free_cmd_ring:
@ -997,7 +1135,7 @@ err_pci_free_chan_ctxt:
psc->chan_ctxt = NULL; psc->chan_ctxt = NULL;
err_pci_disable_msi: err_pci_disable_msi:
err_pci_free_region: err_pci_free_region:
pci_intr_disestablish(psc->sc_pc, psc->sc_ih); pci_intr_disestablish(psc->sc_pc, psc->sc_ih[0]);
return; return;
} }
@ -1007,9 +1145,9 @@ qwx_pci_detach(struct device *self, int flags)
struct qwx_pci_softc *psc = (struct qwx_pci_softc *)self; struct qwx_pci_softc *psc = (struct qwx_pci_softc *)self;
struct qwx_softc *sc = &psc->sc_sc; struct qwx_softc *sc = &psc->sc_sc;
if (psc->sc_ih) { if (psc->sc_ih[0]) {
pci_intr_disestablish(psc->sc_pc, psc->sc_ih); pci_intr_disestablish(psc->sc_pc, psc->sc_ih[0]);
psc->sc_ih = NULL; psc->sc_ih[0] = NULL;
} }
qwx_detach(sc); qwx_detach(sc);
@ -1289,12 +1427,12 @@ qwx_pci_alloc_event_rings(struct qwx_pci_softc *psc)
int ret; int ret;
ret = qwx_pci_alloc_event_ring(sc, &psc->event_rings[0], ret = qwx_pci_alloc_event_ring(sc, &psc->event_rings[0],
MHI_ER_CTRL, 0, 0, 32); MHI_ER_CTRL, psc->mhi_irq[MHI_ER_CTRL], 0, 32);
if (ret) if (ret)
goto fail; goto fail;
ret = qwx_pci_alloc_event_ring(sc, &psc->event_rings[1], ret = qwx_pci_alloc_event_ring(sc, &psc->event_rings[1],
MHI_ER_DATA, 0, 1, 256); MHI_ER_DATA, psc->mhi_irq[MHI_ER_DATA], 1, 256);
if (ret) if (ret)
goto fail; goto fail;
@ -1449,7 +1587,8 @@ qwx_pcic_ce_irq_enable(struct qwx_softc *sc, uint16_t ce_id)
if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, sc->sc_flags)) if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, sc->sc_flags))
return; return;
printf("%s not implemented\n", __func__); /* OpenBSD PCI stack does not yet implement MSI interrupt masking. */
sc->msi_ce_irqmask |= (1U << ce_id);
} }
void void
@ -1461,7 +1600,145 @@ qwx_pcic_ce_irq_disable(struct qwx_softc *sc, uint16_t ce_id)
if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, sc->sc_flags)) if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, sc->sc_flags))
return; return;
printf("%s not implemented\n", __func__); /* OpenBSD PCI stack does not yet implement MSI interrupt masking. */
sc->msi_ce_irqmask &= ~(1U << ce_id);
}
void
qwx_pcic_ext_grp_disable(struct qwx_ext_irq_grp *irq_grp)
{
struct qwx_softc *sc = irq_grp->sc;
/* In case of one MSI vector, we handle irq enable/disable
* in a uniform way since we only have one irq
*/
if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, sc->sc_flags))
return;
}
int
qwx_pcic_ext_irq_config(struct qwx_softc *sc, struct pci_attach_args *pa)
{
struct qwx_pci_softc *psc = (struct qwx_pci_softc *)sc;
int i, ret, num_vectors = 0;
uint32_t msi_data_start = 0;
uint32_t base_vector = 0;
if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, sc->sc_flags))
return 0;
ret = qwx_pcic_get_user_msi_vector(sc, "DP", &num_vectors,
&msi_data_start, &base_vector);
if (ret < 0)
return ret;
for (i = 0; i < nitems(sc->ext_irq_grp); i++) {
struct qwx_ext_irq_grp *irq_grp = &sc->ext_irq_grp[i];
uint32_t num_irq = 0;
irq_grp->sc = sc;
irq_grp->grp_id = i;
#if 0
init_dummy_netdev(&irq_grp->napi_ndev);
netif_napi_add(&irq_grp->napi_ndev, &irq_grp->napi,
ath11k_pcic_ext_grp_napi_poll);
#endif
if (sc->hw_params.ring_mask->tx[i] ||
sc->hw_params.ring_mask->rx[i] ||
sc->hw_params.ring_mask->rx_err[i] ||
sc->hw_params.ring_mask->rx_wbm_rel[i] ||
sc->hw_params.ring_mask->reo_status[i] ||
sc->hw_params.ring_mask->rxdma2host[i] ||
sc->hw_params.ring_mask->host2rxdma[i] ||
sc->hw_params.ring_mask->rx_mon_status[i]) {
num_irq = 1;
}
irq_grp->num_irq = num_irq;
irq_grp->irqs[0] = ATH11K_PCI_IRQ_DP_OFFSET + i;
if (num_irq) {
int irq_idx = irq_grp->irqs[0];
pci_intr_handle_t ih;
if (pci_intr_map_msivec(pa, irq_idx, &ih) != 0 &&
pci_intr_map(pa, &ih) != 0) {
printf("%s: can't map interrupt\n",
sc->sc_dev.dv_xname);
return EIO;
}
snprintf(psc->sc_ivname[irq_idx], sizeof(psc->sc_ivname[0]),
"%s:ex%d", sc->sc_dev.dv_xname, i);
psc->sc_ih[irq_idx] = pci_intr_establish(psc->sc_pc, ih,
IPL_NET, qwx_ext_intr, irq_grp, psc->sc_ivname[irq_idx]);
if (psc->sc_ih[irq_idx] == NULL) {
printf("%s: failed to request irq %d\n",
sc->sc_dev.dv_xname, irq_idx);
return EIO;
}
}
qwx_pcic_ext_grp_disable(irq_grp);
}
return 0;
}
int
qwx_pcic_config_irq(struct qwx_softc *sc, struct pci_attach_args *pa)
{
struct qwx_pci_softc *psc = (struct qwx_pci_softc *)sc;
struct qwx_ce_pipe *ce_pipe;
uint32_t msi_data_start;
uint32_t msi_data_count, msi_data_idx;
uint32_t msi_irq_start;
int i, ret, irq_idx;
pci_intr_handle_t ih;
if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, sc->sc_flags))
return 0;
ret = qwx_pcic_get_user_msi_vector(sc, "CE", &msi_data_count,
&msi_data_start, &msi_irq_start);
if (ret)
return ret;
/* Configure CE irqs */
for (i = 0, msi_data_idx = 0; i < sc->hw_params.ce_count; i++) {
if (qwx_ce_get_attr_flags(sc, i) & CE_ATTR_DIS_INTR)
continue;
ce_pipe = &sc->ce.ce_pipe[i];
irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + i;
if (pci_intr_map_msivec(pa, irq_idx, &ih) != 0 &&
pci_intr_map(pa, &ih) != 0) {
printf("%s: can't map interrupt\n",
sc->sc_dev.dv_xname);
return EIO;
}
snprintf(psc->sc_ivname[irq_idx], sizeof(psc->sc_ivname[0]),
"%s:ce%d", sc->sc_dev.dv_xname, ce_pipe->pipe_num);
psc->sc_ih[irq_idx] = pci_intr_establish(psc->sc_pc, ih,
IPL_NET, qwx_ce_intr, ce_pipe, psc->sc_ivname[irq_idx]);
if (psc->sc_ih[irq_idx] == NULL) {
printf("%s: failed to request irq %d\n",
sc->sc_dev.dv_xname, irq_idx);
return EIO;
}
msi_data_idx++;
qwx_pcic_ce_irq_disable(sc, i);
}
ret = qwx_pcic_ext_irq_config(sc, pa);
if (ret)
return ret;
return 0;
} }
void void
@ -2747,7 +3024,7 @@ qwx_mhi_fw_load_handler(struct qwx_pci_softc *psc)
u_char *data; u_char *data;
size_t len; size_t len;
ret = snprintf(amss_path, sizeof(amss_path), "%s/%s/%s", ret = snprintf(amss_path, sizeof(amss_path), "%s-%s-%s",
ATH11K_FW_DIR, sc->hw_params.fw.dir, ATH11K_AMSS_FILE); ATH11K_FW_DIR, sc->hw_params.fw.dir, ATH11K_AMSS_FILE);
if (ret < 0 || ret >= sizeof(amss_path)) if (ret < 0 || ret >= sizeof(amss_path))
return ENOSPC; return ENOSPC;
@ -3813,6 +4090,28 @@ qwx_pci_intr_data_event(struct qwx_pci_softc *psc, struct qwx_pci_event_ring *ri
return 1; return 1;
} }
int
qwx_pci_intr_mhi_ctrl(void *arg)
{
struct qwx_pci_softc *psc = arg;
if (qwx_pci_intr_ctrl_event(psc, &psc->event_rings[0]))
return 1;
return 0;
}
int
qwx_pci_intr_mhi_data(void *arg)
{
struct qwx_pci_softc *psc = arg;
if (qwx_pci_intr_data_event(psc, &psc->event_rings[1]))
return 1;
return 0;
}
int int
qwx_pci_intr(void *arg) qwx_pci_intr(void *arg)
{ {
@ -3834,7 +4133,7 @@ qwx_pci_intr(void *arg)
MHI_STATUS_MHISTATE_SHFT; MHI_STATUS_MHISTATE_SHFT;
DNPRINTF(QWX_D_MHI, DNPRINTF(QWX_D_MHI,
"%s: MHI interrupt with EE: 0x%x -> 0x%x state: 0x%x -> 0x%x\n", "%s: BHI interrupt with EE: 0x%x -> 0x%x state: 0x%x -> 0x%x\n",
sc->sc_dev.dv_xname, psc->bhi_ee, ee, psc->mhi_state, state); sc->sc_dev.dv_xname, psc->bhi_ee, ee, psc->mhi_state, state);
if (ee == MHI_EE_RDDM) { if (ee == MHI_EE_RDDM) {
@ -3860,13 +4159,26 @@ qwx_pci_intr(void *arg)
ret = 1; ret = 1;
} }
if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, sc->sc_flags)) {
int i;
if (qwx_pci_intr_ctrl_event(psc, &psc->event_rings[0])) if (qwx_pci_intr_ctrl_event(psc, &psc->event_rings[0]))
ret = 1; ret = 1;
if (qwx_pci_intr_data_event(psc, &psc->event_rings[1])) if (qwx_pci_intr_data_event(psc, &psc->event_rings[1]))
ret = 1; ret = 1;
if (qwx_intr(sc)) for (i = 0; i < sc->hw_params.ce_count; i++) {
struct qwx_ce_pipe *ce_pipe = &sc->ce.ce_pipe[i];
if (qwx_ce_intr(ce_pipe))
ret = 1; ret = 1;
}
for (i = 0; i < nitems(sc->ext_irq_grp); i++) {
if (qwx_dp_service_srng(sc, i))
ret = 1;
}
}
return ret; return ret;
} }

View File

@ -25,11 +25,22 @@ THIS SOFTWARE.
This file lists all bug fixes, changes, etc., made since the This file lists all bug fixes, changes, etc., made since the
second edition of the AWK book was published in September 2023. second edition of the AWK book was published in September 2023.
Jan 22, 2024:
Restore the ability to compile with g++. Thanks to
Arnold Robbins.
Dec 24, 2023:
matchop dereference after free problem fix when the first
argument is a function call. thanks to Oguz Ismail Uysal.
Fix inconsistent handling of --csv and FS set in the
command line. Thanks to Wilbert van der Poel.
casting changes to int for is* functions.
Nov 27, 2023: Nov 27, 2023:
Fix exit status of system on MacOS. update to REGRESS. Fix exit status of system on MacOS. update to REGRESS.
Thanks to Arnold Robbins. Thanks to Arnold Robbins.
Fix inconsistent handling of -F and --csv, and loss of csv Fix inconsistent handling of -F and --csv, and loss of csv
mode when FS is set. Thanks to Wilbert van der Poel. mode when FS is set.
Nov 24, 2023: Nov 24, 2023:
Fix issue #199: gototab improvements to dynamically resize the Fix issue #199: gototab improvements to dynamically resize the

View File

@ -1,4 +1,4 @@
/* $OpenBSD: b.c,v 1.49 2023/11/25 16:31:33 millert Exp $ */ /* $OpenBSD: b.c,v 1.50 2024/01/25 16:40:51 millert Exp $ */
/**************************************************************** /****************************************************************
Copyright (C) Lucent Technologies 1997 Copyright (C) Lucent Technologies 1997
All Rights Reserved All Rights Reserved
@ -117,7 +117,7 @@ static int entry_cmp(const void *l, const void *r);
static int get_gototab(fa*, int, int); static int get_gototab(fa*, int, int);
static int set_gototab(fa*, int, int, int); static int set_gototab(fa*, int, int, int);
static void clear_gototab(fa*, int); static void clear_gototab(fa*, int);
extern int u8_rune(int *, const uschar *); extern int u8_rune(int *, const char *);
static int * static int *
intalloc(size_t n, const char *f) intalloc(size_t n, const char *f)
@ -422,7 +422,7 @@ int *cclenter(const char *argp) /* add a character class */
FATAL("out of space for character class [%.10s...] 1", p); FATAL("out of space for character class [%.10s...] 1", p);
bp = buf; bp = buf;
for (i = 0; *p != 0; ) { for (i = 0; *p != 0; ) {
n = u8_rune(&c, p); n = u8_rune(&c, (const char *) p);
p += n; p += n;
if (c == '\\') { if (c == '\\') {
c = quoted(&p); c = quoted(&p);
@ -430,7 +430,7 @@ int *cclenter(const char *argp) /* add a character class */
if (*p != 0) { if (*p != 0) {
c = bp[-1]; c = bp[-1];
/* c2 = *p++; */ /* c2 = *p++; */
n = u8_rune(&c2, p); n = u8_rune(&c2, (const char *) p);
p += n; p += n;
if (c2 == '\\') if (c2 == '\\')
c2 = quoted(&p); /* BUG: sets p, has to be u8 size */ c2 = quoted(&p); /* BUG: sets p, has to be u8 size */
@ -624,7 +624,7 @@ static int get_gototab(fa *f, int state, int ch) /* hide gototab inplementation
key.ch = ch; key.ch = ch;
key.state = 0; /* irrelevant */ key.state = 0; /* irrelevant */
item = bsearch(& key, f->gototab[state].entries, item = (gtte *) bsearch(& key, f->gototab[state].entries,
f->gototab[state].inuse, sizeof(gtte), f->gototab[state].inuse, sizeof(gtte),
entry_cmp); entry_cmp);
@ -668,7 +668,7 @@ static int set_gototab(fa *f, int state, int ch, int val) /* hide gototab inplem
key.ch = ch; key.ch = ch;
key.state = 0; /* irrelevant */ key.state = 0; /* irrelevant */
item = bsearch(& key, f->gototab[state].entries, item = (gtte *) bsearch(& key, f->gototab[state].entries,
f->gototab[state].inuse, sizeof(gtte), f->gototab[state].inuse, sizeof(gtte),
entry_cmp); entry_cmp);
@ -716,7 +716,7 @@ int match(fa *f, const char *p0) /* shortest match ? */
return(1); return(1);
do { do {
/* assert(*p < NCHARS); */ /* assert(*p < NCHARS); */
n = u8_rune(&rune, p); n = u8_rune(&rune, (const char *) p);
if ((ns = get_gototab(f, s, rune)) != 0) if ((ns = get_gototab(f, s, rune)) != 0)
s = ns; s = ns;
else else
@ -749,7 +749,7 @@ int pmatch(fa *f, const char *p0) /* longest match, for sub */
if (f->out[s]) /* final state */ if (f->out[s]) /* final state */
patlen = q-p; patlen = q-p;
/* assert(*q < NCHARS); */ /* assert(*q < NCHARS); */
n = u8_rune(&rune, q); n = u8_rune(&rune, (const char *) q);
if ((ns = get_gototab(f, s, rune)) != 0) if ((ns = get_gototab(f, s, rune)) != 0)
s = ns; s = ns;
else else
@ -780,7 +780,7 @@ int pmatch(fa *f, const char *p0) /* longest match, for sub */
s = 2; s = 2;
if (*p == 0) if (*p == 0)
break; break;
n = u8_rune(&rune, p); n = u8_rune(&rune, (const char *) p);
p += n; p += n;
} while (1); /* was *p++ */ } while (1); /* was *p++ */
return (0); return (0);
@ -805,7 +805,7 @@ int nematch(fa *f, const char *p0) /* non-empty match, for sub */
if (f->out[s]) /* final state */ if (f->out[s]) /* final state */
patlen = q-p; patlen = q-p;
/* assert(*q < NCHARS); */ /* assert(*q < NCHARS); */
n = u8_rune(&rune, q); n = u8_rune(&rune, (const char *) q);
if ((ns = get_gototab(f, s, rune)) != 0) if ((ns = get_gototab(f, s, rune)) != 0)
s = ns; s = ns;
else else
@ -893,7 +893,7 @@ bool fnematch(fa *pfa, FILE *f, char **pbuf, int *pbufsize, int quantum)
} }
} }
j += u8_rune(&c, (uschar *)j); j += u8_rune(&c, j);
if ((ns = get_gototab(pfa, s, c)) != 0) if ((ns = get_gototab(pfa, s, c)) != 0)
s = ns; s = ns;
@ -913,7 +913,7 @@ bool fnematch(fa *pfa, FILE *f, char **pbuf, int *pbufsize, int quantum)
break; /* best match found */ break; /* best match found */
/* no match at origin i, next i and start over */ /* no match at origin i, next i and start over */
i += u8_rune(&c, (uschar *)i); i += u8_rune(&c, i);
if (c == 0) if (c == 0)
break; /* no match */ break; /* no match */
j = i; j = i;
@ -1234,8 +1234,6 @@ static int repeat(const uschar *reptok, int reptoklen, const uschar *atom,
return 0; return 0;
} }
extern int u8_rune(int *, const uschar *); /* run.c; should be in header file */
int relex(void) /* lexical analyzer for reparse */ int relex(void) /* lexical analyzer for reparse */
{ {
int c, n; int c, n;
@ -1253,7 +1251,7 @@ int relex(void) /* lexical analyzer for reparse */
rescan: rescan:
starttok = prestr; starttok = prestr;
if ((n = u8_rune(&rlxval, prestr)) > 1) { if ((n = u8_rune(&rlxval, (const char *) prestr)) > 1) {
prestr += n; prestr += n;
starttok = prestr; starttok = prestr;
return CHAR; return CHAR;
@ -1300,7 +1298,7 @@ rescan:
if (!adjbuf((char **) &buf, &bufsz, n, n, (char **) &bp, "relex1")) if (!adjbuf((char **) &buf, &bufsz, n, n, (char **) &bp, "relex1"))
FATAL("out of space for reg expr %.10s...", lastre); FATAL("out of space for reg expr %.10s...", lastre);
for (; ; ) { for (; ; ) {
if ((n = u8_rune(&rlxval, prestr)) > 1) { if ((n = u8_rune(&rlxval, (const char *) prestr)) > 1) {
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
*bp++ = *prestr++; *bp++ = *prestr++;
continue; continue;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: main.c,v 1.67 2023/11/28 20:54:38 millert Exp $ */ /* $OpenBSD: main.c,v 1.68 2024/01/25 16:40:51 millert Exp $ */
/**************************************************************** /****************************************************************
Copyright (C) Lucent Technologies 1997 Copyright (C) Lucent Technologies 1997
All Rights Reserved All Rights Reserved
@ -23,7 +23,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE. THIS SOFTWARE.
****************************************************************/ ****************************************************************/
const char *version = "version 20231127"; const char *version = "version 20240122";
#define DEBUG #define DEBUG
#include <stdio.h> #include <stdio.h>
@ -180,8 +180,6 @@ int main(int argc, char *argv[])
} }
if (strcmp(argv[1], "--csv") == 0) { /* turn on csv input processing */ if (strcmp(argv[1], "--csv") == 0) { /* turn on csv input processing */
CSV = true; CSV = true;
if (fs)
WARNING("danger: don't set FS when --csv is in effect");
argc--; argc--;
argv++; argv++;
continue; continue;
@ -203,8 +201,6 @@ int main(int argc, char *argv[])
break; break;
case 'F': /* set field separator */ case 'F': /* set field separator */
fs = setfs(getarg(&argc, &argv, "no field separator")); fs = setfs(getarg(&argc, &argv, "no field separator"));
if (CSV)
WARNING("danger: don't set FS when --csv is in effect");
break; break;
case 'v': /* -v a=1 to be done NOW. one -v for each */ case 'v': /* -v a=1 to be done NOW. one -v for each */
vn = getarg(&argc, &argv, "no variable name"); vn = getarg(&argc, &argv, "no variable name");
@ -238,6 +234,9 @@ int main(int argc, char *argv[])
} }
} }
if (CSV && (fs != NULL || lookup("FS", symtab) != NULL))
WARNING("danger: don't set FS when --csv is in effect");
/* argv[1] is now the first argument */ /* argv[1] is now the first argument */
if (npfile == 0) { /* no -f; first argument is program */ if (npfile == 0) { /* no -f; first argument is program */
if (argc <= 1) { if (argc <= 1) {

View File

@ -1,4 +1,4 @@
/* $OpenBSD: run.c,v 1.83 2023/11/28 20:54:38 millert Exp $ */ /* $OpenBSD: run.c,v 1.84 2024/01/25 16:40:51 millert Exp $ */
/**************************************************************** /****************************************************************
Copyright (C) Lucent Technologies 1997 Copyright (C) Lucent Technologies 1997
All Rights Reserved All Rights Reserved
@ -796,7 +796,7 @@ int runetochar(char *str, int c)
Cell *matchop(Node **a, int n) /* ~ and match() */ Cell *matchop(Node **a, int n) /* ~ and match() */
{ {
Cell *x, *y; Cell *x, *y, *z;
char *s, *t; char *s, *t;
int i; int i;
int cstart, cpatlen, len; int cstart, cpatlen, len;
@ -818,7 +818,7 @@ Cell *matchop(Node **a, int n) /* ~ and match() */
i = (*mf)(pfa, s); i = (*mf)(pfa, s);
tempfree(y); tempfree(y);
} }
tempfree(x); z = x;
if (n == MATCHFCN) { if (n == MATCHFCN) {
int start = patbeg - s + 1; /* origin 1 */ int start = patbeg - s + 1; /* origin 1 */
if (patlen < 0) { if (patlen < 0) {
@ -840,11 +840,13 @@ Cell *matchop(Node **a, int n) /* ~ and match() */
x = gettemp(); x = gettemp();
x->tval = NUM; x->tval = NUM;
x->fval = start; x->fval = start;
return x;
} else if ((n == MATCH && i == 1) || (n == NOTMATCH && i == 0)) } else if ((n == MATCH && i == 1) || (n == NOTMATCH && i == 0))
return(True); x = True;
else else
return(False); x = False;
tempfree(z);
return x;
} }
@ -1299,7 +1301,8 @@ int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like co
if (bs == NULL) { // invalid character if (bs == NULL) { // invalid character
// use unicode invalid character, 0xFFFD // use unicode invalid character, 0xFFFD
bs = "\357\277\275"; static char invalid_char[] = "\357\277\275";
bs = invalid_char;
count = 3; count = 3;
} }
t = bs; t = bs;
@ -2567,7 +2570,7 @@ Cell *dosub(Node **a, int subop) /* sub and gsub */
start = getsval(x); start = getsval(x);
while (pmatch(pfa, start)) { while (pmatch(pfa, start)) {
if (buf == NULL) { if (buf == NULL) {
if ((pb = buf = malloc(bufsz)) == NULL) if ((pb = buf = (char *) malloc(bufsz)) == NULL)
FATAL("out of memory in dosub"); FATAL("out of memory in dosub");
tempstat = pfa->initstat; tempstat = pfa->initstat;
pfa->initstat = 2; pfa->initstat = 2;
@ -2672,7 +2675,7 @@ Cell *gensub(Node **a, int nnn) /* global selective substitute */
int mflag, tempstat, num, whichm; int mflag, tempstat, num, whichm;
int bufsz = recsize; int bufsz = recsize;
if ((buf = malloc(bufsz)) == NULL) if ((buf = (char *) malloc(bufsz)) == NULL)
FATAL("out of memory in gensub"); FATAL("out of memory in gensub");
mflag = 0; /* if mflag == 0, can replace empty string */ mflag = 0; /* if mflag == 0, can replace empty string */
num = 0; num = 0;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: bgpctl.c,v 1.301 2024/01/23 16:16:15 claudio Exp $ */ /* $OpenBSD: bgpctl.c,v 1.302 2024/01/25 09:54:21 claudio Exp $ */
/* /*
* Copyright (c) 2003 Henning Brauer <henning@openbsd.org> * Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
@ -470,6 +470,7 @@ show(struct imsg *imsg, struct parse_result *res)
struct flowspec f; struct flowspec f;
struct ctl_show_rib rib; struct ctl_show_rib rib;
struct rde_memstats stats; struct rde_memstats stats;
struct ibuf ibuf;
u_char *asdata; u_char *asdata;
u_int rescode, ilen; u_int rescode, ilen;
size_t aslen; size_t aslen;
@ -539,14 +540,11 @@ show(struct imsg *imsg, struct parse_result *res)
output->rib(&rib, asdata, aslen, res); output->rib(&rib, asdata, aslen, res);
break; break;
case IMSG_CTL_SHOW_RIB_COMMUNITIES: case IMSG_CTL_SHOW_RIB_COMMUNITIES:
ilen = imsg->hdr.len - IMSG_HEADER_SIZE;
if (ilen % sizeof(struct community)) {
warnx("bad IMSG_CTL_SHOW_RIB_COMMUNITIES received");
break;
}
if (output->communities == NULL) if (output->communities == NULL)
break; break;
output->communities(imsg->data, ilen, res); if (imsg_get_ibuf(imsg, &ibuf) == -1)
err(1, "imsg_get_ibuf");
output->communities(&ibuf, res);
break; break;
case IMSG_CTL_SHOW_RIB_ATTR: case IMSG_CTL_SHOW_RIB_ATTR:
ilen = imsg->hdr.len - IMSG_HEADER_SIZE; ilen = imsg->hdr.len - IMSG_HEADER_SIZE;
@ -1044,53 +1042,47 @@ fmt_large_community(uint32_t d1, uint32_t d2, uint32_t d3)
} }
const char * const char *
fmt_ext_community(uint8_t *data) fmt_ext_community(uint64_t ext)
{ {
static char buf[32]; static char buf[32];
uint64_t ext;
struct in_addr ip; struct in_addr ip;
uint32_t as4, u32; uint32_t as4, u32;
uint16_t as2, u16; uint16_t as2, u16;
uint8_t type, subtype; uint8_t type, subtype;
type = data[0]; type = ext >> 56;
subtype = data[1]; subtype = ext >> 48;
switch (type) { switch (type) {
case EXT_COMMUNITY_TRANS_TWO_AS: case EXT_COMMUNITY_TRANS_TWO_AS:
case EXT_COMMUNITY_GEN_TWO_AS: case EXT_COMMUNITY_GEN_TWO_AS:
memcpy(&as2, data + 2, sizeof(as2)); as2 = ext >> 32;
memcpy(&u32, data + 4, sizeof(u32)); u32 = ext;
snprintf(buf, sizeof(buf), "%s %s:%u", snprintf(buf, sizeof(buf), "%s %s:%u",
log_ext_subtype(type, subtype), log_ext_subtype(type, subtype), log_as(as2), u32);
log_as(ntohs(as2)), ntohl(u32));
return buf; return buf;
case EXT_COMMUNITY_TRANS_IPV4: case EXT_COMMUNITY_TRANS_IPV4:
case EXT_COMMUNITY_GEN_IPV4: case EXT_COMMUNITY_GEN_IPV4:
memcpy(&ip, data + 2, sizeof(ip)); ip.s_addr = htonl(ext >> 16);
memcpy(&u16, data + 6, sizeof(u16)); u16 = ext;
snprintf(buf, sizeof(buf), "%s %s:%hu", snprintf(buf, sizeof(buf), "%s %s:%hu",
log_ext_subtype(type, subtype), log_ext_subtype(type, subtype), inet_ntoa(ip), u16);
inet_ntoa(ip), ntohs(u16));
return buf; return buf;
case EXT_COMMUNITY_TRANS_FOUR_AS: case EXT_COMMUNITY_TRANS_FOUR_AS:
case EXT_COMMUNITY_GEN_FOUR_AS: case EXT_COMMUNITY_GEN_FOUR_AS:
memcpy(&as4, data + 2, sizeof(as4)); as4 = ext >> 16;
memcpy(&u16, data + 6, sizeof(u16)); u16 = ext;
snprintf(buf, sizeof(buf), "%s %s:%hu", snprintf(buf, sizeof(buf), "%s %s:%hu",
log_ext_subtype(type, subtype), log_ext_subtype(type, subtype), log_as(as4), u16);
log_as(ntohl(as4)), ntohs(u16));
return buf; return buf;
case EXT_COMMUNITY_TRANS_OPAQUE: case EXT_COMMUNITY_TRANS_OPAQUE:
case EXT_COMMUNITY_TRANS_EVPN: case EXT_COMMUNITY_TRANS_EVPN:
memcpy(&ext, data, sizeof(ext)); ext &= 0xffffffffffffULL;
ext = be64toh(ext) & 0xffffffffffffLL;
snprintf(buf, sizeof(buf), "%s 0x%llx", snprintf(buf, sizeof(buf), "%s 0x%llx",
log_ext_subtype(type, subtype), (unsigned long long)ext); log_ext_subtype(type, subtype), (unsigned long long)ext);
return buf; return buf;
case EXT_COMMUNITY_NON_TRANS_OPAQUE: case EXT_COMMUNITY_NON_TRANS_OPAQUE:
memcpy(&ext, data, sizeof(ext)); ext &= 0xffffffffffffULL;
ext = be64toh(ext) & 0xffffffffffffLL;
if (subtype == EXT_COMMUNITY_SUBTYPE_OVS) { if (subtype == EXT_COMMUNITY_SUBTYPE_OVS) {
switch (ext) { switch (ext) {
case EXT_COMMUNITY_OVS_VALID: case EXT_COMMUNITY_OVS_VALID:
@ -1119,10 +1111,7 @@ fmt_ext_community(uint8_t *data)
} }
break; break;
default: default:
memcpy(&ext, data, sizeof(ext)); snprintf(buf, sizeof(buf), "0x%llx", (unsigned long long)ext);
snprintf(buf, sizeof(buf), "%s 0x%llx",
log_ext_subtype(type, subtype),
(unsigned long long)be64toh(ext));
return buf; return buf;
} }
} }

View File

@ -1,4 +1,4 @@
/* $OpenBSD: bgpctl.h,v 1.21 2023/04/20 14:01:50 claudio Exp $ */ /* $OpenBSD: bgpctl.h,v 1.22 2024/01/25 09:54:21 claudio Exp $ */
/* /*
* Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org> * Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
@ -28,7 +28,7 @@ struct output {
void (*nexthop)(struct ctl_show_nexthop *); void (*nexthop)(struct ctl_show_nexthop *);
void (*interface)(struct ctl_show_interface *); void (*interface)(struct ctl_show_interface *);
void (*attr)(u_char *, size_t, int, int); void (*attr)(u_char *, size_t, int, int);
void (*communities)(u_char *, size_t, struct parse_result *); void (*communities)(struct ibuf *, struct parse_result *);
void (*rib)(struct ctl_show_rib *, u_char *, size_t, void (*rib)(struct ctl_show_rib *, u_char *, size_t,
struct parse_result *); struct parse_result *);
void (*rib_mem)(struct rde_memstats *); void (*rib_mem)(struct rde_memstats *);
@ -57,7 +57,7 @@ const char *fmt_errstr(uint8_t, uint8_t);
const char *fmt_attr(uint8_t, int); const char *fmt_attr(uint8_t, int);
const char *fmt_community(uint16_t, uint16_t); const char *fmt_community(uint16_t, uint16_t);
const char *fmt_large_community(uint32_t, uint32_t, uint32_t); const char *fmt_large_community(uint32_t, uint32_t, uint32_t);
const char *fmt_ext_community(uint8_t *); const char *fmt_ext_community(uint64_t);
const char *fmt_set_type(struct ctl_show_set *); const char *fmt_set_type(struct ctl_show_set *);
#define MPLS_LABEL_OFFSET 12 #define MPLS_LABEL_OFFSET 12

View File

@ -1,4 +1,4 @@
/* $OpenBSD: output.c,v 1.47 2024/01/23 16:16:15 claudio Exp $ */ /* $OpenBSD: output.c,v 1.48 2024/01/25 09:54:21 claudio Exp $ */
/* /*
* Copyright (c) 2003 Henning Brauer <henning@openbsd.org> * Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
@ -646,18 +646,17 @@ show_interface(struct ctl_show_interface *iface)
} }
static void static void
show_communities(u_char *data, size_t len, struct parse_result *res) show_communities(struct ibuf *data, struct parse_result *res)
{ {
struct community c; struct community c;
size_t i;
uint64_t ext; uint64_t ext;
uint8_t type = 0; uint8_t type = 0;
if (len % sizeof(c)) while (ibuf_size(data) != 0) {
return; if (ibuf_get(data, &c, sizeof(c)) == -1) {
warn("communities");
for (i = 0; i < len; i += sizeof(c)) { break;
memcpy(&c, data + i, sizeof(c)); }
if (type != c.flags) { if (type != c.flags) {
if (type != 0) if (type != 0)
@ -690,9 +689,7 @@ show_communities(u_char *data, size_t len, struct parse_result *res)
ext |= (uint64_t)c.data2 & 0xffff; ext |= (uint64_t)c.data2 & 0xffff;
break; break;
} }
ext = htobe64(ext); printf(" %s", fmt_ext_community(ext));
printf(" %s", fmt_ext_community((void *)&ext));
break; break;
} }
} }
@ -751,6 +748,7 @@ show_large_community(u_char *data, uint16_t len)
static void static void
show_ext_community(u_char *data, uint16_t len) show_ext_community(u_char *data, uint16_t len)
{ {
uint64_t ext;
uint16_t i; uint16_t i;
if (len & 0x7) { if (len & 0x7) {
@ -759,7 +757,9 @@ show_ext_community(u_char *data, uint16_t len)
} }
for (i = 0; i < len; i += 8) { for (i = 0; i < len; i += 8) {
printf("%s", fmt_ext_community(data + i)); memcpy(&ext, data + i, sizeof(ext));
ext = be64toh(ext);
printf("%s", fmt_ext_community(ext));
if (i + 8 < len) if (i + 8 < len)
printf(" "); printf(" ");

View File

@ -1,4 +1,4 @@
/* $OpenBSD: output_json.c,v 1.39 2024/01/23 16:16:15 claudio Exp $ */ /* $OpenBSD: output_json.c,v 1.40 2024/01/25 09:54:21 claudio Exp $ */
/* /*
* Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org> * Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org>
@ -465,20 +465,18 @@ json_interface(struct ctl_show_interface *iface)
} }
static void static void
json_communities(u_char *data, size_t len, struct parse_result *res) json_communities(struct ibuf *data, struct parse_result *res)
{ {
struct community c; struct community c;
size_t i;
uint64_t ext; uint64_t ext;
if (len % sizeof(c)) {
warnx("communities: bad size"); while (ibuf_size(data) != 0) {
if (ibuf_get(data, &c, sizeof(c)) == -1) {
warn("communities");
return; return;
} }
for (i = 0; i < len; i += sizeof(c)) {
memcpy(&c, data + i, sizeof(c));
switch (c.flags) { switch (c.flags) {
case COMMUNITY_TYPE_BASIC: case COMMUNITY_TYPE_BASIC:
json_do_array("communities"); json_do_array("communities");
@ -505,11 +503,9 @@ json_communities(u_char *data, size_t len, struct parse_result *res)
ext |= (uint64_t)c.data2 & 0xffff; ext |= (uint64_t)c.data2 & 0xffff;
break; break;
} }
ext = htobe64(ext);
json_do_array("extended_communities"); json_do_array("extended_communities");
json_do_string("community", json_do_string("community", fmt_ext_community(ext));
fmt_ext_community((void *)&ext));
break; break;
} }
} }
@ -569,6 +565,7 @@ json_do_large_community(u_char *data, uint16_t len)
static void static void
json_do_ext_community(u_char *data, uint16_t len) json_do_ext_community(u_char *data, uint16_t len)
{ {
uint64_t ext;
uint16_t i; uint16_t i;
if (len & 0x7) { if (len & 0x7) {
@ -578,8 +575,11 @@ json_do_ext_community(u_char *data, uint16_t len)
json_do_array("extended_communities"); json_do_array("extended_communities");
for (i = 0; i < len; i += 8) for (i = 0; i < len; i += 8) {
json_do_string("community", fmt_ext_community(data + i)); memcpy(&ext, data + i, sizeof(ext));
ext = be64toh(ext);
json_do_string("community", fmt_ext_community(ext));
}
json_do_end(); json_do_end();
} }

View File

@ -1,4 +1,4 @@
/* $OpenBSD: rde.c,v 1.617 2024/01/24 14:51:11 claudio Exp $ */ /* $OpenBSD: rde.c,v 1.619 2024/01/25 11:13:35 claudio Exp $ */
/* /*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -1932,7 +1932,7 @@ rde_attr_parse(struct ibuf *buf, struct rde_peer *peer,
{ {
struct bgpd_addr nexthop; struct bgpd_addr nexthop;
struct rde_aspath *a = &state->aspath; struct rde_aspath *a = &state->aspath;
struct ibuf attrbuf; struct ibuf attrbuf, tmpbuf;
u_char *p, *npath; u_char *p, *npath;
uint32_t tmp32, zero = 0; uint32_t tmp32, zero = 0;
int error; int error;
@ -1974,20 +1974,25 @@ rde_attr_parse(struct ibuf *buf, struct rde_peer *peer,
/* ignore and drop path attributes with a type code of 0 */ /* ignore and drop path attributes with a type code of 0 */
break; break;
case ATTR_ORIGIN: case ATTR_ORIGIN:
if (attr_len != 1)
goto bad_len;
if (!CHECK_FLAGS(flags, ATTR_WELL_KNOWN, 0)) if (!CHECK_FLAGS(flags, ATTR_WELL_KNOWN, 0))
goto bad_flags; goto bad_flags;
if (ibuf_size(&attrbuf) != 1)
UPD_READ(&a->origin, p, plen, 1); goto bad_len;
if (a->origin > ORIGIN_INCOMPLETE) {
rde_update_err(peer, ERR_UPDATE, ERR_UPD_ORIGIN,
&attrbuf);
return (-1);
}
if (a->flags & F_ATTR_ORIGIN) if (a->flags & F_ATTR_ORIGIN)
goto bad_list; goto bad_list;
if (ibuf_get_n8(&attrbuf, &a->origin) == -1)
goto bad_len;
if (a->origin > ORIGIN_INCOMPLETE) {
/*
* mark update as bad and withdraw all routes as per
* RFC 7606
*/
a->flags |= F_ATTR_PARSE_ERR;
log_peer_warnx(&peer->conf, "bad ORIGIN %u, "
"path invalidated and prefix withdrawn",
a->origin);
return (-1);
}
a->flags |= F_ATTR_ORIGIN; a->flags |= F_ATTR_ORIGIN;
break; break;
case ATTR_ASPATH: case ATTR_ASPATH:
@ -2033,17 +2038,19 @@ rde_attr_parse(struct ibuf *buf, struct rde_peer *peer,
plen += attr_len; plen += attr_len;
break; break;
case ATTR_NEXTHOP: case ATTR_NEXTHOP:
if (attr_len != 4)
goto bad_len;
if (!CHECK_FLAGS(flags, ATTR_WELL_KNOWN, 0)) if (!CHECK_FLAGS(flags, ATTR_WELL_KNOWN, 0))
goto bad_flags; goto bad_flags;
if (ibuf_size(&attrbuf) != 4)
goto bad_len;
if (a->flags & F_ATTR_NEXTHOP) if (a->flags & F_ATTR_NEXTHOP)
goto bad_list; goto bad_list;
a->flags |= F_ATTR_NEXTHOP; a->flags |= F_ATTR_NEXTHOP;
memset(&nexthop, 0, sizeof(nexthop)); memset(&nexthop, 0, sizeof(nexthop));
nexthop.aid = AID_INET; nexthop.aid = AID_INET;
UPD_READ(&nexthop.v4.s_addr, p, plen, 4); if (ibuf_get_h32(&attrbuf, &nexthop.v4.s_addr) == -1)
goto bad_len;
/* /*
* Check if the nexthop is a valid IP address. We consider * Check if the nexthop is a valid IP address. We consider
* multicast addresses as invalid. * multicast addresses as invalid.
@ -2058,80 +2065,77 @@ rde_attr_parse(struct ibuf *buf, struct rde_peer *peer,
state->nexthop = nexthop_get(&nexthop); state->nexthop = nexthop_get(&nexthop);
break; break;
case ATTR_MED: case ATTR_MED:
if (attr_len != 4)
goto bad_len;
if (!CHECK_FLAGS(flags, ATTR_OPTIONAL, 0)) if (!CHECK_FLAGS(flags, ATTR_OPTIONAL, 0))
goto bad_flags; goto bad_flags;
if (ibuf_size(&attrbuf) != 4)
goto bad_len;
if (a->flags & F_ATTR_MED) if (a->flags & F_ATTR_MED)
goto bad_list; goto bad_list;
if (ibuf_get_n32(&attrbuf, &a->med) == -1)
goto bad_len;
a->flags |= F_ATTR_MED; a->flags |= F_ATTR_MED;
UPD_READ(&tmp32, p, plen, 4);
a->med = ntohl(tmp32);
break; break;
case ATTR_LOCALPREF: case ATTR_LOCALPREF:
if (attr_len != 4)
goto bad_len;
if (!CHECK_FLAGS(flags, ATTR_WELL_KNOWN, 0)) if (!CHECK_FLAGS(flags, ATTR_WELL_KNOWN, 0))
goto bad_flags; goto bad_flags;
if (ibuf_size(&attrbuf) != 4)
goto bad_len;
if (peer->conf.ebgp) { if (peer->conf.ebgp) {
/* ignore local-pref attr on non ibgp peers */ /* ignore local-pref attr on non ibgp peers */
plen += attr_len;
break; break;
} }
if (a->flags & F_ATTR_LOCALPREF) if (a->flags & F_ATTR_LOCALPREF)
goto bad_list; goto bad_list;
if (ibuf_get_n32(&attrbuf, &a->lpref) == -1)
goto bad_len;
a->flags |= F_ATTR_LOCALPREF; a->flags |= F_ATTR_LOCALPREF;
UPD_READ(&tmp32, p, plen, 4);
a->lpref = ntohl(tmp32);
break; break;
case ATTR_ATOMIC_AGGREGATE: case ATTR_ATOMIC_AGGREGATE:
if (attr_len != 0)
goto bad_len;
if (!CHECK_FLAGS(flags, ATTR_WELL_KNOWN, 0)) if (!CHECK_FLAGS(flags, ATTR_WELL_KNOWN, 0))
goto bad_flags; goto bad_flags;
if (ibuf_size(&attrbuf) != 0)
goto bad_len;
goto optattr; goto optattr;
case ATTR_AGGREGATOR: case ATTR_AGGREGATOR:
if ((!peer_has_as4byte(peer) && attr_len != 6) || if (!CHECK_FLAGS(flags, ATTR_OPTIONAL|ATTR_TRANSITIVE,
(peer_has_as4byte(peer) && attr_len != 8)) { ATTR_PARTIAL))
goto bad_flags;
if ((!peer_has_as4byte(peer) && ibuf_size(&attrbuf) != 6) ||
(peer_has_as4byte(peer) && ibuf_size(&attrbuf) != 8)) {
/* /*
* ignore attribute in case of error as per * ignore attribute in case of error as per
* RFC 7606 * RFC 7606
*/ */
log_peer_warnx(&peer->conf, "bad AGGREGATOR, " log_peer_warnx(&peer->conf, "bad AGGREGATOR, "
"attribute discarded"); "attribute discarded");
plen += attr_len;
break; break;
} }
if (!CHECK_FLAGS(flags, ATTR_OPTIONAL|ATTR_TRANSITIVE,
ATTR_PARTIAL))
goto bad_flags;
if (!peer_has_as4byte(peer)) { if (!peer_has_as4byte(peer)) {
/* need to inflate aggregator AS to 4-byte */ /* need to inflate aggregator AS to 4-byte */
u_char t[8]; u_char t[8];
t[0] = t[1] = 0; t[0] = t[1] = 0;
UPD_READ(&t[2], p, plen, 2); if (ibuf_get(&attrbuf, &t[2], 6) == -1)
UPD_READ(&t[4], p, plen, 4); goto bad_list;
if (memcmp(t, &zero, sizeof(uint32_t)) == 0) { if (memcmp(t, &zero, sizeof(uint32_t)) == 0) {
/* As per RFC7606 use "attribute discard". */ /* As per RFC7606 use "attribute discard". */
log_peer_warnx(&peer->conf, "bad AGGREGATOR, " log_peer_warnx(&peer->conf, "bad AGGREGATOR, "
"AS 0 not allowed, attribute discarded"); "AS 0 not allowed, attribute discarded");
break; break;
} }
if (attr_optadd(a, flags, type, t, if (attr_optadd(a, flags, type, t, sizeof(t)) == -1)
sizeof(t)) == -1)
goto bad_list; goto bad_list;
break; break;
} }
/* 4-byte ready server take the default route */ /* 4-byte ready server take the default route */
if (memcmp(p, &zero, sizeof(uint32_t)) == 0) { ibuf_from_ibuf(&tmpbuf, &attrbuf);
if (ibuf_get_n32(&tmpbuf, &tmp32) == -1)
goto bad_len;
if (tmp32 == 0) {
/* As per RFC7606 use "attribute discard" here. */ /* As per RFC7606 use "attribute discard" here. */
char *pfmt = log_fmt_peer(&peer->conf); char *pfmt = log_fmt_peer(&peer->conf);
log_debug("%s: bad AGGREGATOR, " log_debug("%s: bad AGGREGATOR, "
"AS 0 not allowed, attribute discarded", pfmt); "AS 0 not allowed, attribute discarded", pfmt);
free(pfmt); free(pfmt);
plen += attr_len;
break; break;
} }
goto optattr; goto optattr;
@ -2181,22 +2185,22 @@ rde_attr_parse(struct ibuf *buf, struct rde_peer *peer,
} }
break; break;
case ATTR_ORIGINATOR_ID: case ATTR_ORIGINATOR_ID:
if (attr_len != 4)
goto bad_len;
if (!CHECK_FLAGS(flags, ATTR_OPTIONAL, 0)) if (!CHECK_FLAGS(flags, ATTR_OPTIONAL, 0))
goto bad_flags; goto bad_flags;
if (ibuf_size(&attrbuf) != 4)
goto bad_len;
goto optattr; goto optattr;
case ATTR_CLUSTER_LIST: case ATTR_CLUSTER_LIST:
if (attr_len % 4 != 0)
goto bad_len;
if (!CHECK_FLAGS(flags, ATTR_OPTIONAL, 0)) if (!CHECK_FLAGS(flags, ATTR_OPTIONAL, 0))
goto bad_flags; goto bad_flags;
if (ibuf_size(&attrbuf) % 4 != 0)
goto bad_len;
goto optattr; goto optattr;
case ATTR_MP_REACH_NLRI: case ATTR_MP_REACH_NLRI:
if (attr_len < 5)
goto bad_len;
if (!CHECK_FLAGS(flags, ATTR_OPTIONAL, 0)) if (!CHECK_FLAGS(flags, ATTR_OPTIONAL, 0))
goto bad_flags; goto bad_flags;
if (ibuf_size(&attrbuf) < 5)
goto bad_len;
/* the validity is checked in rde_update_dispatch() */ /* the validity is checked in rde_update_dispatch() */
if (a->flags & F_ATTR_MP_REACH) if (a->flags & F_ATTR_MP_REACH)
goto bad_list; goto bad_list;
@ -2205,10 +2209,10 @@ rde_attr_parse(struct ibuf *buf, struct rde_peer *peer,
*reach = attrbuf; *reach = attrbuf;
break; break;
case ATTR_MP_UNREACH_NLRI: case ATTR_MP_UNREACH_NLRI:
if (attr_len < 3)
goto bad_len;
if (!CHECK_FLAGS(flags, ATTR_OPTIONAL, 0)) if (!CHECK_FLAGS(flags, ATTR_OPTIONAL, 0))
goto bad_flags; goto bad_flags;
if (ibuf_size(&attrbuf) < 3)
goto bad_len;
/* the validity is checked in rde_update_dispatch() */ /* the validity is checked in rde_update_dispatch() */
if (a->flags & F_ATTR_MP_UNREACH) if (a->flags & F_ATTR_MP_UNREACH)
goto bad_list; goto bad_list;
@ -2217,21 +2221,22 @@ rde_attr_parse(struct ibuf *buf, struct rde_peer *peer,
*unreach = attrbuf; *unreach = attrbuf;
break; break;
case ATTR_AS4_AGGREGATOR: case ATTR_AS4_AGGREGATOR:
if (attr_len != 8) {
/* see ATTR_AGGREGATOR ... */
log_peer_warnx(&peer->conf, "bad AS4_AGGREGATOR, "
"attribute discarded");
plen += attr_len;
break;
}
if (!CHECK_FLAGS(flags, ATTR_OPTIONAL|ATTR_TRANSITIVE, if (!CHECK_FLAGS(flags, ATTR_OPTIONAL|ATTR_TRANSITIVE,
ATTR_PARTIAL)) ATTR_PARTIAL))
goto bad_flags; goto bad_flags;
if (memcmp(p, &zero, sizeof(uint32_t)) == 0) { if (ibuf_size(&attrbuf) != 8) {
/* see ATTR_AGGREGATOR ... */
log_peer_warnx(&peer->conf, "bad AS4_AGGREGATOR, "
"attribute discarded");
break;
}
ibuf_from_ibuf(&tmpbuf, &attrbuf);
if (ibuf_get_n32(&tmpbuf, &tmp32) == -1)
goto bad_len;
if (tmp32 == 0) {
/* As per RFC6793 use "attribute discard" here. */ /* As per RFC6793 use "attribute discard" here. */
log_peer_warnx(&peer->conf, "bad AS4_AGGREGATOR, " log_peer_warnx(&peer->conf, "bad AS4_AGGREGATOR, "
"AS 0 not allowed, attribute discarded"); "AS 0 not allowed, attribute discarded");
plen += attr_len;
break; break;
} }
a->flags |= F_ATTR_AS4BYTE_NEW; a->flags |= F_ATTR_AS4BYTE_NEW;
@ -2251,25 +2256,24 @@ rde_attr_parse(struct ibuf *buf, struct rde_peer *peer,
a->flags |= F_ATTR_AS4BYTE_NEW; a->flags |= F_ATTR_AS4BYTE_NEW;
goto optattr; goto optattr;
case ATTR_OTC: case ATTR_OTC:
if (attr_len != 4) { if (!CHECK_FLAGS(flags, ATTR_OPTIONAL|ATTR_TRANSITIVE,
ATTR_PARTIAL))
goto bad_flags;
if (ibuf_size(&attrbuf) != 4) {
/* treat-as-withdraw */ /* treat-as-withdraw */
a->flags |= F_ATTR_PARSE_ERR; a->flags |= F_ATTR_PARSE_ERR;
log_peer_warnx(&peer->conf, "bad OTC, " log_peer_warnx(&peer->conf, "bad OTC, "
"path invalidated and prefix withdrawn"); "path invalidated and prefix withdrawn");
plen += attr_len;
break; break;
} }
if (!CHECK_FLAGS(flags, ATTR_OPTIONAL|ATTR_TRANSITIVE,
ATTR_PARTIAL))
goto bad_flags;
switch (peer->role) { switch (peer->role) {
case ROLE_PROVIDER: case ROLE_PROVIDER:
case ROLE_RS: case ROLE_RS:
a->flags |= F_ATTR_OTC_LEAK; a->flags |= F_ATTR_OTC_LEAK;
break; break;
case ROLE_PEER: case ROLE_PEER:
memcpy(&tmp32, p, sizeof(tmp32)); if (ibuf_get_n32(&attrbuf, &tmp32) == -1)
tmp32 = ntohl(tmp32); goto bad_len;
if (tmp32 != peer->conf.remote_as) if (tmp32 != peer->conf.remote_as)
a->flags |= F_ATTR_OTC_LEAK; a->flags |= F_ATTR_OTC_LEAK;
break; break;
@ -2285,10 +2289,9 @@ rde_attr_parse(struct ibuf *buf, struct rde_peer *peer,
return (-1); return (-1);
} }
optattr: optattr:
if (attr_optadd(a, flags, type, p, attr_len) == -1) if (attr_optadd(a, flags, type, ibuf_data(&attrbuf),
ibuf_size(&attrbuf)) == -1)
goto bad_list; goto bad_list;
plen += attr_len;
break; break;
} }