Merge ^/head r343202 through r343319.
This commit is contained in:
commit
88148a071b
@ -1,9 +1,6 @@
|
||||
# $FreeBSD$
|
||||
#
|
||||
# System-wide .login file for csh(1).
|
||||
# Uncomment this to give you the default 4.2 behavior, where disk
|
||||
# information is shown in K-Blocks
|
||||
# setenv BLOCKSIZE K
|
||||
#
|
||||
# For the setting of languages and character sets please see
|
||||
# login.conf(5) and in particular the charset and lang options.
|
||||
|
@ -19,7 +19,6 @@ set path = (/sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin $HOME/b
|
||||
|
||||
setenv EDITOR vi
|
||||
setenv PAGER less
|
||||
setenv BLOCKSIZE K
|
||||
|
||||
if ($?prompt) then
|
||||
# An interactive shell -- set some stuff up
|
||||
|
@ -67,7 +67,7 @@ __FBSDID("$FreeBSD$");
|
||||
History *hist; /* history cookie */
|
||||
EditLine *el; /* editline cookie */
|
||||
int displayhist;
|
||||
static FILE *el_in, *el_out, *el_err;
|
||||
static FILE *el_in, *el_out;
|
||||
|
||||
static char *fc_replace(const char *, char *, char *);
|
||||
static int not_fcnumber(const char *);
|
||||
@ -106,18 +106,16 @@ histedit(void)
|
||||
INTOFF;
|
||||
if (el_in == NULL)
|
||||
el_in = fdopen(0, "r");
|
||||
if (el_err == NULL)
|
||||
el_err = fdopen(1, "w");
|
||||
if (el_out == NULL)
|
||||
el_out = fdopen(2, "w");
|
||||
if (el_in == NULL || el_err == NULL || el_out == NULL)
|
||||
if (el_in == NULL || el_out == NULL)
|
||||
goto bad;
|
||||
term = lookupvar("TERM");
|
||||
if (term)
|
||||
setenv("TERM", term, 1);
|
||||
else
|
||||
unsetenv("TERM");
|
||||
el = el_init(arg0, el_in, el_out, el_err);
|
||||
el = el_init(arg0, el_in, el_out, el_out);
|
||||
if (el != NULL) {
|
||||
if (hist)
|
||||
el_set(el, EL_HIST, history, hist);
|
||||
|
@ -2,10 +2,6 @@
|
||||
#
|
||||
# System-wide .profile file for sh(1).
|
||||
#
|
||||
# Uncomment this to give you the default 4.2 behavior, where disk
|
||||
# information is shown in K-Blocks
|
||||
# BLOCKSIZE=K; export BLOCKSIZE
|
||||
#
|
||||
# For the setting of languages and character sets please see
|
||||
# login.conf(5) and in particular the charset and lang options.
|
||||
# For full locales list check /usr/share/locale/*
|
||||
|
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd November 4, 2018
|
||||
.Dd January 21, 2019
|
||||
.Dt CAPSICUM_HELPERS 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -50,11 +50,13 @@
|
||||
.Ft int
|
||||
.Fn caph_enter_casper "void"
|
||||
.Ft int
|
||||
.Fn caph_rights_limit "inf fd" "const cap_righst_t *rights"
|
||||
.Fn caph_rights_limit "int fd" "const cap_righst_t *rights"
|
||||
.Ft int
|
||||
.Fn caph_ioctls_limit "inf fd" "const unsigned long *cmds" "size_t ncmds"
|
||||
.Fn caph_ioctls_limit "int fd" "const unsigned long *cmds" "size_t ncmds"
|
||||
.Ft int
|
||||
.Fn caph_fcntls_limit "inf fd" "uint32_t fcntlrights"
|
||||
.Fn caph_fcntls_limit "int fd" "uint32_t fcntlrights"
|
||||
.Ft int
|
||||
.Fn caph_limit_stream "int fd" "int flags"
|
||||
.Ft int
|
||||
.Fn caph_limit_stdin "void"
|
||||
.Ft int
|
||||
|
@ -23,8 +23,8 @@ options {
|
||||
esp|ida|iir|ips|isp|mlx|mly|mpr|mps|mpt|sym|trm)\
|
||||
[0-9]+";
|
||||
set wifi-driver-regex
|
||||
"(ath|bwi|bwn|ipw|iwi|iwm|iwn|malo|mwl|ral|rsu|rtwn|rum|run|\
|
||||
uath|upgt|ural|urtw|wi|wpi|wtap|zyd)[0-9]+";
|
||||
"(ath|bwi|bwn|ipw|iwi|iwm|iwn|malo|mwl|otus|ral|rsu|rtwn|rum|\
|
||||
run|uath|upgt|ural|urtw|wi|wpi|wtap|zyd)[0-9]+";
|
||||
};
|
||||
|
||||
# Note that the attach/detach with the highest value wins, so that one can
|
||||
@ -43,7 +43,7 @@ options {
|
||||
#
|
||||
notify 0 {
|
||||
match "system" "IFNET";
|
||||
match "subsystem" "!usbus[0-9]+";
|
||||
match "subsystem" "(?!usbus[0-9]+|?!wlan[0-9]+)";
|
||||
match "type" "ATTACH";
|
||||
action "/etc/pccard_ether $subsystem start";
|
||||
};
|
||||
|
@ -77,6 +77,7 @@
|
||||
#include <net80211/ieee80211_superg.h>
|
||||
#include <net80211/ieee80211_tdma.h>
|
||||
#include <net80211/ieee80211_mesh.h>
|
||||
#include <net80211/ieee80211_wps.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
@ -3129,13 +3130,6 @@ printrsnie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX move to a public include file */
|
||||
#define IEEE80211_WPS_DEV_PASS_ID 0x1012
|
||||
#define IEEE80211_WPS_SELECTED_REG 0x1041
|
||||
#define IEEE80211_WPS_SETUP_STATE 0x1044
|
||||
#define IEEE80211_WPS_UUID_E 0x1047
|
||||
#define IEEE80211_WPS_VERSION 0x104a
|
||||
|
||||
#define BE_READ_2(p) \
|
||||
((u_int16_t) \
|
||||
((((const u_int8_t *)(p))[1] ) | \
|
||||
@ -3157,6 +3151,7 @@ printwpsie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
|
||||
"R" /* Registrar-specified */
|
||||
};
|
||||
int n;
|
||||
int f;
|
||||
|
||||
ie +=6, len -= 4; /* NB: len is payload only */
|
||||
|
||||
@ -3165,6 +3160,7 @@ printwpsie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
|
||||
while (len) {
|
||||
uint16_t tlv_type = BE_READ_2(ie);
|
||||
uint16_t tlv_len = BE_READ_2(ie + 2);
|
||||
uint16_t cfg_mthd;
|
||||
|
||||
/* some devices broadcast invalid WPS frames */
|
||||
if (tlv_len > len) {
|
||||
@ -3177,30 +3173,191 @@ printwpsie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
|
||||
ie += 4, len -= 4;
|
||||
|
||||
switch (tlv_type) {
|
||||
case IEEE80211_WPS_VERSION:
|
||||
case IEEE80211_WPS_ATTR_VERSION:
|
||||
printf("v:%d.%d", *ie >> 4, *ie & 0xf);
|
||||
break;
|
||||
case IEEE80211_WPS_SETUP_STATE:
|
||||
/* Only 1 and 2 are valid */
|
||||
if (*ie == 0 || *ie >= 3)
|
||||
printf(" state:B");
|
||||
case IEEE80211_WPS_ATTR_AP_SETUP_LOCKED:
|
||||
printf(" ap_setup:%s", *ie ? "locked" :
|
||||
"unlocked");
|
||||
break;
|
||||
case IEEE80211_WPS_ATTR_CONFIG_METHODS:
|
||||
case IEEE80211_WPS_ATTR_SELECTED_REGISTRAR_CONFIG_METHODS:
|
||||
if (tlv_type == IEEE80211_WPS_ATTR_SELECTED_REGISTRAR_CONFIG_METHODS)
|
||||
printf(" sel_reg_cfg_mthd:");
|
||||
else
|
||||
printf(" st:%s", *ie == 1 ? "N" : "C");
|
||||
printf(" cfg_mthd:" );
|
||||
cfg_mthd = BE_READ_2(ie);
|
||||
f = 0;
|
||||
for (n = 15; n >= 0; n--) {
|
||||
if (f) {
|
||||
printf(",");
|
||||
f = 0;
|
||||
}
|
||||
switch (cfg_mthd & (1 << n)) {
|
||||
case 0:
|
||||
break;
|
||||
case IEEE80211_WPS_CONFIG_USBA:
|
||||
printf("usba");
|
||||
f++;
|
||||
break;
|
||||
case IEEE80211_WPS_CONFIG_ETHERNET:
|
||||
printf("ethernet");
|
||||
f++;
|
||||
break;
|
||||
case IEEE80211_WPS_CONFIG_LABEL:
|
||||
printf("label");
|
||||
f++;
|
||||
break;
|
||||
case IEEE80211_WPS_CONFIG_DISPLAY:
|
||||
if (!(cfg_mthd &
|
||||
(IEEE80211_WPS_CONFIG_VIRT_DISPLAY |
|
||||
IEEE80211_WPS_CONFIG_PHY_DISPLAY)))
|
||||
{
|
||||
printf("display");
|
||||
f++;
|
||||
}
|
||||
break;
|
||||
case IEEE80211_WPS_CONFIG_EXT_NFC_TOKEN:
|
||||
printf("ext_nfc_tokenk");
|
||||
f++;
|
||||
break;
|
||||
case IEEE80211_WPS_CONFIG_INT_NFC_TOKEN:
|
||||
printf("int_nfc_token");
|
||||
f++;
|
||||
break;
|
||||
case IEEE80211_WPS_CONFIG_NFC_INTERFACE:
|
||||
printf("nfc_interface");
|
||||
f++;
|
||||
break;
|
||||
case IEEE80211_WPS_CONFIG_PUSHBUTTON:
|
||||
if (!(cfg_mthd &
|
||||
(IEEE80211_WPS_CONFIG_VIRT_PUSHBUTTON |
|
||||
IEEE80211_WPS_CONFIG_PHY_PUSHBUTTON))) {
|
||||
printf("push_button");
|
||||
f++;
|
||||
}
|
||||
break;
|
||||
case IEEE80211_WPS_CONFIG_KEYPAD:
|
||||
printf("keypad");
|
||||
f++;
|
||||
break;
|
||||
case IEEE80211_WPS_CONFIG_VIRT_PUSHBUTTON:
|
||||
printf("virtual_push_button");
|
||||
f++;
|
||||
break;
|
||||
case IEEE80211_WPS_CONFIG_PHY_PUSHBUTTON:
|
||||
printf("physical_push_button");
|
||||
f++;
|
||||
break;
|
||||
case IEEE80211_WPS_CONFIG_P2PS:
|
||||
printf("p2ps");
|
||||
f++;
|
||||
break;
|
||||
case IEEE80211_WPS_CONFIG_VIRT_DISPLAY:
|
||||
printf("virtual_display");
|
||||
f++;
|
||||
break;
|
||||
case IEEE80211_WPS_CONFIG_PHY_DISPLAY:
|
||||
printf("physical_display");
|
||||
f++;
|
||||
break;
|
||||
default:
|
||||
printf("unknown_wps_config<%04x>",
|
||||
cfg_mthd & (1 << n));
|
||||
f++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IEEE80211_WPS_SELECTED_REG:
|
||||
printf(" sel:%s", *ie ? "T" : "F");
|
||||
case IEEE80211_WPS_ATTR_DEV_NAME:
|
||||
printf(" device_name:<%.*s>", tlv_len, ie);
|
||||
break;
|
||||
case IEEE80211_WPS_DEV_PASS_ID:
|
||||
case IEEE80211_WPS_ATTR_DEV_PASSWORD_ID:
|
||||
n = LE_READ_2(ie);
|
||||
if (n < nitems(dev_pass_id))
|
||||
printf(" dpi:%s", dev_pass_id[n]);
|
||||
break;
|
||||
case IEEE80211_WPS_UUID_E:
|
||||
case IEEE80211_WPS_ATTR_MANUFACTURER:
|
||||
printf(" manufacturer:<%.*s>", tlv_len, ie);
|
||||
break;
|
||||
case IEEE80211_WPS_ATTR_MODEL_NAME:
|
||||
printf(" model_name:<%.*s>", tlv_len, ie);
|
||||
break;
|
||||
case IEEE80211_WPS_ATTR_MODEL_NUMBER:
|
||||
printf(" model_number:<%.*s>", tlv_len, ie);
|
||||
break;
|
||||
case IEEE80211_WPS_ATTR_PRIMARY_DEV_TYPE:
|
||||
printf(" prim_dev:");
|
||||
for (n = 0; n < tlv_len; n++)
|
||||
printf("%02x", ie[n]);
|
||||
break;
|
||||
case IEEE80211_WPS_ATTR_RF_BANDS:
|
||||
printf(" rf:");
|
||||
f = 0;
|
||||
for (n = 7; n >= 0; n--) {
|
||||
if (f) {
|
||||
printf(",");
|
||||
f = 0;
|
||||
}
|
||||
switch (*ie & (1 << n)) {
|
||||
case 0:
|
||||
break;
|
||||
case IEEE80211_WPS_RF_BAND_24GHZ:
|
||||
printf("2.4Ghz");
|
||||
f++;
|
||||
break;
|
||||
case IEEE80211_WPS_RF_BAND_50GHZ:
|
||||
printf("5Ghz");
|
||||
f++;
|
||||
break;
|
||||
case IEEE80211_WPS_RF_BAND_600GHZ:
|
||||
printf("60Ghz");
|
||||
f++;
|
||||
break;
|
||||
default:
|
||||
printf("unknown<%02x>",
|
||||
*ie & (1 << n));
|
||||
f++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IEEE80211_WPS_ATTR_RESPONSE_TYPE:
|
||||
printf(" resp_type:0x%02x", *ie);
|
||||
break;
|
||||
case IEEE80211_WPS_ATTR_SELECTED_REGISTRAR:
|
||||
printf(" sel:%s", *ie ? "T" : "F");
|
||||
break;
|
||||
case IEEE80211_WPS_ATTR_SERIAL_NUMBER:
|
||||
printf(" serial_number:<%.*s>", tlv_len, ie);
|
||||
break;
|
||||
case IEEE80211_WPS_ATTR_UUID_E:
|
||||
printf(" uuid-e:");
|
||||
for (n = 0; n < (tlv_len - 1); n++)
|
||||
printf("%02x-", ie[n]);
|
||||
printf("%02x", ie[n]);
|
||||
break;
|
||||
case IEEE80211_WPS_ATTR_VENDOR_EXT:
|
||||
printf(" vendor:");
|
||||
for (n = 0; n < tlv_len; n++)
|
||||
printf("%02x", ie[n]);
|
||||
break;
|
||||
case IEEE80211_WPS_ATTR_WPS_STATE:
|
||||
switch (*ie) {
|
||||
case IEEE80211_WPS_STATE_NOT_CONFIGURED:
|
||||
printf(" state:N");
|
||||
break;
|
||||
case IEEE80211_WPS_STATE_CONFIGURED:
|
||||
printf(" state:C");
|
||||
break;
|
||||
default:
|
||||
printf(" state:B<%02x>", *ie);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf(" unknown_wps_attr:0x%x", tlv_type);
|
||||
break;
|
||||
}
|
||||
ie += tlv_len, len -= tlv_len;
|
||||
}
|
||||
@ -3353,6 +3510,7 @@ iswpsoui(const uint8_t *frm)
|
||||
static const char *
|
||||
iename(int elemid)
|
||||
{
|
||||
static char iename_buf[64];
|
||||
switch (elemid) {
|
||||
case IEEE80211_ELEMID_FHPARMS: return " FHPARMS";
|
||||
case IEEE80211_ELEMID_CFPARMS: return " CFPARMS";
|
||||
@ -3370,10 +3528,21 @@ iename(int elemid)
|
||||
case IEEE80211_ELEMID_MEASREP: return " MEASREP";
|
||||
case IEEE80211_ELEMID_QUIET: return " QUIET";
|
||||
case IEEE80211_ELEMID_IBSSDFS: return " IBSSDFS";
|
||||
case IEEE80211_ELEMID_RESERVED_47:
|
||||
return " RESERVED_47";
|
||||
case IEEE80211_ELEMID_MOBILITY_DOMAIN:
|
||||
return " MOBILITY_DOMAIN";
|
||||
case IEEE80211_ELEMID_RRM_ENACAPS:
|
||||
return " RRM_ENCAPS";
|
||||
case IEEE80211_ELEMID_OVERLAP_BSS_SCAN_PARAM:
|
||||
return " OVERLAP_BSS";
|
||||
case IEEE80211_ELEMID_TPC: return " TPC";
|
||||
case IEEE80211_ELEMID_CCKM: return " CCKM";
|
||||
case IEEE80211_ELEMID_EXTCAP: return " EXTCAP";
|
||||
}
|
||||
return " ???";
|
||||
snprintf(iename_buf, sizeof(iename_buf), " UNKNOWN_ELEMID_%d",
|
||||
elemid);
|
||||
return (const char *) iename_buf;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -114,7 +114,6 @@ extern int loadopt;
|
||||
|
||||
int check_commit_altq(int, int);
|
||||
void pfaltq_store(struct pf_altq *);
|
||||
struct pf_altq *pfaltq_lookup(const char *);
|
||||
char *rate2str(double);
|
||||
|
||||
void print_addr(struct pf_addr_wrap *, sa_family_t, int);
|
||||
|
@ -24,6 +24,7 @@ __FBSDID("$FreeBSD$");
|
||||
#define PFIOC_USE_LATEST
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/bitset.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
@ -36,6 +37,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <search.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -53,38 +55,44 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#define is_sc_null(sc) (((sc) == NULL) || ((sc)->m1 == 0 && (sc)->m2 == 0))
|
||||
|
||||
static TAILQ_HEAD(altqs, pf_altq) altqs = TAILQ_HEAD_INITIALIZER(altqs);
|
||||
static LIST_HEAD(gen_sc, segment) rtsc, lssc;
|
||||
static STAILQ_HEAD(interfaces, pfctl_altq) interfaces = STAILQ_HEAD_INITIALIZER(interfaces);
|
||||
static struct hsearch_data queue_map;
|
||||
static struct hsearch_data if_map;
|
||||
static struct hsearch_data qid_map;
|
||||
|
||||
struct pf_altq *qname_to_pfaltq(const char *, const char *);
|
||||
u_int32_t qname_to_qid(const char *);
|
||||
static struct pfctl_altq *pfaltq_lookup(char *ifname);
|
||||
static struct pfctl_altq *qname_to_pfaltq(const char *, const char *);
|
||||
static u_int32_t qname_to_qid(char *);
|
||||
|
||||
static int eval_pfqueue_cbq(struct pfctl *, struct pf_altq *);
|
||||
static int eval_pfqueue_cbq(struct pfctl *, struct pf_altq *,
|
||||
struct pfctl_altq *);
|
||||
static int cbq_compute_idletime(struct pfctl *, struct pf_altq *);
|
||||
static int check_commit_cbq(int, int, struct pf_altq *);
|
||||
static int check_commit_cbq(int, int, struct pfctl_altq *);
|
||||
static int print_cbq_opts(const struct pf_altq *);
|
||||
|
||||
static int print_codel_opts(const struct pf_altq *,
|
||||
const struct node_queue_opt *);
|
||||
|
||||
static int eval_pfqueue_priq(struct pfctl *, struct pf_altq *);
|
||||
static int check_commit_priq(int, int, struct pf_altq *);
|
||||
static int eval_pfqueue_priq(struct pfctl *, struct pf_altq *,
|
||||
struct pfctl_altq *);
|
||||
static int check_commit_priq(int, int, struct pfctl_altq *);
|
||||
static int print_priq_opts(const struct pf_altq *);
|
||||
|
||||
static int eval_pfqueue_hfsc(struct pfctl *, struct pf_altq *);
|
||||
static int check_commit_hfsc(int, int, struct pf_altq *);
|
||||
static int eval_pfqueue_hfsc(struct pfctl *, struct pf_altq *,
|
||||
struct pfctl_altq *, struct pfctl_altq *);
|
||||
static int check_commit_hfsc(int, int, struct pfctl_altq *);
|
||||
static int print_hfsc_opts(const struct pf_altq *,
|
||||
const struct node_queue_opt *);
|
||||
|
||||
static int eval_pfqueue_fairq(struct pfctl *, struct pf_altq *);
|
||||
static int eval_pfqueue_fairq(struct pfctl *, struct pf_altq *,
|
||||
struct pfctl_altq *, struct pfctl_altq *);
|
||||
static int print_fairq_opts(const struct pf_altq *,
|
||||
const struct node_queue_opt *);
|
||||
static int check_commit_fairq(int, int, struct pf_altq *);
|
||||
static int check_commit_fairq(int, int, struct pfctl_altq *);
|
||||
|
||||
static void gsc_add_sc(struct gen_sc *, struct service_curve *);
|
||||
static int is_gsc_under_sc(struct gen_sc *,
|
||||
struct service_curve *);
|
||||
static void gsc_destroy(struct gen_sc *);
|
||||
static struct segment *gsc_getentry(struct gen_sc *, double);
|
||||
static int gsc_add_seg(struct gen_sc *, double, double, double,
|
||||
double);
|
||||
@ -104,59 +112,101 @@ void print_hfsc_sc(const char *, u_int, u_int, u_int,
|
||||
void print_fairq_sc(const char *, u_int, u_int, u_int,
|
||||
const struct node_fairq_sc *);
|
||||
|
||||
static __attribute__((constructor)) void
|
||||
pfctl_altq_init(void)
|
||||
{
|
||||
/*
|
||||
* As hdestroy() will never be called on these tables, it will be
|
||||
* safe to use references into the stored data as keys.
|
||||
*/
|
||||
if (hcreate_r(0, &queue_map) == 0)
|
||||
err(1, "Failed to create altq queue map");
|
||||
if (hcreate_r(0, &if_map) == 0)
|
||||
err(1, "Failed to create altq interface map");
|
||||
if (hcreate_r(0, &qid_map) == 0)
|
||||
err(1, "Failed to create altq queue id map");
|
||||
}
|
||||
|
||||
void
|
||||
pfaltq_store(struct pf_altq *a)
|
||||
{
|
||||
struct pf_altq *altq;
|
||||
|
||||
struct pfctl_altq *altq;
|
||||
ENTRY item;
|
||||
ENTRY *ret_item;
|
||||
size_t key_size;
|
||||
|
||||
if ((altq = malloc(sizeof(*altq))) == NULL)
|
||||
err(1, "malloc");
|
||||
memcpy(altq, a, sizeof(struct pf_altq));
|
||||
TAILQ_INSERT_TAIL(&altqs, altq, entries);
|
||||
}
|
||||
err(1, "queue malloc");
|
||||
memcpy(&altq->pa, a, sizeof(struct pf_altq));
|
||||
memset(&altq->meta, 0, sizeof(altq->meta));
|
||||
|
||||
struct pf_altq *
|
||||
pfaltq_lookup(const char *ifname)
|
||||
{
|
||||
struct pf_altq *altq;
|
||||
if (a->qname[0] == 0) {
|
||||
item.key = altq->pa.ifname;
|
||||
item.data = altq;
|
||||
if (hsearch_r(item, ENTER, &ret_item, &if_map) == 0)
|
||||
err(1, "interface map insert");
|
||||
STAILQ_INSERT_TAIL(&interfaces, altq, meta.link);
|
||||
} else {
|
||||
key_size = sizeof(a->ifname) + sizeof(a->qname);
|
||||
if ((item.key = malloc(key_size)) == NULL)
|
||||
err(1, "queue map key malloc");
|
||||
snprintf(item.key, key_size, "%s:%s", a->ifname, a->qname);
|
||||
item.data = altq;
|
||||
if (hsearch_r(item, ENTER, &ret_item, &queue_map) == 0)
|
||||
err(1, "queue map insert");
|
||||
|
||||
TAILQ_FOREACH(altq, &altqs, entries) {
|
||||
if (strncmp(ifname, altq->ifname, IFNAMSIZ) == 0 &&
|
||||
altq->qname[0] == 0)
|
||||
return (altq);
|
||||
item.key = altq->pa.qname;
|
||||
item.data = &altq->pa.qid;
|
||||
if (hsearch_r(item, ENTER, &ret_item, &qid_map) == 0)
|
||||
err(1, "qid map insert");
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
struct pf_altq *
|
||||
static struct pfctl_altq *
|
||||
pfaltq_lookup(char *ifname)
|
||||
{
|
||||
ENTRY item;
|
||||
ENTRY *ret_item;
|
||||
|
||||
item.key = ifname;
|
||||
if (hsearch_r(item, FIND, &ret_item, &if_map) == 0)
|
||||
return (NULL);
|
||||
|
||||
return (ret_item->data);
|
||||
}
|
||||
|
||||
static struct pfctl_altq *
|
||||
qname_to_pfaltq(const char *qname, const char *ifname)
|
||||
{
|
||||
struct pf_altq *altq;
|
||||
ENTRY item;
|
||||
ENTRY *ret_item;
|
||||
char key[IFNAMSIZ + PF_QNAME_SIZE];
|
||||
|
||||
TAILQ_FOREACH(altq, &altqs, entries) {
|
||||
if (strncmp(ifname, altq->ifname, IFNAMSIZ) == 0 &&
|
||||
strncmp(qname, altq->qname, PF_QNAME_SIZE) == 0)
|
||||
return (altq);
|
||||
}
|
||||
return (NULL);
|
||||
item.key = key;
|
||||
snprintf(item.key, sizeof(key), "%s:%s", ifname, qname);
|
||||
if (hsearch_r(item, FIND, &ret_item, &queue_map) == 0)
|
||||
return (NULL);
|
||||
|
||||
return (ret_item->data);
|
||||
}
|
||||
|
||||
u_int32_t
|
||||
qname_to_qid(const char *qname)
|
||||
static u_int32_t
|
||||
qname_to_qid(char *qname)
|
||||
{
|
||||
struct pf_altq *altq;
|
||||
|
||||
ENTRY item;
|
||||
ENTRY *ret_item;
|
||||
uint32_t qid;
|
||||
|
||||
/*
|
||||
* We guarantee that same named queues on different interfaces
|
||||
* have the same qid, so we do NOT need to limit matching on
|
||||
* one interface!
|
||||
* have the same qid.
|
||||
*/
|
||||
item.key = qname;
|
||||
if (hsearch_r(item, FIND, &ret_item, &qid_map) == 0)
|
||||
return (0);
|
||||
|
||||
TAILQ_FOREACH(altq, &altqs, entries) {
|
||||
if (strncmp(qname, altq->qname, PF_QNAME_SIZE) == 0)
|
||||
return (altq->qid);
|
||||
}
|
||||
return (0);
|
||||
qid = *(uint32_t *)ret_item->data;
|
||||
return (qid);
|
||||
}
|
||||
|
||||
void
|
||||
@ -315,28 +365,26 @@ eval_pfaltq(struct pfctl *pf, struct pf_altq *pa, struct node_queue_bw *bw,
|
||||
int
|
||||
check_commit_altq(int dev, int opts)
|
||||
{
|
||||
struct pf_altq *altq;
|
||||
int error = 0;
|
||||
struct pfctl_altq *if_ppa;
|
||||
int error = 0;
|
||||
|
||||
/* call the discipline check for each interface. */
|
||||
TAILQ_FOREACH(altq, &altqs, entries) {
|
||||
if (altq->qname[0] == 0) {
|
||||
switch (altq->scheduler) {
|
||||
case ALTQT_CBQ:
|
||||
error = check_commit_cbq(dev, opts, altq);
|
||||
break;
|
||||
case ALTQT_PRIQ:
|
||||
error = check_commit_priq(dev, opts, altq);
|
||||
break;
|
||||
case ALTQT_HFSC:
|
||||
error = check_commit_hfsc(dev, opts, altq);
|
||||
break;
|
||||
case ALTQT_FAIRQ:
|
||||
error = check_commit_fairq(dev, opts, altq);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
STAILQ_FOREACH(if_ppa, &interfaces, meta.link) {
|
||||
switch (if_ppa->pa.scheduler) {
|
||||
case ALTQT_CBQ:
|
||||
error = check_commit_cbq(dev, opts, if_ppa);
|
||||
break;
|
||||
case ALTQT_PRIQ:
|
||||
error = check_commit_priq(dev, opts, if_ppa);
|
||||
break;
|
||||
case ALTQT_HFSC:
|
||||
error = check_commit_hfsc(dev, opts, if_ppa);
|
||||
break;
|
||||
case ALTQT_FAIRQ:
|
||||
error = check_commit_fairq(dev, opts, if_ppa);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (error);
|
||||
@ -350,17 +398,16 @@ eval_pfqueue(struct pfctl *pf, struct pf_altq *pa, struct node_queue_bw *bw,
|
||||
struct node_queue_opt *opts)
|
||||
{
|
||||
/* should be merged with expand_queue */
|
||||
struct pf_altq *if_pa, *parent, *altq;
|
||||
u_int64_t bwsum;
|
||||
int error = 0;
|
||||
struct pfctl_altq *if_ppa, *parent;
|
||||
int error = 0;
|
||||
|
||||
/* find the corresponding interface and copy fields used by queues */
|
||||
if ((if_pa = pfaltq_lookup(pa->ifname)) == NULL) {
|
||||
if ((if_ppa = pfaltq_lookup(pa->ifname)) == NULL) {
|
||||
fprintf(stderr, "altq not defined on %s\n", pa->ifname);
|
||||
return (1);
|
||||
}
|
||||
pa->scheduler = if_pa->scheduler;
|
||||
pa->ifbandwidth = if_pa->ifbandwidth;
|
||||
pa->scheduler = if_ppa->pa.scheduler;
|
||||
pa->ifbandwidth = if_ppa->pa.ifbandwidth;
|
||||
|
||||
if (qname_to_pfaltq(pa->qname, pa->ifname) != NULL) {
|
||||
fprintf(stderr, "queue %s already exists on interface %s\n",
|
||||
@ -377,15 +424,31 @@ eval_pfqueue(struct pfctl *pf, struct pf_altq *pa, struct node_queue_bw *bw,
|
||||
pa->parent, pa->qname);
|
||||
return (1);
|
||||
}
|
||||
pa->parent_qid = parent->qid;
|
||||
pa->parent_qid = parent->pa.qid;
|
||||
}
|
||||
if (pa->qlimit == 0)
|
||||
pa->qlimit = DEFAULT_QLIMIT;
|
||||
|
||||
if (eval_queue_opts(pa, opts,
|
||||
parent == NULL ? pa->ifbandwidth : parent->pa.bandwidth))
|
||||
return (1);
|
||||
|
||||
if (pa->scheduler == ALTQT_CBQ || pa->scheduler == ALTQT_HFSC ||
|
||||
pa->scheduler == ALTQT_FAIRQ) {
|
||||
pa->bandwidth = eval_bwspec(bw,
|
||||
parent == NULL ? pa->ifbandwidth : parent->bandwidth);
|
||||
parent == NULL ? pa->ifbandwidth : parent->pa.bandwidth);
|
||||
|
||||
/*
|
||||
* For HFSC, if the linkshare service curve m2 parameter is
|
||||
* set, it overrides the provided queue bandwidth parameter,
|
||||
* so adjust the queue bandwidth parameter accordingly here
|
||||
* to avoid false positives in the total child bandwidth
|
||||
* check below.
|
||||
*/
|
||||
if ((pa->scheduler == ALTQT_HFSC) &&
|
||||
(pa->pq_u.hfsc_opts.lssc_m2 != 0)) {
|
||||
pa->bandwidth = pa->pq_u.hfsc_opts.lssc_m2;
|
||||
}
|
||||
|
||||
if (pa->bandwidth > pa->ifbandwidth) {
|
||||
fprintf(stderr, "bandwidth for %s higher than "
|
||||
@ -394,44 +457,36 @@ eval_pfqueue(struct pfctl *pf, struct pf_altq *pa, struct node_queue_bw *bw,
|
||||
}
|
||||
/* check the sum of the child bandwidth is under parent's */
|
||||
if (parent != NULL) {
|
||||
if (pa->bandwidth > parent->bandwidth) {
|
||||
if (pa->bandwidth > parent->pa.bandwidth) {
|
||||
warnx("bandwidth for %s higher than parent",
|
||||
pa->qname);
|
||||
return (1);
|
||||
}
|
||||
bwsum = 0;
|
||||
TAILQ_FOREACH(altq, &altqs, entries) {
|
||||
if (strncmp(altq->ifname, pa->ifname,
|
||||
IFNAMSIZ) == 0 &&
|
||||
altq->qname[0] != 0 &&
|
||||
strncmp(altq->parent, pa->parent,
|
||||
PF_QNAME_SIZE) == 0)
|
||||
bwsum += altq->bandwidth;
|
||||
}
|
||||
bwsum += pa->bandwidth;
|
||||
if (bwsum > parent->bandwidth) {
|
||||
warnx("the sum of the child bandwidth higher"
|
||||
" than parent \"%s\"", parent->qname);
|
||||
parent->meta.bwsum += pa->bandwidth;
|
||||
if (parent->meta.bwsum > parent->pa.bandwidth) {
|
||||
warnx("the sum of the child bandwidth (%" PRIu64
|
||||
") higher than parent \"%s\" (%" PRIu64 ")",
|
||||
parent->meta.bwsum, parent->pa.qname,
|
||||
parent->pa.bandwidth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (eval_queue_opts(pa, opts,
|
||||
parent == NULL ? pa->ifbandwidth : parent->bandwidth))
|
||||
return (1);
|
||||
|
||||
if (parent != NULL)
|
||||
parent->meta.children++;
|
||||
|
||||
switch (pa->scheduler) {
|
||||
case ALTQT_CBQ:
|
||||
error = eval_pfqueue_cbq(pf, pa);
|
||||
error = eval_pfqueue_cbq(pf, pa, if_ppa);
|
||||
break;
|
||||
case ALTQT_PRIQ:
|
||||
error = eval_pfqueue_priq(pf, pa);
|
||||
error = eval_pfqueue_priq(pf, pa, if_ppa);
|
||||
break;
|
||||
case ALTQT_HFSC:
|
||||
error = eval_pfqueue_hfsc(pf, pa);
|
||||
error = eval_pfqueue_hfsc(pf, pa, if_ppa, parent);
|
||||
break;
|
||||
case ALTQT_FAIRQ:
|
||||
error = eval_pfqueue_fairq(pf, pa);
|
||||
error = eval_pfqueue_fairq(pf, pa, if_ppa, parent);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -446,7 +501,7 @@ eval_pfqueue(struct pfctl *pf, struct pf_altq *pa, struct node_queue_bw *bw,
|
||||
#define RM_NS_PER_SEC (1000000000)
|
||||
|
||||
static int
|
||||
eval_pfqueue_cbq(struct pfctl *pf, struct pf_altq *pa)
|
||||
eval_pfqueue_cbq(struct pfctl *pf, struct pf_altq *pa, struct pfctl_altq *if_ppa)
|
||||
{
|
||||
struct cbq_opts *opts;
|
||||
u_int ifmtu;
|
||||
@ -476,6 +531,11 @@ eval_pfqueue_cbq(struct pfctl *pf, struct pf_altq *pa)
|
||||
if (pa->parent[0] == 0)
|
||||
opts->flags |= (CBQCLF_ROOTCLASS | CBQCLF_WRR);
|
||||
|
||||
if (pa->pq_u.cbq_opts.flags & CBQCLF_ROOTCLASS)
|
||||
if_ppa->meta.root_classes++;
|
||||
if (pa->pq_u.cbq_opts.flags & CBQCLF_DEFCLASS)
|
||||
if_ppa->meta.default_classes++;
|
||||
|
||||
cbq_compute_idletime(pf, pa);
|
||||
return (0);
|
||||
}
|
||||
@ -568,33 +628,20 @@ cbq_compute_idletime(struct pfctl *pf, struct pf_altq *pa)
|
||||
}
|
||||
|
||||
static int
|
||||
check_commit_cbq(int dev, int opts, struct pf_altq *pa)
|
||||
check_commit_cbq(int dev, int opts, struct pfctl_altq *if_ppa)
|
||||
{
|
||||
struct pf_altq *altq;
|
||||
int root_class, default_class;
|
||||
int error = 0;
|
||||
int error = 0;
|
||||
|
||||
/*
|
||||
* check if cbq has one root queue and one default queue
|
||||
* for this interface
|
||||
*/
|
||||
root_class = default_class = 0;
|
||||
TAILQ_FOREACH(altq, &altqs, entries) {
|
||||
if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) != 0)
|
||||
continue;
|
||||
if (altq->qname[0] == 0) /* this is for interface */
|
||||
continue;
|
||||
if (altq->pq_u.cbq_opts.flags & CBQCLF_ROOTCLASS)
|
||||
root_class++;
|
||||
if (altq->pq_u.cbq_opts.flags & CBQCLF_DEFCLASS)
|
||||
default_class++;
|
||||
}
|
||||
if (root_class != 1) {
|
||||
warnx("should have one root queue on %s", pa->ifname);
|
||||
if (if_ppa->meta.root_classes != 1) {
|
||||
warnx("should have one root queue on %s", if_ppa->pa.ifname);
|
||||
error++;
|
||||
}
|
||||
if (default_class != 1) {
|
||||
warnx("should have one default queue on %s", pa->ifname);
|
||||
if (if_ppa->meta.default_classes != 1) {
|
||||
warnx("should have one default queue on %s", if_ppa->pa.ifname);
|
||||
error++;
|
||||
}
|
||||
return (error);
|
||||
@ -641,51 +688,37 @@ print_cbq_opts(const struct pf_altq *a)
|
||||
* PRIQ support functions
|
||||
*/
|
||||
static int
|
||||
eval_pfqueue_priq(struct pfctl *pf, struct pf_altq *pa)
|
||||
eval_pfqueue_priq(struct pfctl *pf, struct pf_altq *pa, struct pfctl_altq *if_ppa)
|
||||
{
|
||||
struct pf_altq *altq;
|
||||
|
||||
if (pa->priority >= PRIQ_MAXPRI) {
|
||||
warnx("priority out of range: max %d", PRIQ_MAXPRI - 1);
|
||||
return (-1);
|
||||
}
|
||||
/* the priority should be unique for the interface */
|
||||
TAILQ_FOREACH(altq, &altqs, entries) {
|
||||
if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) == 0 &&
|
||||
altq->qname[0] != 0 && altq->priority == pa->priority) {
|
||||
warnx("%s and %s have the same priority",
|
||||
altq->qname, pa->qname);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
if (BIT_ISSET(QPRI_BITSET_SIZE, pa->priority, &if_ppa->meta.qpris)) {
|
||||
warnx("%s does not have a unique priority on interface %s",
|
||||
pa->qname, pa->ifname);
|
||||
return (-1);
|
||||
} else
|
||||
BIT_SET(QPRI_BITSET_SIZE, pa->priority, &if_ppa->meta.qpris);
|
||||
|
||||
if (pa->pq_u.priq_opts.flags & PRCF_DEFAULTCLASS)
|
||||
if_ppa->meta.default_classes++;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
check_commit_priq(int dev, int opts, struct pf_altq *pa)
|
||||
check_commit_priq(int dev, int opts, struct pfctl_altq *if_ppa)
|
||||
{
|
||||
struct pf_altq *altq;
|
||||
int default_class;
|
||||
int error = 0;
|
||||
|
||||
/*
|
||||
* check if priq has one default class for this interface
|
||||
*/
|
||||
default_class = 0;
|
||||
TAILQ_FOREACH(altq, &altqs, entries) {
|
||||
if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) != 0)
|
||||
continue;
|
||||
if (altq->qname[0] == 0) /* this is for interface */
|
||||
continue;
|
||||
if (altq->pq_u.priq_opts.flags & PRCF_DEFAULTCLASS)
|
||||
default_class++;
|
||||
if (if_ppa->meta.default_classes != 1) {
|
||||
warnx("should have one default queue on %s", if_ppa->pa.ifname);
|
||||
return (1);
|
||||
}
|
||||
if (default_class != 1) {
|
||||
warnx("should have one default queue on %s", pa->ifname);
|
||||
error++;
|
||||
}
|
||||
return (error);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -720,15 +753,15 @@ print_priq_opts(const struct pf_altq *a)
|
||||
* HFSC support functions
|
||||
*/
|
||||
static int
|
||||
eval_pfqueue_hfsc(struct pfctl *pf, struct pf_altq *pa)
|
||||
eval_pfqueue_hfsc(struct pfctl *pf, struct pf_altq *pa, struct pfctl_altq *if_ppa,
|
||||
struct pfctl_altq *parent)
|
||||
{
|
||||
struct pf_altq *altq, *parent;
|
||||
struct hfsc_opts_v1 *opts;
|
||||
struct service_curve sc;
|
||||
|
||||
opts = &pa->pq_u.hfsc_opts;
|
||||
|
||||
if (pa->parent[0] == 0) {
|
||||
if (parent == NULL) {
|
||||
/* root queue */
|
||||
opts->lssc_m1 = pa->ifbandwidth;
|
||||
opts->lssc_m2 = pa->ifbandwidth;
|
||||
@ -736,9 +769,21 @@ eval_pfqueue_hfsc(struct pfctl *pf, struct pf_altq *pa)
|
||||
return (0);
|
||||
}
|
||||
|
||||
LIST_INIT(&rtsc);
|
||||
LIST_INIT(&lssc);
|
||||
/* First child initializes the parent's service curve accumulators. */
|
||||
if (parent->meta.children == 1) {
|
||||
LIST_INIT(&parent->meta.rtsc);
|
||||
LIST_INIT(&parent->meta.lssc);
|
||||
}
|
||||
|
||||
if (parent->pa.pq_u.hfsc_opts.flags & HFCF_DEFAULTCLASS) {
|
||||
warnx("adding %s would make default queue %s not a leaf",
|
||||
pa->qname, pa->parent);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (pa->pq_u.hfsc_opts.flags & HFCF_DEFAULTCLASS)
|
||||
if_ppa->meta.default_classes++;
|
||||
|
||||
/* if link_share is not specified, use bandwidth */
|
||||
if (opts->lssc_m2 == 0)
|
||||
opts->lssc_m2 = pa->bandwidth;
|
||||
@ -768,51 +813,22 @@ eval_pfqueue_hfsc(struct pfctl *pf, struct pf_altq *pa)
|
||||
* be smaller than the interface bandwidth, and the upper-limit should
|
||||
* be larger than the real-time service curve when both are defined.
|
||||
*/
|
||||
parent = qname_to_pfaltq(pa->parent, pa->ifname);
|
||||
if (parent == NULL)
|
||||
errx(1, "parent %s not found for %s", pa->parent, pa->qname);
|
||||
|
||||
TAILQ_FOREACH(altq, &altqs, entries) {
|
||||
if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) != 0)
|
||||
continue;
|
||||
if (altq->qname[0] == 0) /* this is for interface */
|
||||
continue;
|
||||
|
||||
/* if the class has a real-time service curve, add it. */
|
||||
if (opts->rtsc_m2 != 0 && altq->pq_u.hfsc_opts.rtsc_m2 != 0) {
|
||||
sc.m1 = altq->pq_u.hfsc_opts.rtsc_m1;
|
||||
sc.d = altq->pq_u.hfsc_opts.rtsc_d;
|
||||
sc.m2 = altq->pq_u.hfsc_opts.rtsc_m2;
|
||||
gsc_add_sc(&rtsc, &sc);
|
||||
}
|
||||
|
||||
if (strncmp(altq->parent, pa->parent, PF_QNAME_SIZE) != 0)
|
||||
continue;
|
||||
|
||||
/* if the class has a linkshare service curve, add it. */
|
||||
if (opts->lssc_m2 != 0 && altq->pq_u.hfsc_opts.lssc_m2 != 0) {
|
||||
sc.m1 = altq->pq_u.hfsc_opts.lssc_m1;
|
||||
sc.d = altq->pq_u.hfsc_opts.lssc_d;
|
||||
sc.m2 = altq->pq_u.hfsc_opts.lssc_m2;
|
||||
gsc_add_sc(&lssc, &sc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* check the real-time service curve. reserve 20% of interface bw */
|
||||
if (opts->rtsc_m2 != 0) {
|
||||
/* add this queue to the sum */
|
||||
sc.m1 = opts->rtsc_m1;
|
||||
sc.d = opts->rtsc_d;
|
||||
sc.m2 = opts->rtsc_m2;
|
||||
gsc_add_sc(&rtsc, &sc);
|
||||
gsc_add_sc(&parent->meta.rtsc, &sc);
|
||||
/* compare the sum with 80% of the interface */
|
||||
sc.m1 = 0;
|
||||
sc.d = 0;
|
||||
sc.m2 = pa->ifbandwidth / 100 * 80;
|
||||
if (!is_gsc_under_sc(&rtsc, &sc)) {
|
||||
if (!is_gsc_under_sc(&parent->meta.rtsc, &sc)) {
|
||||
warnx("real-time sc exceeds 80%% of the interface "
|
||||
"bandwidth (%s)", rate2str((double)sc.m2));
|
||||
goto err_ret;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -822,14 +838,14 @@ eval_pfqueue_hfsc(struct pfctl *pf, struct pf_altq *pa)
|
||||
sc.m1 = opts->lssc_m1;
|
||||
sc.d = opts->lssc_d;
|
||||
sc.m2 = opts->lssc_m2;
|
||||
gsc_add_sc(&lssc, &sc);
|
||||
gsc_add_sc(&parent->meta.lssc, &sc);
|
||||
/* compare the sum of the children with parent's sc */
|
||||
sc.m1 = parent->pq_u.hfsc_opts.lssc_m1;
|
||||
sc.d = parent->pq_u.hfsc_opts.lssc_d;
|
||||
sc.m2 = parent->pq_u.hfsc_opts.lssc_m2;
|
||||
if (!is_gsc_under_sc(&lssc, &sc)) {
|
||||
sc.m1 = parent->pa.pq_u.hfsc_opts.lssc_m1;
|
||||
sc.d = parent->pa.pq_u.hfsc_opts.lssc_d;
|
||||
sc.m2 = parent->pa.pq_u.hfsc_opts.lssc_m2;
|
||||
if (!is_gsc_under_sc(&parent->meta.lssc, &sc)) {
|
||||
warnx("linkshare sc exceeds parent's sc");
|
||||
goto err_ret;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -838,38 +854,30 @@ eval_pfqueue_hfsc(struct pfctl *pf, struct pf_altq *pa)
|
||||
if (opts->ulsc_m1 > pa->ifbandwidth ||
|
||||
opts->ulsc_m2 > pa->ifbandwidth) {
|
||||
warnx("upper-limit larger than interface bandwidth");
|
||||
goto err_ret;
|
||||
return (-1);
|
||||
}
|
||||
if (opts->rtsc_m2 != 0 && opts->rtsc_m2 > opts->ulsc_m2) {
|
||||
warnx("upper-limit sc smaller than real-time sc");
|
||||
goto err_ret;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
gsc_destroy(&rtsc);
|
||||
gsc_destroy(&lssc);
|
||||
|
||||
return (0);
|
||||
|
||||
err_ret:
|
||||
gsc_destroy(&rtsc);
|
||||
gsc_destroy(&lssc);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* FAIRQ support functions
|
||||
*/
|
||||
static int
|
||||
eval_pfqueue_fairq(struct pfctl *pf __unused, struct pf_altq *pa)
|
||||
eval_pfqueue_fairq(struct pfctl *pf __unused, struct pf_altq *pa,
|
||||
struct pfctl_altq *if_ppa, struct pfctl_altq *parent)
|
||||
{
|
||||
struct pf_altq *altq, *parent;
|
||||
struct fairq_opts *opts;
|
||||
struct service_curve sc;
|
||||
|
||||
opts = &pa->pq_u.fairq_opts;
|
||||
|
||||
if (pa->parent[0] == 0) {
|
||||
if (pa->parent == NULL) {
|
||||
/* root queue */
|
||||
opts->lssc_m1 = pa->ifbandwidth;
|
||||
opts->lssc_m2 = pa->ifbandwidth;
|
||||
@ -877,7 +885,18 @@ eval_pfqueue_fairq(struct pfctl *pf __unused, struct pf_altq *pa)
|
||||
return (0);
|
||||
}
|
||||
|
||||
LIST_INIT(&lssc);
|
||||
/* First child initializes the parent's service curve accumulator. */
|
||||
if (parent->meta.children == 1)
|
||||
LIST_INIT(&parent->meta.lssc);
|
||||
|
||||
if (parent->pa.pq_u.fairq_opts.flags & FARF_DEFAULTCLASS) {
|
||||
warnx("adding %s would make default queue %s not a leaf",
|
||||
pa->qname, pa->parent);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (pa->pq_u.fairq_opts.flags & FARF_DEFAULTCLASS)
|
||||
if_ppa->meta.default_classes++;
|
||||
|
||||
/* if link_share is not specified, use bandwidth */
|
||||
if (opts->lssc_m2 == 0)
|
||||
@ -894,122 +913,49 @@ eval_pfqueue_fairq(struct pfctl *pf __unused, struct pf_altq *pa)
|
||||
* be smaller than the interface bandwidth, and the upper-limit should
|
||||
* be larger than the real-time service curve when both are defined.
|
||||
*/
|
||||
parent = qname_to_pfaltq(pa->parent, pa->ifname);
|
||||
if (parent == NULL)
|
||||
errx(1, "parent %s not found for %s", pa->parent, pa->qname);
|
||||
|
||||
TAILQ_FOREACH(altq, &altqs, entries) {
|
||||
if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) != 0)
|
||||
continue;
|
||||
if (altq->qname[0] == 0) /* this is for interface */
|
||||
continue;
|
||||
|
||||
if (strncmp(altq->parent, pa->parent, PF_QNAME_SIZE) != 0)
|
||||
continue;
|
||||
|
||||
/* if the class has a link-sharing service curve, add it. */
|
||||
if (opts->lssc_m2 != 0 && altq->pq_u.fairq_opts.lssc_m2 != 0) {
|
||||
sc.m1 = altq->pq_u.fairq_opts.lssc_m1;
|
||||
sc.d = altq->pq_u.fairq_opts.lssc_d;
|
||||
sc.m2 = altq->pq_u.fairq_opts.lssc_m2;
|
||||
gsc_add_sc(&lssc, &sc);
|
||||
}
|
||||
}
|
||||
|
||||
/* check the link-sharing service curve. */
|
||||
/* check the linkshare service curve. */
|
||||
if (opts->lssc_m2 != 0) {
|
||||
sc.m1 = parent->pq_u.fairq_opts.lssc_m1;
|
||||
sc.d = parent->pq_u.fairq_opts.lssc_d;
|
||||
sc.m2 = parent->pq_u.fairq_opts.lssc_m2;
|
||||
if (!is_gsc_under_sc(&lssc, &sc)) {
|
||||
/* add this queue to the child sum */
|
||||
sc.m1 = opts->lssc_m1;
|
||||
sc.d = opts->lssc_d;
|
||||
sc.m2 = opts->lssc_m2;
|
||||
gsc_add_sc(&parent->meta.lssc, &sc);
|
||||
/* compare the sum of the children with parent's sc */
|
||||
sc.m1 = parent->pa.pq_u.fairq_opts.lssc_m1;
|
||||
sc.d = parent->pa.pq_u.fairq_opts.lssc_d;
|
||||
sc.m2 = parent->pa.pq_u.fairq_opts.lssc_m2;
|
||||
if (!is_gsc_under_sc(&parent->meta.lssc, &sc)) {
|
||||
warnx("link-sharing sc exceeds parent's sc");
|
||||
goto err_ret;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
gsc_destroy(&lssc);
|
||||
|
||||
return (0);
|
||||
|
||||
err_ret:
|
||||
gsc_destroy(&lssc);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
check_commit_hfsc(int dev, int opts, struct pf_altq *pa)
|
||||
check_commit_hfsc(int dev, int opts, struct pfctl_altq *if_ppa)
|
||||
{
|
||||
struct pf_altq *altq, *def = NULL;
|
||||
int default_class;
|
||||
int error = 0;
|
||||
|
||||
/* check if hfsc has one default queue for this interface */
|
||||
default_class = 0;
|
||||
TAILQ_FOREACH(altq, &altqs, entries) {
|
||||
if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) != 0)
|
||||
continue;
|
||||
if (altq->qname[0] == 0) /* this is for interface */
|
||||
continue;
|
||||
if (altq->parent[0] == 0) /* dummy root */
|
||||
continue;
|
||||
if (altq->pq_u.hfsc_opts.flags & HFCF_DEFAULTCLASS) {
|
||||
default_class++;
|
||||
def = altq;
|
||||
}
|
||||
}
|
||||
if (default_class != 1) {
|
||||
warnx("should have one default queue on %s", pa->ifname);
|
||||
if (if_ppa->meta.default_classes != 1) {
|
||||
warnx("should have one default queue on %s", if_ppa->pa.ifname);
|
||||
return (1);
|
||||
}
|
||||
/* make sure the default queue is a leaf */
|
||||
TAILQ_FOREACH(altq, &altqs, entries) {
|
||||
if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) != 0)
|
||||
continue;
|
||||
if (altq->qname[0] == 0) /* this is for interface */
|
||||
continue;
|
||||
if (strncmp(altq->parent, def->qname, PF_QNAME_SIZE) == 0) {
|
||||
warnx("default queue is not a leaf");
|
||||
error++;
|
||||
}
|
||||
}
|
||||
return (error);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
check_commit_fairq(int dev __unused, int opts __unused, struct pf_altq *pa)
|
||||
check_commit_fairq(int dev __unused, int opts __unused, struct pfctl_altq *if_ppa)
|
||||
{
|
||||
struct pf_altq *altq, *def = NULL;
|
||||
int default_class;
|
||||
int error = 0;
|
||||
|
||||
/* check if fairq has one default queue for this interface */
|
||||
default_class = 0;
|
||||
TAILQ_FOREACH(altq, &altqs, entries) {
|
||||
if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) != 0)
|
||||
continue;
|
||||
if (altq->qname[0] == 0) /* this is for interface */
|
||||
continue;
|
||||
if (altq->pq_u.fairq_opts.flags & FARF_DEFAULTCLASS) {
|
||||
default_class++;
|
||||
def = altq;
|
||||
}
|
||||
}
|
||||
if (default_class != 1) {
|
||||
warnx("should have one default queue on %s", pa->ifname);
|
||||
if (if_ppa->meta.default_classes != 1) {
|
||||
warnx("should have one default queue on %s", if_ppa->pa.ifname);
|
||||
return (1);
|
||||
}
|
||||
/* make sure the default queue is a leaf */
|
||||
TAILQ_FOREACH(altq, &altqs, entries) {
|
||||
if (strncmp(altq->ifname, pa->ifname, IFNAMSIZ) != 0)
|
||||
continue;
|
||||
if (altq->qname[0] == 0) /* this is for interface */
|
||||
continue;
|
||||
if (strncmp(altq->parent, def->qname, PF_QNAME_SIZE) == 0) {
|
||||
warnx("default queue is not a leaf");
|
||||
error++;
|
||||
}
|
||||
}
|
||||
return (error);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1182,17 +1128,6 @@ is_gsc_under_sc(struct gen_sc *gsc, struct service_curve *sc)
|
||||
return (1);
|
||||
}
|
||||
|
||||
static void
|
||||
gsc_destroy(struct gen_sc *gsc)
|
||||
{
|
||||
struct segment *s;
|
||||
|
||||
while ((s = LIST_FIRST(gsc)) != NULL) {
|
||||
LIST_REMOVE(s, _next);
|
||||
free(s);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* return a segment entry starting at x.
|
||||
* if gsc has no entry starting at x, a new entry is created at x.
|
||||
@ -1351,8 +1286,7 @@ getifspeed(char *ifname)
|
||||
struct ifreq ifr;
|
||||
struct if_data ifrdat;
|
||||
|
||||
if ((s = socket(get_socket_domain(), SOCK_DGRAM, 0)) < 0)
|
||||
err(1, "socket");
|
||||
s = get_query_socket();
|
||||
bzero(&ifr, sizeof(ifr));
|
||||
if (strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)) >=
|
||||
sizeof(ifr.ifr_name))
|
||||
@ -1360,8 +1294,6 @@ getifspeed(char *ifname)
|
||||
ifr.ifr_data = (caddr_t)&ifrdat;
|
||||
if (ioctl(s, SIOCGIFDATA, (caddr_t)&ifr) == -1)
|
||||
err(1, "SIOCGIFDATA");
|
||||
if (close(s))
|
||||
err(1, "close");
|
||||
return ((u_int32_t)ifrdat.ifi_baudrate);
|
||||
}
|
||||
#endif
|
||||
@ -1372,8 +1304,7 @@ getifmtu(char *ifname)
|
||||
int s;
|
||||
struct ifreq ifr;
|
||||
|
||||
if ((s = socket(get_socket_domain(), SOCK_DGRAM, 0)) < 0)
|
||||
err(1, "socket");
|
||||
s = get_query_socket();
|
||||
bzero(&ifr, sizeof(ifr));
|
||||
if (strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)) >=
|
||||
sizeof(ifr.ifr_name))
|
||||
@ -1384,8 +1315,6 @@ getifmtu(char *ifname)
|
||||
#else
|
||||
err(1, "SIOCGIFMTU");
|
||||
#endif
|
||||
if (close(s))
|
||||
err(1, "close");
|
||||
if (ifr.ifr_mtu > 0)
|
||||
return (ifr.ifr_mtu);
|
||||
else {
|
||||
|
@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <net/pfvar.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <search.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -72,7 +73,6 @@ void print_fromto(struct pf_rule_addr *, pf_osfp_t,
|
||||
struct pf_rule_addr *, u_int8_t, u_int8_t, int, int);
|
||||
int ifa_skip_if(const char *filter, struct node_host *p);
|
||||
|
||||
struct node_host *ifa_grouplookup(const char *, int);
|
||||
struct node_host *host_if(const char *, int);
|
||||
struct node_host *host_v4(const char *, int);
|
||||
struct node_host *host_v6(const char *, int);
|
||||
@ -209,6 +209,19 @@ const struct pf_timeout pf_timeouts[] = {
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static struct hsearch_data isgroup_map;
|
||||
|
||||
static __attribute__((constructor)) void
|
||||
pfctl_parser_init(void)
|
||||
{
|
||||
/*
|
||||
* As hdestroy() will never be called on these tables, it will be
|
||||
* safe to use references into the stored data as keys.
|
||||
*/
|
||||
if (hcreate_r(0, &isgroup_map) == 0)
|
||||
err(1, "Failed to create interface group query response map");
|
||||
}
|
||||
|
||||
const struct icmptypeent *
|
||||
geticmptypebynumber(u_int8_t type, sa_family_t af)
|
||||
{
|
||||
@ -1153,6 +1166,71 @@ check_netmask(struct node_host *h, sa_family_t af)
|
||||
|
||||
static struct node_host *iftab;
|
||||
|
||||
/*
|
||||
* Retrieve the list of groups this interface is a member of and make sure
|
||||
* each group is in the group map.
|
||||
*/
|
||||
static void
|
||||
ifa_add_groups_to_map(char *ifa_name)
|
||||
{
|
||||
int s, len;
|
||||
struct ifgroupreq ifgr;
|
||||
struct ifg_req *ifg;
|
||||
|
||||
s = get_query_socket();
|
||||
|
||||
/* Get size of group list for this interface */
|
||||
memset(&ifgr, 0, sizeof(ifgr));
|
||||
strlcpy(ifgr.ifgr_name, ifa_name, IFNAMSIZ);
|
||||
if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1)
|
||||
err(1, "SIOCGIFGROUP");
|
||||
|
||||
/* Retrieve group list for this interface */
|
||||
len = ifgr.ifgr_len;
|
||||
ifgr.ifgr_groups =
|
||||
(struct ifg_req *)calloc(len / sizeof(struct ifg_req),
|
||||
sizeof(struct ifg_req));
|
||||
if (ifgr.ifgr_groups == NULL)
|
||||
err(1, "calloc");
|
||||
if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1)
|
||||
err(1, "SIOCGIFGROUP");
|
||||
|
||||
ifg = ifgr.ifgr_groups;
|
||||
for (; ifg && len >= sizeof(struct ifg_req); ifg++) {
|
||||
len -= sizeof(struct ifg_req);
|
||||
if (strcmp(ifg->ifgrq_group, "all")) {
|
||||
ENTRY item;
|
||||
ENTRY *ret_item;
|
||||
int *answer;
|
||||
|
||||
item.key = ifg->ifgrq_group;
|
||||
if (hsearch_r(item, FIND, &ret_item, &isgroup_map) == 0) {
|
||||
struct ifgroupreq ifgr2;
|
||||
|
||||
/* Don't know the answer yet */
|
||||
if ((answer = malloc(sizeof(int))) == NULL)
|
||||
err(1, "malloc");
|
||||
|
||||
bzero(&ifgr2, sizeof(ifgr2));
|
||||
strlcpy(ifgr2.ifgr_name, ifg->ifgrq_group,
|
||||
sizeof(ifgr2.ifgr_name));
|
||||
if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr2) == 0)
|
||||
*answer = ifgr2.ifgr_len;
|
||||
else
|
||||
*answer = 0;
|
||||
|
||||
item.key = strdup(ifg->ifgrq_group);
|
||||
item.data = answer;
|
||||
if (hsearch_r(item, ENTER, &ret_item,
|
||||
&isgroup_map) == 0)
|
||||
err(1, "interface group query response"
|
||||
" map insert");
|
||||
}
|
||||
}
|
||||
}
|
||||
free(ifgr.ifgr_groups);
|
||||
}
|
||||
|
||||
void
|
||||
ifa_load(void)
|
||||
{
|
||||
@ -1220,6 +1298,8 @@ ifa_load(void)
|
||||
sizeof(struct in6_addr));
|
||||
n->ifindex = ((struct sockaddr_in6 *)
|
||||
ifa->ifa_addr)->sin6_scope_id;
|
||||
} else if (n->af == AF_LINK) {
|
||||
ifa_add_groups_to_map(ifa->ifa_name);
|
||||
}
|
||||
if ((n->ifname = strdup(ifa->ifa_name)) == NULL)
|
||||
err(1, "ifa_load: strdup");
|
||||
@ -1237,7 +1317,7 @@ ifa_load(void)
|
||||
freeifaddrs(ifap);
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
get_socket_domain(void)
|
||||
{
|
||||
int sdom;
|
||||
@ -1257,31 +1337,54 @@ get_socket_domain(void)
|
||||
return (sdom);
|
||||
}
|
||||
|
||||
int
|
||||
get_query_socket(void)
|
||||
{
|
||||
static int s = -1;
|
||||
|
||||
if (s == -1) {
|
||||
if ((s = socket(get_socket_domain(), SOCK_DGRAM, 0)) == -1)
|
||||
err(1, "socket");
|
||||
}
|
||||
|
||||
return (s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the response len if the name is a group, otherwise returns 0.
|
||||
*/
|
||||
static int
|
||||
is_a_group(char *name)
|
||||
{
|
||||
ENTRY item;
|
||||
ENTRY *ret_item;
|
||||
|
||||
item.key = name;
|
||||
if (hsearch_r(item, FIND, &ret_item, &isgroup_map) == 0)
|
||||
return (0);
|
||||
|
||||
return (*(int *)ret_item->data);
|
||||
}
|
||||
|
||||
struct node_host *
|
||||
ifa_exists(const char *ifa_name)
|
||||
ifa_exists(char *ifa_name)
|
||||
{
|
||||
struct node_host *n;
|
||||
struct ifgroupreq ifgr;
|
||||
int s;
|
||||
|
||||
if (iftab == NULL)
|
||||
ifa_load();
|
||||
|
||||
/* check wether this is a group */
|
||||
if ((s = socket(get_socket_domain(), SOCK_DGRAM, 0)) == -1)
|
||||
err(1, "socket");
|
||||
bzero(&ifgr, sizeof(ifgr));
|
||||
strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name));
|
||||
if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == 0) {
|
||||
/* check whether this is a group */
|
||||
s = get_query_socket();
|
||||
if (is_a_group(ifa_name)) {
|
||||
/* fake a node_host */
|
||||
if ((n = calloc(1, sizeof(*n))) == NULL)
|
||||
err(1, "calloc");
|
||||
if ((n->ifname = strdup(ifa_name)) == NULL)
|
||||
err(1, "strdup");
|
||||
close(s);
|
||||
return (n);
|
||||
}
|
||||
close(s);
|
||||
|
||||
for (n = iftab; n; n = n->next) {
|
||||
if (n->af == AF_LINK && !strncmp(n->ifname, ifa_name, IFNAMSIZ))
|
||||
@ -1292,23 +1395,19 @@ ifa_exists(const char *ifa_name)
|
||||
}
|
||||
|
||||
struct node_host *
|
||||
ifa_grouplookup(const char *ifa_name, int flags)
|
||||
ifa_grouplookup(char *ifa_name, int flags)
|
||||
{
|
||||
struct ifg_req *ifg;
|
||||
struct ifgroupreq ifgr;
|
||||
int s, len;
|
||||
struct node_host *n, *h = NULL;
|
||||
|
||||
if ((s = socket(get_socket_domain(), SOCK_DGRAM, 0)) == -1)
|
||||
err(1, "socket");
|
||||
s = get_query_socket();
|
||||
len = is_a_group(ifa_name);
|
||||
if (len == 0)
|
||||
return (NULL);
|
||||
bzero(&ifgr, sizeof(ifgr));
|
||||
strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name));
|
||||
if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) {
|
||||
close(s);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
len = ifgr.ifgr_len;
|
||||
if ((ifgr.ifgr_groups = calloc(1, len)) == NULL)
|
||||
err(1, "calloc");
|
||||
if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1)
|
||||
@ -1327,13 +1426,12 @@ ifa_grouplookup(const char *ifa_name, int flags)
|
||||
}
|
||||
}
|
||||
free(ifgr.ifgr_groups);
|
||||
close(s);
|
||||
|
||||
return (h);
|
||||
}
|
||||
|
||||
struct node_host *
|
||||
ifa_lookup(const char *ifa_name, int flags)
|
||||
ifa_lookup(char *ifa_name, int flags)
|
||||
{
|
||||
struct node_host *p = NULL, *h = NULL, *n = NULL;
|
||||
int got4 = 0, got6 = 0;
|
||||
|
@ -177,6 +177,24 @@ struct node_queue_opt {
|
||||
} data;
|
||||
};
|
||||
|
||||
#define QPRI_BITSET_SIZE 256
|
||||
BITSET_DEFINE(qpri_bitset, QPRI_BITSET_SIZE);
|
||||
LIST_HEAD(gen_sc, segment);
|
||||
|
||||
struct pfctl_altq {
|
||||
struct pf_altq pa;
|
||||
struct {
|
||||
STAILQ_ENTRY(pfctl_altq) link;
|
||||
u_int64_t bwsum;
|
||||
struct qpri_bitset qpris;
|
||||
int children;
|
||||
int root_classes;
|
||||
int default_classes;
|
||||
struct gen_sc lssc;
|
||||
struct gen_sc rtsc;
|
||||
} meta;
|
||||
};
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
/*
|
||||
* XXX
|
||||
@ -313,10 +331,10 @@ void set_ipmask(struct node_host *, u_int8_t);
|
||||
int check_netmask(struct node_host *, sa_family_t);
|
||||
int unmask(struct pf_addr *, sa_family_t);
|
||||
void ifa_load(void);
|
||||
int get_socket_domain(void);
|
||||
struct node_host *ifa_exists(const char *);
|
||||
struct node_host *ifa_grouplookup(const char *ifa_name, int flags);
|
||||
struct node_host *ifa_lookup(const char *, int);
|
||||
int get_query_socket(void);
|
||||
struct node_host *ifa_exists(char *);
|
||||
struct node_host *ifa_grouplookup(char *ifa_name, int flags);
|
||||
struct node_host *ifa_lookup(char *, int);
|
||||
struct node_host *host(const char *);
|
||||
|
||||
int append_addr(struct pfr_buffer *, char *, int);
|
||||
|
@ -15,7 +15,6 @@ alias ll ls -lAF
|
||||
# These are normally set through /etc/login.conf. You may override them here
|
||||
# if wanted.
|
||||
# set path = (/sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin $HOME/bin)
|
||||
# setenv BLOCKSIZE K
|
||||
# A righteous umask
|
||||
# umask 22
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
# These are normally set through /etc/login.conf. You may override them here
|
||||
# if wanted.
|
||||
# PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:$HOME/bin; export PATH
|
||||
# BLOCKSIZE=K; export BLOCKSIZE
|
||||
|
||||
# Setting TERM is normally done through /etc/ttys. Do only override
|
||||
# if you're sure that you'll never log in via telnet or xterm or a
|
||||
|
@ -651,3 +651,19 @@ xgetc(int fn)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
getchar(void)
|
||||
{
|
||||
|
||||
return xgetc(0);
|
||||
}
|
||||
|
||||
void
|
||||
exit(int code)
|
||||
{
|
||||
|
||||
printf("error: loader exit\n");
|
||||
while (1);
|
||||
__unreachable();
|
||||
}
|
||||
|
@ -284,7 +284,6 @@ device xl # 3Com 3c90x (``Boomerang'', ``Cyclone'')
|
||||
# Wireless NIC cards
|
||||
device wlan # 802.11 support
|
||||
options IEEE80211_DEBUG # enable debug msgs
|
||||
options IEEE80211_AMPDU_AGE # age frames in AMPDU reorder q's
|
||||
options IEEE80211_SUPPORT_MESH # enable 802.11s draft support
|
||||
device wlan_wep # 802.11 WEP support
|
||||
device wlan_ccmp # 802.11 CCMP support
|
||||
|
@ -201,6 +201,7 @@ linux_sigaltstack(struct thread *td, struct linux_sigaltstack_args *uap)
|
||||
l_stack_t lss;
|
||||
int error;
|
||||
|
||||
memset(&lss, 0, sizeof(lss));
|
||||
LINUX_CTR2(sigaltstack, "%p, %p", uap->uss, uap->uoss);
|
||||
|
||||
if (uap->uss != NULL) {
|
||||
|
@ -1466,6 +1466,12 @@ awg_setup_extres(device_t dev)
|
||||
goto fail;
|
||||
}
|
||||
if (rst_ephy != NULL) {
|
||||
/*
|
||||
* The ephy reset is left de-asserted by U-Boot. Assert it
|
||||
* here to make sure that we're in a known good state going
|
||||
* into the PHY reset.
|
||||
*/
|
||||
hwreset_assert(rst_ephy);
|
||||
error = hwreset_deassert(rst_ephy);
|
||||
if (error != 0) {
|
||||
device_printf(dev, "cannot de-assert ephy reset\n");
|
||||
|
@ -79,7 +79,6 @@ device bpf
|
||||
|
||||
# Wireless NIC cards
|
||||
options IEEE80211_DEBUG
|
||||
options IEEE80211_AMPDU_AGE
|
||||
options IEEE80211_SUPPORT_MESH
|
||||
options IEEE80211_SUPPORT_TDMA
|
||||
device wlan # 802.11 support
|
||||
|
@ -686,6 +686,7 @@ bsd_to_linux_termio(struct termios *bios, struct linux_termio *lio)
|
||||
{
|
||||
struct linux_termios lios;
|
||||
|
||||
memset(lio, 0, sizeof(*lio));
|
||||
bsd_to_linux_termios(bios, &lios);
|
||||
lio->c_iflag = lios.c_iflag;
|
||||
lio->c_oflag = lios.c_oflag;
|
||||
@ -2843,6 +2844,8 @@ linux_to_bsd_v4l_window(struct l_video_window *lvw, struct video_window *vw)
|
||||
static int
|
||||
bsd_to_linux_v4l_window(struct video_window *vw, struct l_video_window *lvw)
|
||||
{
|
||||
memset(lvw, 0, sizeof(*lvw));
|
||||
|
||||
lvw->x = vw->x;
|
||||
lvw->y = vw->y;
|
||||
lvw->width = vw->width;
|
||||
|
@ -1089,9 +1089,8 @@ linux_waitid(struct thread *td, struct linux_waitid_args *args)
|
||||
}
|
||||
if (args->info != NULL) {
|
||||
p = td->td_proc;
|
||||
if (td->td_retval[0] == 0)
|
||||
bzero(&lsi, sizeof(lsi));
|
||||
else {
|
||||
bzero(&lsi, sizeof(lsi));
|
||||
if (td->td_retval[0] != 0) {
|
||||
sig = bsd_to_linux_signal(siginfo.si_signo);
|
||||
siginfo_to_lsiginfo(&siginfo, &lsi, sig);
|
||||
}
|
||||
|
@ -58,6 +58,10 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/segments.h>
|
||||
#endif
|
||||
|
||||
#ifdef __amd64__
|
||||
#include <machine/fpu.h>
|
||||
#endif
|
||||
|
||||
#include <dev/usb/usb.h>
|
||||
|
||||
#include <compat/ndis/pe_var.h>
|
||||
@ -68,6 +72,19 @@ __FBSDID("$FreeBSD$");
|
||||
#include <compat/ndis/hal_var.h>
|
||||
#include <compat/ndis/usbd_var.h>
|
||||
|
||||
#ifdef __amd64__
|
||||
struct fpu_cc_ent {
|
||||
struct fpu_kern_ctx *ctx;
|
||||
LIST_ENTRY(fpu_cc_ent) entries;
|
||||
};
|
||||
static LIST_HEAD(fpu_ctx_free, fpu_cc_ent) fpu_free_head =
|
||||
LIST_HEAD_INITIALIZER(fpu_free_head);
|
||||
static LIST_HEAD(fpu_ctx_busy, fpu_cc_ent) fpu_busy_head =
|
||||
LIST_HEAD_INITIALIZER(fpu_busy_head);
|
||||
static struct mtx fpu_free_mtx;
|
||||
static struct mtx fpu_busy_mtx;
|
||||
#endif
|
||||
|
||||
static struct mtx drvdb_mtx;
|
||||
static STAILQ_HEAD(drvdb, drvdb_ent) drvdb_head;
|
||||
|
||||
@ -98,6 +115,13 @@ windrv_libinit(void)
|
||||
mtx_init(&drvdb_mtx, "Windows driver DB lock",
|
||||
"Windows internal lock", MTX_DEF);
|
||||
|
||||
#ifdef __amd64__
|
||||
LIST_INIT(&fpu_free_head);
|
||||
LIST_INIT(&fpu_busy_head);
|
||||
mtx_init(&fpu_free_mtx, "free fpu context list lock", NULL, MTX_DEF);
|
||||
mtx_init(&fpu_busy_mtx, "busy fpu context list lock", NULL, MTX_DEF);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* PCI and pccard devices don't need to use IRPs to
|
||||
* interact with their bus drivers (usually), so our
|
||||
@ -132,6 +156,9 @@ int
|
||||
windrv_libfini(void)
|
||||
{
|
||||
struct drvdb_ent *d;
|
||||
#ifdef __amd64__
|
||||
struct fpu_cc_ent *ent;
|
||||
#endif
|
||||
|
||||
mtx_lock(&drvdb_mtx);
|
||||
while(STAILQ_FIRST(&drvdb_head) != NULL) {
|
||||
@ -149,6 +176,18 @@ windrv_libfini(void)
|
||||
#ifdef __i386__
|
||||
smp_rendezvous(NULL, x86_oldldt, NULL, NULL);
|
||||
ExFreePool(my_tids);
|
||||
#endif
|
||||
#ifdef __amd64__
|
||||
while ((ent = LIST_FIRST(&fpu_free_head)) != NULL) {
|
||||
LIST_REMOVE(ent, entries);
|
||||
fpu_kern_free_ctx(ent->ctx);
|
||||
free(ent, M_DEVBUF);
|
||||
}
|
||||
mtx_destroy(&fpu_free_mtx);
|
||||
|
||||
ent = LIST_FIRST(&fpu_busy_head);
|
||||
KASSERT(ent == NULL, ("busy fpu context list is not empty"));
|
||||
mtx_destroy(&fpu_busy_mtx);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
@ -615,6 +654,148 @@ windrv_wrap(func, wrap, argcnt, ftype)
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static struct fpu_cc_ent *
|
||||
request_fpu_cc_ent(void)
|
||||
{
|
||||
struct fpu_cc_ent *ent;
|
||||
|
||||
mtx_lock(&fpu_free_mtx);
|
||||
if ((ent = LIST_FIRST(&fpu_free_head)) != NULL) {
|
||||
LIST_REMOVE(ent, entries);
|
||||
mtx_unlock(&fpu_free_mtx);
|
||||
mtx_lock(&fpu_busy_mtx);
|
||||
LIST_INSERT_HEAD(&fpu_busy_head, ent, entries);
|
||||
mtx_unlock(&fpu_busy_mtx);
|
||||
return (ent);
|
||||
}
|
||||
mtx_unlock(&fpu_free_mtx);
|
||||
|
||||
if ((ent = malloc(sizeof(struct fpu_cc_ent), M_DEVBUF, M_NOWAIT |
|
||||
M_ZERO)) != NULL) {
|
||||
ent->ctx = fpu_kern_alloc_ctx(FPU_KERN_NORMAL |
|
||||
FPU_KERN_NOWAIT);
|
||||
if (ent->ctx != NULL) {
|
||||
mtx_lock(&fpu_busy_mtx);
|
||||
LIST_INSERT_HEAD(&fpu_busy_head, ent, entries);
|
||||
mtx_unlock(&fpu_busy_mtx);
|
||||
} else {
|
||||
free(ent, M_DEVBUF);
|
||||
ent = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return (ent);
|
||||
}
|
||||
|
||||
static void
|
||||
release_fpu_cc_ent(struct fpu_cc_ent *ent)
|
||||
{
|
||||
mtx_lock(&fpu_busy_mtx);
|
||||
LIST_REMOVE(ent, entries);
|
||||
mtx_unlock(&fpu_busy_mtx);
|
||||
mtx_lock(&fpu_free_mtx);
|
||||
LIST_INSERT_HEAD(&fpu_free_head, ent, entries);
|
||||
mtx_unlock(&fpu_free_mtx);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
_x86_64_call1(void *fn, uint64_t a)
|
||||
{
|
||||
struct fpu_cc_ent *ent;
|
||||
uint64_t ret;
|
||||
|
||||
if ((ent = request_fpu_cc_ent()) == NULL)
|
||||
return (ENOMEM);
|
||||
fpu_kern_enter(curthread, ent->ctx, FPU_KERN_NORMAL);
|
||||
ret = x86_64_call1(fn, a);
|
||||
fpu_kern_leave(curthread, ent->ctx);
|
||||
release_fpu_cc_ent(ent);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
_x86_64_call2(void *fn, uint64_t a, uint64_t b)
|
||||
{
|
||||
struct fpu_cc_ent *ent;
|
||||
uint64_t ret;
|
||||
|
||||
if ((ent = request_fpu_cc_ent()) == NULL)
|
||||
return (ENOMEM);
|
||||
fpu_kern_enter(curthread, ent->ctx, FPU_KERN_NORMAL);
|
||||
ret = x86_64_call2(fn, a, b);
|
||||
fpu_kern_leave(curthread, ent->ctx);
|
||||
release_fpu_cc_ent(ent);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
_x86_64_call3(void *fn, uint64_t a, uint64_t b, uint64_t c)
|
||||
{
|
||||
struct fpu_cc_ent *ent;
|
||||
uint64_t ret;
|
||||
|
||||
if ((ent = request_fpu_cc_ent()) == NULL)
|
||||
return (ENOMEM);
|
||||
fpu_kern_enter(curthread, ent->ctx, FPU_KERN_NORMAL);
|
||||
ret = x86_64_call3(fn, a, b, c);
|
||||
fpu_kern_leave(curthread, ent->ctx);
|
||||
release_fpu_cc_ent(ent);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
_x86_64_call4(void *fn, uint64_t a, uint64_t b, uint64_t c, uint64_t d)
|
||||
{
|
||||
struct fpu_cc_ent *ent;
|
||||
uint64_t ret;
|
||||
|
||||
if ((ent = request_fpu_cc_ent()) == NULL)
|
||||
return (ENOMEM);
|
||||
fpu_kern_enter(curthread, ent->ctx, FPU_KERN_NORMAL);
|
||||
ret = x86_64_call4(fn, a, b, c, d);
|
||||
fpu_kern_leave(curthread, ent->ctx);
|
||||
release_fpu_cc_ent(ent);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
_x86_64_call5(void *fn, uint64_t a, uint64_t b, uint64_t c, uint64_t d,
|
||||
uint64_t e)
|
||||
{
|
||||
struct fpu_cc_ent *ent;
|
||||
uint64_t ret;
|
||||
|
||||
if ((ent = request_fpu_cc_ent()) == NULL)
|
||||
return (ENOMEM);
|
||||
fpu_kern_enter(curthread, ent->ctx, FPU_KERN_NORMAL);
|
||||
ret = x86_64_call5(fn, a, b, c, d, e);
|
||||
fpu_kern_leave(curthread, ent->ctx);
|
||||
release_fpu_cc_ent(ent);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
_x86_64_call6(void *fn, uint64_t a, uint64_t b, uint64_t c, uint64_t d,
|
||||
uint64_t e, uint64_t f)
|
||||
{
|
||||
struct fpu_cc_ent *ent;
|
||||
uint64_t ret;
|
||||
|
||||
if ((ent = request_fpu_cc_ent()) == NULL)
|
||||
return (ENOMEM);
|
||||
fpu_kern_enter(curthread, ent->ctx, FPU_KERN_NORMAL);
|
||||
ret = x86_64_call6(fn, a, b, c, d, e, f);
|
||||
fpu_kern_leave(curthread, ent->ctx);
|
||||
release_fpu_cc_ent(ent);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
#endif /* __amd64__ */
|
||||
|
||||
|
||||
|
@ -460,22 +460,30 @@ extern uint64_t x86_64_call5(void *, uint64_t, uint64_t, uint64_t, uint64_t,
|
||||
extern uint64_t x86_64_call6(void *, uint64_t, uint64_t, uint64_t, uint64_t,
|
||||
uint64_t, uint64_t);
|
||||
|
||||
uint64_t _x86_64_call1(void *, uint64_t);
|
||||
uint64_t _x86_64_call2(void *, uint64_t, uint64_t);
|
||||
uint64_t _x86_64_call3(void *, uint64_t, uint64_t, uint64_t);
|
||||
uint64_t _x86_64_call4(void *, uint64_t, uint64_t, uint64_t, uint64_t);
|
||||
uint64_t _x86_64_call5(void *, uint64_t, uint64_t, uint64_t, uint64_t,
|
||||
uint64_t);
|
||||
uint64_t _x86_64_call6(void *, uint64_t, uint64_t, uint64_t, uint64_t,
|
||||
uint64_t, uint64_t);
|
||||
|
||||
#define MSCALL1(fn, a) \
|
||||
x86_64_call1((fn), (uint64_t)(a))
|
||||
_x86_64_call1((fn), (uint64_t)(a))
|
||||
#define MSCALL2(fn, a, b) \
|
||||
x86_64_call2((fn), (uint64_t)(a), (uint64_t)(b))
|
||||
_x86_64_call2((fn), (uint64_t)(a), (uint64_t)(b))
|
||||
#define MSCALL3(fn, a, b, c) \
|
||||
x86_64_call3((fn), (uint64_t)(a), (uint64_t)(b), \
|
||||
_x86_64_call3((fn), (uint64_t)(a), (uint64_t)(b), \
|
||||
(uint64_t)(c))
|
||||
#define MSCALL4(fn, a, b, c, d) \
|
||||
x86_64_call4((fn), (uint64_t)(a), (uint64_t)(b), \
|
||||
_x86_64_call4((fn), (uint64_t)(a), (uint64_t)(b), \
|
||||
(uint64_t)(c), (uint64_t)(d))
|
||||
#define MSCALL5(fn, a, b, c, d, e) \
|
||||
x86_64_call5((fn), (uint64_t)(a), (uint64_t)(b), \
|
||||
_x86_64_call5((fn), (uint64_t)(a), (uint64_t)(b), \
|
||||
(uint64_t)(c), (uint64_t)(d), (uint64_t)(e))
|
||||
#define MSCALL6(fn, a, b, c, d, e, f) \
|
||||
x86_64_call6((fn), (uint64_t)(a), (uint64_t)(b), \
|
||||
_x86_64_call6((fn), (uint64_t)(a), (uint64_t)(b), \
|
||||
(uint64_t)(c), (uint64_t)(d), (uint64_t)(e), (uint64_t)(f))
|
||||
|
||||
#endif /* __amd64__ */
|
||||
|
@ -843,7 +843,6 @@ device vxlan
|
||||
# and ath drivers and will eventually be required by all 802.11 drivers.
|
||||
device wlan
|
||||
options IEEE80211_DEBUG #enable debugging msgs
|
||||
options IEEE80211_AMPDU_AGE #age frames in AMPDU reorder q's
|
||||
options IEEE80211_SUPPORT_MESH #enable 802.11s D3.0 support
|
||||
options IEEE80211_SUPPORT_TDMA #enable TDMA support
|
||||
|
||||
|
@ -31,13 +31,12 @@ opt_scsi.h:
|
||||
echo "#define SCSI_DELAY 15000" > ${.TARGET}
|
||||
opt_wlan.h:
|
||||
echo "#define IEEE80211_DEBUG 1" > ${.TARGET}
|
||||
echo "#define IEEE80211_AMPDU_AGE 1" >> ${.TARGET}
|
||||
echo "#define IEEE80211_SUPPORT_MESH 1" >> ${.TARGET}
|
||||
KERN_OPTS.i386=NEW_PCIB DEV_PCI
|
||||
KERN_OPTS.amd64=NEW_PCIB DEV_PCI
|
||||
KERN_OPTS.powerpc=NEW_PCIB DEV_PCI
|
||||
KERN_OPTS=MROUTING IEEE80211_DEBUG \
|
||||
IEEE80211_AMPDU_AGE IEEE80211_SUPPORT_MESH DEV_BPF \
|
||||
IEEE80211_SUPPORT_MESH DEV_BPF \
|
||||
${KERN_OPTS.${MACHINE}} ${KERN_OPTS_EXTRA}
|
||||
.if ${MK_INET_SUPPORT} != "no"
|
||||
KERN_OPTS+= INET TCP_OFFLOAD
|
||||
|
@ -908,7 +908,6 @@ HWPMC_MIPS_BACKTRACE opt_hwpmc_hooks.h
|
||||
# 802.11 support layer
|
||||
IEEE80211_DEBUG opt_wlan.h
|
||||
IEEE80211_DEBUG_REFCNT opt_wlan.h
|
||||
IEEE80211_AMPDU_AGE opt_wlan.h
|
||||
IEEE80211_SUPPORT_MESH opt_wlan.h
|
||||
IEEE80211_SUPPORT_SUPERG opt_wlan.h
|
||||
IEEE80211_SUPPORT_TDMA opt_wlan.h
|
||||
|
@ -1229,6 +1229,7 @@ t4_hashfilter_ao_rpl(struct sge_iq *iq, const struct rss_header *rss,
|
||||
/* provide errno instead of tid to ioctl */
|
||||
f->tid = act_open_rpl_status_to_errno(status);
|
||||
f->valid = 0;
|
||||
f->pending = 0;
|
||||
if (act_open_has_tid(status))
|
||||
release_tid(sc, GET_TID(cpl), &sc->sge.ctrlq[0]);
|
||||
free_filter_resources(f);
|
||||
@ -1587,7 +1588,6 @@ set_hashfilter(struct adapter *sc, struct t4_filter *t, uint64_t ftuple,
|
||||
f->locked = 0;
|
||||
t->idx = f->tid;
|
||||
} else {
|
||||
remove_hf(sc, f);
|
||||
rc = f->tid;
|
||||
free(f, M_CXGBE);
|
||||
}
|
||||
|
@ -480,9 +480,10 @@ SYSCTL_INT(_hw_cxgbe, OID_AUTO, autoneg, CTLFLAG_RDTUN, &t4_autoneg, 0,
|
||||
|
||||
/*
|
||||
* Firmware auto-install by driver during attach (0, 1, 2 = prohibited, allowed,
|
||||
* encouraged respectively).
|
||||
* encouraged respectively). '-n' is the same as 'n' except the firmware
|
||||
* version used in the checks is read from the firmware bundled with the driver.
|
||||
*/
|
||||
static unsigned int t4_fw_install = 1;
|
||||
static int t4_fw_install = 1;
|
||||
SYSCTL_INT(_hw_cxgbe, OID_AUTO, fw_install, CTLFLAG_RDTUN, &t4_fw_install, 0,
|
||||
"Firmware auto-install (0 = prohibited, 1 = allowed, 2 = encouraged)");
|
||||
|
||||
@ -3324,17 +3325,38 @@ cfg_itype_and_nqueues(struct adapter *sc, struct intrs_and_queues *iaq)
|
||||
V_FW_HDR_FW_VER_BUILD(chip##FW_VERSION_BUILD))
|
||||
#define FW_INTFVER(chip, intf) (chip##FW_HDR_INTFVER_##intf)
|
||||
|
||||
/* Just enough of fw_hdr to cover all version info. */
|
||||
struct fw_h {
|
||||
__u8 ver;
|
||||
__u8 chip;
|
||||
__be16 len512;
|
||||
__be32 fw_ver;
|
||||
__be32 tp_microcode_ver;
|
||||
__u8 intfver_nic;
|
||||
__u8 intfver_vnic;
|
||||
__u8 intfver_ofld;
|
||||
__u8 intfver_ri;
|
||||
__u8 intfver_iscsipdu;
|
||||
__u8 intfver_iscsi;
|
||||
__u8 intfver_fcoepdu;
|
||||
__u8 intfver_fcoe;
|
||||
};
|
||||
/* Spot check a couple of fields. */
|
||||
CTASSERT(offsetof(struct fw_h, fw_ver) == offsetof(struct fw_hdr, fw_ver));
|
||||
CTASSERT(offsetof(struct fw_h, intfver_nic) == offsetof(struct fw_hdr, intfver_nic));
|
||||
CTASSERT(offsetof(struct fw_h, intfver_fcoe) == offsetof(struct fw_hdr, intfver_fcoe));
|
||||
|
||||
struct fw_info {
|
||||
uint8_t chip;
|
||||
char *kld_name;
|
||||
char *fw_mod_name;
|
||||
struct fw_hdr fw_hdr; /* XXX: waste of space, need a sparse struct */
|
||||
struct fw_h fw_h;
|
||||
} fw_info[] = {
|
||||
{
|
||||
.chip = CHELSIO_T4,
|
||||
.kld_name = "t4fw_cfg",
|
||||
.fw_mod_name = "t4fw",
|
||||
.fw_hdr = {
|
||||
.fw_h = {
|
||||
.chip = FW_HDR_CHIP_T4,
|
||||
.fw_ver = htobe32(FW_VERSION(T4)),
|
||||
.intfver_nic = FW_INTFVER(T4, NIC),
|
||||
@ -3350,7 +3372,7 @@ struct fw_info {
|
||||
.chip = CHELSIO_T5,
|
||||
.kld_name = "t5fw_cfg",
|
||||
.fw_mod_name = "t5fw",
|
||||
.fw_hdr = {
|
||||
.fw_h = {
|
||||
.chip = FW_HDR_CHIP_T5,
|
||||
.fw_ver = htobe32(FW_VERSION(T5)),
|
||||
.intfver_nic = FW_INTFVER(T5, NIC),
|
||||
@ -3366,7 +3388,7 @@ struct fw_info {
|
||||
.chip = CHELSIO_T6,
|
||||
.kld_name = "t6fw_cfg",
|
||||
.fw_mod_name = "t6fw",
|
||||
.fw_hdr = {
|
||||
.fw_h = {
|
||||
.chip = FW_HDR_CHIP_T6,
|
||||
.fw_ver = htobe32(FW_VERSION(T6)),
|
||||
.intfver_nic = FW_INTFVER(T6, NIC),
|
||||
@ -3398,7 +3420,7 @@ find_fw_info(int chip)
|
||||
* with?
|
||||
*/
|
||||
static int
|
||||
fw_compatible(const struct fw_hdr *hdr1, const struct fw_hdr *hdr2)
|
||||
fw_compatible(const struct fw_h *hdr1, const struct fw_h *hdr2)
|
||||
{
|
||||
|
||||
/* short circuit if it's the exact same firmware version */
|
||||
@ -3465,14 +3487,19 @@ unload_fw_module(struct adapter *sc, const struct firmware *dcfg,
|
||||
* +ve errno means a firmware install was attempted but failed.
|
||||
*/
|
||||
static int
|
||||
install_kld_firmware(struct adapter *sc, struct fw_hdr *card_fw,
|
||||
const struct fw_hdr *drv_fw, const char *reason, int *already)
|
||||
install_kld_firmware(struct adapter *sc, struct fw_h *card_fw,
|
||||
const struct fw_h *drv_fw, const char *reason, int *already)
|
||||
{
|
||||
const struct firmware *cfg, *fw;
|
||||
const uint32_t c = be32toh(card_fw->fw_ver);
|
||||
const uint32_t d = be32toh(drv_fw->fw_ver);
|
||||
uint32_t k;
|
||||
int rc;
|
||||
uint32_t d, k;
|
||||
int rc, fw_install;
|
||||
struct fw_h bundled_fw;
|
||||
bool load_attempted;
|
||||
|
||||
cfg = fw = NULL;
|
||||
load_attempted = false;
|
||||
fw_install = t4_fw_install < 0 ? -t4_fw_install : t4_fw_install;
|
||||
|
||||
if (reason != NULL)
|
||||
goto install;
|
||||
@ -3487,7 +3514,23 @@ install_kld_firmware(struct adapter *sc, struct fw_hdr *card_fw,
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (!fw_compatible(card_fw, drv_fw)) {
|
||||
memcpy(&bundled_fw, drv_fw, sizeof(bundled_fw));
|
||||
if (t4_fw_install < 0) {
|
||||
rc = load_fw_module(sc, &cfg, &fw);
|
||||
if (rc != 0 || fw == NULL) {
|
||||
device_printf(sc->dev,
|
||||
"failed to load firmware module: %d. cfg %p, fw %p;"
|
||||
" will use compiled-in firmware version for"
|
||||
"hw.cxgbe.fw_install checks.\n",
|
||||
rc, cfg, fw);
|
||||
} else {
|
||||
memcpy(&bundled_fw, fw->data, sizeof(bundled_fw));
|
||||
}
|
||||
load_attempted = true;
|
||||
}
|
||||
d = be32toh(bundled_fw.fw_ver);
|
||||
|
||||
if (!fw_compatible(card_fw, &bundled_fw)) {
|
||||
reason = "incompatible or unusable";
|
||||
goto install;
|
||||
}
|
||||
@ -3497,25 +3540,64 @@ install_kld_firmware(struct adapter *sc, struct fw_hdr *card_fw,
|
||||
goto install;
|
||||
}
|
||||
|
||||
if (t4_fw_install == 2 && d != c) {
|
||||
if (fw_install == 2 && d != c) {
|
||||
reason = "different than the version bundled with this driver";
|
||||
goto install;
|
||||
}
|
||||
|
||||
return (0);
|
||||
/* No reason to do anything to the firmware already on the card. */
|
||||
rc = 0;
|
||||
goto done;
|
||||
|
||||
install:
|
||||
rc = 0;
|
||||
if ((*already)++)
|
||||
return (0);
|
||||
goto done;
|
||||
|
||||
if (t4_fw_install == 0) {
|
||||
if (fw_install == 0) {
|
||||
device_printf(sc->dev, "firmware on card (%u.%u.%u.%u) is %s, "
|
||||
"but the driver is prohibited from installing a firmware "
|
||||
"on the card.\n",
|
||||
G_FW_HDR_FW_VER_MAJOR(c), G_FW_HDR_FW_VER_MINOR(c),
|
||||
G_FW_HDR_FW_VER_MICRO(c), G_FW_HDR_FW_VER_BUILD(c), reason);
|
||||
|
||||
return (0);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* We'll attempt to install a firmware. Load the module first (if it
|
||||
* hasn't been loaded already).
|
||||
*/
|
||||
if (!load_attempted) {
|
||||
rc = load_fw_module(sc, &cfg, &fw);
|
||||
if (rc != 0 || fw == NULL) {
|
||||
device_printf(sc->dev,
|
||||
"failed to load firmware module: %d. cfg %p, fw %p\n",
|
||||
rc, cfg, fw);
|
||||
/* carry on */
|
||||
}
|
||||
}
|
||||
if (fw == NULL) {
|
||||
device_printf(sc->dev, "firmware on card (%u.%u.%u.%u) is %s, "
|
||||
"but the driver cannot take corrective action because it "
|
||||
"is unable to load the firmware module.\n",
|
||||
G_FW_HDR_FW_VER_MAJOR(c), G_FW_HDR_FW_VER_MINOR(c),
|
||||
G_FW_HDR_FW_VER_MICRO(c), G_FW_HDR_FW_VER_BUILD(c), reason);
|
||||
rc = sc->flags & FW_OK ? 0 : ENOENT;
|
||||
goto done;
|
||||
}
|
||||
k = be32toh(((const struct fw_hdr *)fw->data)->fw_ver);
|
||||
if (k != d) {
|
||||
MPASS(t4_fw_install > 0);
|
||||
device_printf(sc->dev,
|
||||
"firmware in KLD (%u.%u.%u.%u) is not what the driver was "
|
||||
"expecting (%u.%u.%u.%u) and will not be used.\n",
|
||||
G_FW_HDR_FW_VER_MAJOR(k), G_FW_HDR_FW_VER_MINOR(k),
|
||||
G_FW_HDR_FW_VER_MICRO(k), G_FW_HDR_FW_VER_BUILD(k),
|
||||
G_FW_HDR_FW_VER_MAJOR(d), G_FW_HDR_FW_VER_MINOR(d),
|
||||
G_FW_HDR_FW_VER_MICRO(d), G_FW_HDR_FW_VER_BUILD(d));
|
||||
rc = sc->flags & FW_OK ? 0 : EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
device_printf(sc->dev, "firmware on card (%u.%u.%u.%u) is %s, "
|
||||
@ -3525,25 +3607,6 @@ install_kld_firmware(struct adapter *sc, struct fw_hdr *card_fw,
|
||||
G_FW_HDR_FW_VER_MAJOR(d), G_FW_HDR_FW_VER_MINOR(d),
|
||||
G_FW_HDR_FW_VER_MICRO(d), G_FW_HDR_FW_VER_BUILD(d));
|
||||
|
||||
rc = load_fw_module(sc, &cfg, &fw);
|
||||
if (rc != 0 || fw == NULL) {
|
||||
device_printf(sc->dev,
|
||||
"failed to load firmware module: %d. cfg %p, fw %p\n", rc,
|
||||
cfg, fw);
|
||||
rc = sc->flags & FW_OK ? 0 : ENOENT;
|
||||
goto done;
|
||||
}
|
||||
k = be32toh(((const struct fw_hdr *)fw->data)->fw_ver);
|
||||
if (k != d) {
|
||||
device_printf(sc->dev,
|
||||
"firmware in KLD (%u.%u.%u.%u) is not what the driver was "
|
||||
"compiled with and will not be used.\n",
|
||||
G_FW_HDR_FW_VER_MAJOR(k), G_FW_HDR_FW_VER_MINOR(k),
|
||||
G_FW_HDR_FW_VER_MICRO(k), G_FW_HDR_FW_VER_BUILD(k));
|
||||
rc = sc->flags & FW_OK ? 0 : EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = -t4_fw_upgrade(sc, sc->mbox, fw->data, fw->datasize, 0);
|
||||
if (rc != 0) {
|
||||
device_printf(sc->dev, "failed to install firmware: %d\n", rc);
|
||||
@ -3571,7 +3634,7 @@ contact_firmware(struct adapter *sc)
|
||||
enum dev_state state;
|
||||
struct fw_info *fw_info;
|
||||
struct fw_hdr *card_fw; /* fw on the card */
|
||||
const struct fw_hdr *drv_fw; /* fw bundled with the driver */
|
||||
const struct fw_h *drv_fw;
|
||||
|
||||
fw_info = find_fw_info(chip_id(sc));
|
||||
if (fw_info == NULL) {
|
||||
@ -3580,7 +3643,7 @@ contact_firmware(struct adapter *sc)
|
||||
chip_id(sc));
|
||||
return (EINVAL);
|
||||
}
|
||||
drv_fw = &fw_info->fw_hdr;
|
||||
drv_fw = &fw_info->fw_h;
|
||||
|
||||
/* Read the header of the firmware on the card */
|
||||
card_fw = malloc(sizeof(*card_fw), M_CXGBE, M_ZERO | M_WAITOK);
|
||||
@ -3593,7 +3656,8 @@ contact_firmware(struct adapter *sc)
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = install_kld_firmware(sc, card_fw, drv_fw, NULL, &already);
|
||||
rc = install_kld_firmware(sc, (struct fw_h *)card_fw, drv_fw, NULL,
|
||||
&already);
|
||||
if (rc == ERESTART)
|
||||
goto restart;
|
||||
if (rc != 0)
|
||||
@ -3606,7 +3670,7 @@ contact_firmware(struct adapter *sc)
|
||||
"failed to connect to the firmware: %d, %d. "
|
||||
"PCIE_FW 0x%08x\n", rc, state, t4_read_reg(sc, A_PCIE_FW));
|
||||
#if 0
|
||||
if (install_kld_firmware(sc, card_fw, drv_fw,
|
||||
if (install_kld_firmware(sc, (struct fw_h *)card_fw, drv_fw,
|
||||
"not responding properly to HELLO", &already) == ERESTART)
|
||||
goto restart;
|
||||
#endif
|
||||
@ -3617,7 +3681,8 @@ contact_firmware(struct adapter *sc)
|
||||
|
||||
if (rc == sc->pf) {
|
||||
sc->flags |= MASTER_PF;
|
||||
rc = install_kld_firmware(sc, card_fw, drv_fw, NULL, &already);
|
||||
rc = install_kld_firmware(sc, (struct fw_h *)card_fw, drv_fw,
|
||||
NULL, &already);
|
||||
if (rc == ERESTART)
|
||||
rc = 0;
|
||||
else if (rc != 0)
|
||||
|
@ -3512,6 +3512,7 @@ pmc_syscall_handler(struct thread *td, void *syscall_args)
|
||||
struct pmc_classdep *pcd;
|
||||
int cl;
|
||||
|
||||
memset(&gci, 0, sizeof(gci));
|
||||
gci.pm_cputype = md->pmd_cputype;
|
||||
gci.pm_ncpu = pmc_cpu_max();
|
||||
gci.pm_npmc = md->pmd_npmc;
|
||||
@ -3661,7 +3662,7 @@ pmc_syscall_handler(struct thread *td, void *syscall_args)
|
||||
npmc = md->pmd_npmc;
|
||||
|
||||
pmcinfo_size = npmc * sizeof(struct pmc_info);
|
||||
pmcinfo = malloc(pmcinfo_size, M_PMC, M_WAITOK);
|
||||
pmcinfo = malloc(pmcinfo_size, M_PMC, M_WAITOK | M_ZERO);
|
||||
|
||||
p = pmcinfo;
|
||||
|
||||
|
@ -1033,7 +1033,8 @@ iwm_reset_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring)
|
||||
* The hw rx ring index in shared memory must also be cleared,
|
||||
* otherwise the discrepancy can cause reprocessing chaos.
|
||||
*/
|
||||
memset(sc->rxq.stat, 0, sizeof(*sc->rxq.stat));
|
||||
if (sc->rxq.stat)
|
||||
memset(sc->rxq.stat, 0, sizeof(*sc->rxq.stat));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -131,8 +131,8 @@ static const struct iwn_ident iwn_ident_table[] = {
|
||||
|
||||
static int iwn_probe(device_t);
|
||||
static int iwn_attach(device_t);
|
||||
static int iwn4965_attach(struct iwn_softc *, uint16_t);
|
||||
static int iwn5000_attach(struct iwn_softc *, uint16_t);
|
||||
static void iwn4965_attach(struct iwn_softc *, uint16_t);
|
||||
static void iwn5000_attach(struct iwn_softc *, uint16_t);
|
||||
static int iwn_config_specific(struct iwn_softc *, uint16_t);
|
||||
static void iwn_radiotap_attach(struct iwn_softc *);
|
||||
static void iwn_sysctlattach(struct iwn_softc *);
|
||||
@ -495,14 +495,9 @@ iwn_attach(device_t dev)
|
||||
* Let's set those up first.
|
||||
*/
|
||||
if (sc->hw_type == IWN_HW_REV_TYPE_4965)
|
||||
error = iwn4965_attach(sc, pci_get_device(dev));
|
||||
iwn4965_attach(sc, pci_get_device(dev));
|
||||
else
|
||||
error = iwn5000_attach(sc, pci_get_device(dev));
|
||||
if (error != 0) {
|
||||
device_printf(dev, "could not attach device, error %d\n",
|
||||
error);
|
||||
goto fail;
|
||||
}
|
||||
iwn5000_attach(sc, pci_get_device(dev));
|
||||
|
||||
/*
|
||||
* Next, let's setup the various parameters of each NIC.
|
||||
@ -1224,12 +1219,13 @@ iwn_config_specific(struct iwn_softc *sc, uint16_t pid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
iwn4965_attach(struct iwn_softc *sc, uint16_t pid)
|
||||
{
|
||||
struct iwn_ops *ops = &sc->ops;
|
||||
|
||||
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);
|
||||
|
||||
ops->load_firmware = iwn4965_load_firmware;
|
||||
ops->read_eeprom = iwn4965_read_eeprom;
|
||||
ops->post_alive = iwn4965_post_alive;
|
||||
@ -1264,11 +1260,9 @@ iwn4965_attach(struct iwn_softc *sc, uint16_t pid)
|
||||
sc->sc_flags |= IWN_FLAG_BTCOEX;
|
||||
|
||||
DPRINTF(sc, IWN_DEBUG_TRACE, "%s: end\n",__func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
iwn5000_attach(struct iwn_softc *sc, uint16_t pid)
|
||||
{
|
||||
struct iwn_ops *ops = &sc->ops;
|
||||
@ -1303,7 +1297,7 @@ iwn5000_attach(struct iwn_softc *sc, uint16_t pid)
|
||||
sc->reset_noise_gain = IWN5000_PHY_CALIB_RESET_NOISE_GAIN;
|
||||
sc->noise_gain = IWN5000_PHY_CALIB_NOISE_GAIN;
|
||||
|
||||
return 0;
|
||||
DPRINTF(sc, IWN_DEBUG_TRACE, "%s: end\n",__func__);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4593,10 +4587,6 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
|
||||
if (!IEEE80211_AMPDU_RUNNING(tap))
|
||||
return (EINVAL);
|
||||
|
||||
/* NB: clear Fragment Number field. */
|
||||
/* XXX move this to net80211 */
|
||||
*(uint16_t *)wh->i_seq = 0;
|
||||
|
||||
ac = *(int *)tap->txa_private;
|
||||
}
|
||||
|
||||
|
@ -1750,7 +1750,7 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw,
|
||||
case 0x0000:
|
||||
/* mask VLAN ID */
|
||||
fdirm |= IXGBE_FDIRM_VLANID;
|
||||
/* fall through */
|
||||
/* FALLTHROUGH */
|
||||
case 0x0FFF:
|
||||
/* mask VLAN priority */
|
||||
fdirm |= IXGBE_FDIRM_VLANP;
|
||||
@ -2039,7 +2039,7 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
|
||||
DEBUGOUT(" Error on src/dst port\n");
|
||||
return IXGBE_ERR_CONFIG;
|
||||
}
|
||||
/* fall through */
|
||||
/* FALLTHROUGH */
|
||||
case IXGBE_ATR_FLOW_TYPE_TCPV4:
|
||||
case IXGBE_ATR_FLOW_TYPE_TUNNELED_TCPV4:
|
||||
case IXGBE_ATR_FLOW_TYPE_UDPV4:
|
||||
|
@ -269,7 +269,8 @@ s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw)
|
||||
if (ret_val != IXGBE_SUCCESS)
|
||||
goto out;
|
||||
|
||||
/* fall through - only backplane uses autoc */
|
||||
/* only backplane uses autoc */
|
||||
/* FALLTHROUGH */
|
||||
case ixgbe_media_type_fiber_fixed:
|
||||
case ixgbe_media_type_fiber_qsfp:
|
||||
case ixgbe_media_type_fiber:
|
||||
@ -4756,7 +4757,8 @@ void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, int num_pb, u32 headroom,
|
||||
rxpktsize <<= IXGBE_RXPBSIZE_SHIFT;
|
||||
for (; i < (num_pb / 2); i++)
|
||||
IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
|
||||
/* fall through - configure remaining packet buffers */
|
||||
/* configure remaining packet buffers */
|
||||
/* FALLTHROUGH */
|
||||
case PBA_STRATEGY_EQUAL:
|
||||
rxpktsize = (pbsize / (num_pb - i)) << IXGBE_RXPBSIZE_SHIFT;
|
||||
for (; i < num_pb; i++)
|
||||
|
@ -96,6 +96,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
|
||||
USB_QUIRK(TELEX, MIC1, 0x009, 0x009, UQ_AU_NO_FRAC),
|
||||
USB_QUIRK(SILICONPORTALS, YAPPHONE, 0x100, 0x100, UQ_AU_INP_ASYNC),
|
||||
USB_QUIRK(LOGITECH, UN53B, 0x0000, 0xffff, UQ_NO_STRINGS),
|
||||
USB_QUIRK(LOGITECH, G510S, 0x0000, 0xFFFF, UQ_KBD_BOOTPROTO),
|
||||
USB_QUIRK(REALTEK, RTL8196EU, 0x0000, 0xffff, UQ_CFG_INDEX_1),
|
||||
USB_QUIRK(ELSA, MODEM1, 0x0000, 0xffff, UQ_CFG_INDEX_1),
|
||||
USB_QUIRK(PLANEX2, MZKUE150N, 0x0000, 0xffff, UQ_CFG_INDEX_1),
|
||||
|
@ -2842,6 +2842,7 @@ product LOGITECH UN58A 0xc030 iFeel Mouse
|
||||
product LOGITECH UN53B 0xc032 iFeel MouseMan
|
||||
product LOGITECH WMPAD 0xc208 WingMan GamePad Extreme
|
||||
product LOGITECH WMRPAD 0xc20a WingMan RumblePad
|
||||
product LOGITECH G510S 0xc22d G510s Keyboard
|
||||
product LOGITECH WMJOY 0xc281 WingMan Force joystick
|
||||
product LOGITECH BB13 0xc401 USB-PS/2 Trackball
|
||||
product LOGITECH RK53 0xc501 Cordless mouse
|
||||
|
@ -2824,69 +2824,80 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen)
|
||||
uint8_t ant, rssi;
|
||||
int8_t nf;
|
||||
|
||||
rxwi = mtod(m, struct rt2860_rxwi *);
|
||||
len = le16toh(rxwi->len) & 0xfff;
|
||||
rxwisize = sizeof(struct rt2860_rxwi);
|
||||
if (sc->mac_ver == 0x5592)
|
||||
rxwisize += sizeof(uint64_t);
|
||||
else if (sc->mac_ver == 0x3593)
|
||||
rxwisize += sizeof(uint32_t);
|
||||
if (__predict_false(len > dmalen)) {
|
||||
m_freem(m);
|
||||
counter_u64_add(ic->ic_ierrors, 1);
|
||||
|
||||
if (__predict_false(dmalen <
|
||||
rxwisize + sizeof(struct ieee80211_frame_ack))) {
|
||||
RUN_DPRINTF(sc, RUN_DEBUG_RECV,
|
||||
"payload is too short: dma length %u < %zu\n",
|
||||
dmalen, rxwisize + sizeof(struct ieee80211_frame_ack));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rxwi = mtod(m, struct rt2860_rxwi *);
|
||||
len = le16toh(rxwi->len) & 0xfff;
|
||||
|
||||
if (__predict_false(len > dmalen - rxwisize)) {
|
||||
RUN_DPRINTF(sc, RUN_DEBUG_RECV,
|
||||
"bad RXWI length %u > %u\n", len, dmalen);
|
||||
return;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Rx descriptor is located at the end */
|
||||
rxd = (struct rt2870_rxd *)(mtod(m, caddr_t) + dmalen);
|
||||
flags = le32toh(rxd->flags);
|
||||
|
||||
if (__predict_false(flags & (RT2860_RX_CRCERR | RT2860_RX_ICVERR))) {
|
||||
m_freem(m);
|
||||
counter_u64_add(ic->ic_ierrors, 1);
|
||||
RUN_DPRINTF(sc, RUN_DEBUG_RECV, "%s error.\n",
|
||||
(flags & RT2860_RX_CRCERR)?"CRC":"ICV");
|
||||
return;
|
||||
}
|
||||
|
||||
m->m_data += rxwisize;
|
||||
m->m_pkthdr.len = m->m_len -= rxwisize;
|
||||
|
||||
wh = mtod(m, struct ieee80211_frame *);
|
||||
|
||||
if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
|
||||
wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED;
|
||||
m->m_flags |= M_WEP;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (flags & RT2860_RX_L2PAD) {
|
||||
/*
|
||||
* XXX OpenBSD removes padding between header
|
||||
* and payload here...
|
||||
*/
|
||||
RUN_DPRINTF(sc, RUN_DEBUG_RECV,
|
||||
"received RT2860_RX_L2PAD frame\n");
|
||||
len += 2;
|
||||
}
|
||||
|
||||
ni = ieee80211_find_rxnode(ic,
|
||||
mtod(m, struct ieee80211_frame_min *));
|
||||
m->m_data += rxwisize;
|
||||
m->m_pkthdr.len = m->m_len = len;
|
||||
|
||||
wh = mtod(m, struct ieee80211_frame *);
|
||||
|
||||
/* XXX wrong for monitor mode */
|
||||
if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
|
||||
wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED;
|
||||
m->m_flags |= M_WEP;
|
||||
}
|
||||
|
||||
if (len >= sizeof(struct ieee80211_frame_min)) {
|
||||
ni = ieee80211_find_rxnode(ic,
|
||||
mtod(m, struct ieee80211_frame_min *));
|
||||
} else
|
||||
ni = NULL;
|
||||
|
||||
if (__predict_false(flags & RT2860_RX_MICERR)) {
|
||||
/* report MIC failures to net80211 for TKIP */
|
||||
if (ni != NULL)
|
||||
ieee80211_notify_michael_failure(ni->ni_vap, wh,
|
||||
rxwi->keyidx);
|
||||
m_freem(m);
|
||||
counter_u64_add(ic->ic_ierrors, 1);
|
||||
RUN_DPRINTF(sc, RUN_DEBUG_RECV,
|
||||
"MIC error. Someone is lying.\n");
|
||||
return;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ant = run_maxrssi_chain(sc, rxwi);
|
||||
rssi = rxwi->rssi[ant];
|
||||
nf = run_rssi2dbm(sc, rssi, ant);
|
||||
|
||||
m->m_pkthdr.len = m->m_len = len;
|
||||
|
||||
if (__predict_false(ieee80211_radiotap_active(ic))) {
|
||||
struct run_rx_radiotap_header *tap = &sc->sc_rxtap;
|
||||
uint16_t phy;
|
||||
@ -2934,6 +2945,12 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen)
|
||||
} else {
|
||||
(void)ieee80211_input_all(ic, m, rssi, nf);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
fail:
|
||||
m_freem(m);
|
||||
counter_u64_add(ic->ic_ierrors, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2943,7 +2960,7 @@ run_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
struct mbuf *m = NULL;
|
||||
struct mbuf *m0;
|
||||
uint32_t dmalen;
|
||||
uint32_t dmalen, mbuf_len;
|
||||
uint16_t rxwisize;
|
||||
int xferlen;
|
||||
|
||||
@ -3049,6 +3066,14 @@ run_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
|
||||
break;
|
||||
}
|
||||
|
||||
mbuf_len = dmalen + sizeof(struct rt2870_rxd);
|
||||
if (__predict_false(mbuf_len > MCLBYTES)) {
|
||||
RUN_DPRINTF(sc, RUN_DEBUG_RECV_DESC | RUN_DEBUG_USB,
|
||||
"payload is too big: mbuf_len %u\n", mbuf_len);
|
||||
counter_u64_add(ic->ic_ierrors, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
/* copy aggregated frames to another mbuf */
|
||||
m0 = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (__predict_false(m0 == NULL)) {
|
||||
@ -3058,14 +3083,13 @@ run_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
|
||||
break;
|
||||
}
|
||||
m_copydata(m, 4 /* skip 32-bit DMA-len header */,
|
||||
dmalen + sizeof(struct rt2870_rxd), mtod(m0, caddr_t));
|
||||
m0->m_pkthdr.len = m0->m_len =
|
||||
dmalen + sizeof(struct rt2870_rxd);
|
||||
mbuf_len, mtod(m0, caddr_t));
|
||||
m0->m_pkthdr.len = m0->m_len = mbuf_len;
|
||||
run_rx_frame(sc, m0, dmalen);
|
||||
|
||||
/* update data ptr */
|
||||
m->m_data += dmalen + 8;
|
||||
m->m_pkthdr.len = m->m_len -= dmalen + 8;
|
||||
m->m_data += mbuf_len + 4;
|
||||
m->m_pkthdr.len = m->m_len -= mbuf_len + 4;
|
||||
}
|
||||
|
||||
/* make sure we free the source buffer, if any */
|
||||
|
@ -3933,21 +3933,18 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p,
|
||||
|
||||
usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
|
||||
|
||||
if (actlen < (int)URTW_MIN_RXBUFSZ) {
|
||||
counter_u64_add(ic->ic_ierrors, 1);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (sc->sc_flags & URTW_RTL8187B) {
|
||||
struct urtw_8187b_rxhdr *rx;
|
||||
|
||||
if (actlen < sizeof(*rx) + IEEE80211_ACK_LEN)
|
||||
goto fail;
|
||||
|
||||
rx = (struct urtw_8187b_rxhdr *)(data->buf +
|
||||
(actlen - (sizeof(struct urtw_8187b_rxhdr))));
|
||||
flen = le32toh(rx->flag) & 0xfff;
|
||||
if (flen > actlen) {
|
||||
counter_u64_add(ic->ic_ierrors, 1);
|
||||
return (NULL);
|
||||
}
|
||||
if (flen > actlen - sizeof(*rx))
|
||||
goto fail;
|
||||
|
||||
rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf;
|
||||
/* XXX correct? */
|
||||
rssi = rx->rssi & URTW_RX_RSSI_MASK;
|
||||
@ -3955,13 +3952,14 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p,
|
||||
} else {
|
||||
struct urtw_8187l_rxhdr *rx;
|
||||
|
||||
if (actlen < sizeof(*rx) + IEEE80211_ACK_LEN)
|
||||
goto fail;
|
||||
|
||||
rx = (struct urtw_8187l_rxhdr *)(data->buf +
|
||||
(actlen - (sizeof(struct urtw_8187l_rxhdr))));
|
||||
flen = le32toh(rx->flag) & 0xfff;
|
||||
if (flen > actlen) {
|
||||
counter_u64_add(ic->ic_ierrors, 1);
|
||||
return (NULL);
|
||||
}
|
||||
if (flen > actlen - sizeof(*rx))
|
||||
goto fail;
|
||||
|
||||
rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf;
|
||||
/* XXX correct? */
|
||||
@ -3969,11 +3967,12 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p,
|
||||
noise = rx->noise;
|
||||
}
|
||||
|
||||
if (flen < IEEE80211_ACK_LEN)
|
||||
goto fail;
|
||||
|
||||
mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (mnew == NULL) {
|
||||
counter_u64_add(ic->ic_ierrors, 1);
|
||||
return (NULL);
|
||||
}
|
||||
if (mnew == NULL)
|
||||
goto fail;
|
||||
|
||||
m = data->m;
|
||||
data->m = mnew;
|
||||
@ -3992,13 +3991,17 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p,
|
||||
}
|
||||
|
||||
wh = mtod(m, struct ieee80211_frame *);
|
||||
if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA)
|
||||
if (IEEE80211_IS_DATA(wh))
|
||||
sc->sc_currate = (rate > 0) ? rate : sc->sc_currate;
|
||||
|
||||
*rssi_p = rssi;
|
||||
*nf_p = noise; /* XXX correct? */
|
||||
|
||||
return (m);
|
||||
|
||||
fail:
|
||||
counter_u64_add(ic->ic_ierrors, 1);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -4006,7 +4009,6 @@ urtw_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
|
||||
{
|
||||
struct urtw_softc *sc = usbd_xfer_softc(xfer);
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
struct ieee80211_frame *wh;
|
||||
struct ieee80211_node *ni;
|
||||
struct mbuf *m = NULL;
|
||||
struct urtw_data *data;
|
||||
@ -4044,9 +4046,13 @@ urtw_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
|
||||
*/
|
||||
URTW_UNLOCK(sc);
|
||||
if (m != NULL) {
|
||||
wh = mtod(m, struct ieee80211_frame *);
|
||||
ni = ieee80211_find_rxnode(ic,
|
||||
(struct ieee80211_frame_min *)wh);
|
||||
if (m->m_pkthdr.len >=
|
||||
sizeof(struct ieee80211_frame_min)) {
|
||||
ni = ieee80211_find_rxnode(ic,
|
||||
mtod(m, struct ieee80211_frame_min *));
|
||||
} else
|
||||
ni = NULL;
|
||||
|
||||
if (ni != NULL) {
|
||||
(void) ieee80211_input(ni, m, rssi, nf);
|
||||
/* node is no longer needed */
|
||||
|
@ -47,10 +47,6 @@ struct urtw_data {
|
||||
};
|
||||
typedef STAILQ_HEAD(, urtw_data) urtw_datahead;
|
||||
|
||||
/* XXX not correct.. */
|
||||
#define URTW_MIN_RXBUFSZ \
|
||||
(sizeof(struct ieee80211_frame_min))
|
||||
|
||||
#define URTW_RX_DATA_LIST_COUNT 4
|
||||
#define URTW_TX_DATA_LIST_COUNT 16
|
||||
#define URTW_RX_MAXSIZE 0x9c4
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,7 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 Tsubai Masanari
|
||||
* Copyright (c) 2013 Bryan Venteicher <bryanv@FreeBSD.org>
|
||||
* Copyright (c) 2018 Patrick Kelsey
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -22,14 +23,6 @@
|
||||
|
||||
struct vmxnet3_softc;
|
||||
|
||||
struct vmxnet3_dma_alloc {
|
||||
bus_addr_t dma_paddr;
|
||||
caddr_t dma_vaddr;
|
||||
bus_dma_tag_t dma_tag;
|
||||
bus_dmamap_t dma_map;
|
||||
bus_size_t dma_size;
|
||||
};
|
||||
|
||||
/*
|
||||
* The number of Rx/Tx queues this driver prefers.
|
||||
*/
|
||||
@ -57,153 +50,68 @@ struct vmxnet3_dma_alloc {
|
||||
#define VMXNET3_MAX_RX_NCOMPDESC \
|
||||
(VMXNET3_MAX_RX_NDESC * VMXNET3_RXRINGS_PERQ)
|
||||
|
||||
struct vmxnet3_txbuf {
|
||||
bus_dmamap_t vtxb_dmamap;
|
||||
struct mbuf *vtxb_m;
|
||||
};
|
||||
|
||||
struct vmxnet3_txring {
|
||||
struct vmxnet3_txbuf *vxtxr_txbuf;
|
||||
u_int vxtxr_head;
|
||||
u_int vxtxr_next;
|
||||
u_int vxtxr_ndesc;
|
||||
int vxtxr_gen;
|
||||
bus_dma_tag_t vxtxr_txtag;
|
||||
struct vmxnet3_txdesc *vxtxr_txd;
|
||||
struct vmxnet3_dma_alloc vxtxr_dma;
|
||||
};
|
||||
|
||||
static inline int
|
||||
VMXNET3_TXRING_AVAIL(struct vmxnet3_txring *txr)
|
||||
{
|
||||
int avail = txr->vxtxr_next - txr->vxtxr_head - 1;
|
||||
return (avail < 0 ? txr->vxtxr_ndesc + avail : avail);
|
||||
}
|
||||
|
||||
struct vmxnet3_rxbuf {
|
||||
bus_dmamap_t vrxb_dmamap;
|
||||
struct mbuf *vrxb_m;
|
||||
bus_addr_t vxtxr_paddr;
|
||||
};
|
||||
|
||||
struct vmxnet3_rxring {
|
||||
struct vmxnet3_rxbuf *vxrxr_rxbuf;
|
||||
struct vmxnet3_rxdesc *vxrxr_rxd;
|
||||
u_int vxrxr_fill;
|
||||
u_int vxrxr_ndesc;
|
||||
int vxrxr_gen;
|
||||
int vxrxr_rid;
|
||||
bus_dma_tag_t vxrxr_rxtag;
|
||||
struct vmxnet3_dma_alloc vxrxr_dma;
|
||||
bus_dmamap_t vxrxr_spare_dmap;
|
||||
bus_addr_t vxrxr_paddr;
|
||||
};
|
||||
|
||||
static inline void
|
||||
vmxnet3_rxr_increment_fill(struct vmxnet3_rxring *rxr)
|
||||
{
|
||||
|
||||
if (++rxr->vxrxr_fill == rxr->vxrxr_ndesc) {
|
||||
rxr->vxrxr_fill = 0;
|
||||
rxr->vxrxr_gen ^= 1;
|
||||
}
|
||||
}
|
||||
|
||||
struct vmxnet3_comp_ring {
|
||||
union {
|
||||
struct vmxnet3_txcompdesc *txcd;
|
||||
struct vmxnet3_rxcompdesc *rxcd;
|
||||
} vxcr_u;
|
||||
/*
|
||||
* vxcr_next is used on the transmit side to track the next index to
|
||||
* begin cleaning at. It is not used on the receive side.
|
||||
*/
|
||||
u_int vxcr_next;
|
||||
u_int vxcr_ndesc;
|
||||
int vxcr_gen;
|
||||
struct vmxnet3_dma_alloc vxcr_dma;
|
||||
};
|
||||
|
||||
struct vmxnet3_txq_stats {
|
||||
uint64_t vmtxs_opackets; /* if_opackets */
|
||||
uint64_t vmtxs_obytes; /* if_obytes */
|
||||
uint64_t vmtxs_omcasts; /* if_omcasts */
|
||||
uint64_t vmtxs_csum;
|
||||
uint64_t vmtxs_tso;
|
||||
uint64_t vmtxs_full;
|
||||
uint64_t vmtxs_offload_failed;
|
||||
bus_addr_t vxcr_paddr;
|
||||
};
|
||||
|
||||
struct vmxnet3_txqueue {
|
||||
struct mtx vxtxq_mtx;
|
||||
struct vmxnet3_softc *vxtxq_sc;
|
||||
#ifndef VMXNET3_LEGACY_TX
|
||||
struct buf_ring *vxtxq_br;
|
||||
#endif
|
||||
int vxtxq_id;
|
||||
int vxtxq_last_flush;
|
||||
int vxtxq_intr_idx;
|
||||
int vxtxq_watchdog;
|
||||
struct vmxnet3_txring vxtxq_cmd_ring;
|
||||
struct vmxnet3_comp_ring vxtxq_comp_ring;
|
||||
struct vmxnet3_txq_stats vxtxq_stats;
|
||||
struct vmxnet3_txq_shared *vxtxq_ts;
|
||||
struct sysctl_oid_list *vxtxq_sysctl;
|
||||
#ifndef VMXNET3_LEGACY_TX
|
||||
struct task vxtxq_defrtask;
|
||||
#endif
|
||||
char vxtxq_name[16];
|
||||
} __aligned(CACHE_LINE_SIZE);
|
||||
|
||||
#define VMXNET3_TXQ_LOCK(_txq) mtx_lock(&(_txq)->vxtxq_mtx)
|
||||
#define VMXNET3_TXQ_TRYLOCK(_txq) mtx_trylock(&(_txq)->vxtxq_mtx)
|
||||
#define VMXNET3_TXQ_UNLOCK(_txq) mtx_unlock(&(_txq)->vxtxq_mtx)
|
||||
#define VMXNET3_TXQ_LOCK_ASSERT(_txq) \
|
||||
mtx_assert(&(_txq)->vxtxq_mtx, MA_OWNED)
|
||||
#define VMXNET3_TXQ_LOCK_ASSERT_NOTOWNED(_txq) \
|
||||
mtx_assert(&(_txq)->vxtxq_mtx, MA_NOTOWNED)
|
||||
|
||||
struct vmxnet3_rxq_stats {
|
||||
uint64_t vmrxs_ipackets; /* if_ipackets */
|
||||
uint64_t vmrxs_ibytes; /* if_ibytes */
|
||||
uint64_t vmrxs_iqdrops; /* if_iqdrops */
|
||||
uint64_t vmrxs_ierrors; /* if_ierrors */
|
||||
};
|
||||
|
||||
struct vmxnet3_rxqueue {
|
||||
struct mtx vxrxq_mtx;
|
||||
struct vmxnet3_softc *vxrxq_sc;
|
||||
int vxrxq_id;
|
||||
int vxrxq_intr_idx;
|
||||
struct mbuf *vxrxq_mhead;
|
||||
struct mbuf *vxrxq_mtail;
|
||||
struct if_irq vxrxq_irq;
|
||||
struct vmxnet3_rxring vxrxq_cmd_ring[VMXNET3_RXRINGS_PERQ];
|
||||
struct vmxnet3_comp_ring vxrxq_comp_ring;
|
||||
struct vmxnet3_rxq_stats vxrxq_stats;
|
||||
struct vmxnet3_rxq_shared *vxrxq_rs;
|
||||
struct sysctl_oid_list *vxrxq_sysctl;
|
||||
char vxrxq_name[16];
|
||||
} __aligned(CACHE_LINE_SIZE);
|
||||
|
||||
#define VMXNET3_RXQ_LOCK(_rxq) mtx_lock(&(_rxq)->vxrxq_mtx)
|
||||
#define VMXNET3_RXQ_UNLOCK(_rxq) mtx_unlock(&(_rxq)->vxrxq_mtx)
|
||||
#define VMXNET3_RXQ_LOCK_ASSERT(_rxq) \
|
||||
mtx_assert(&(_rxq)->vxrxq_mtx, MA_OWNED)
|
||||
#define VMXNET3_RXQ_LOCK_ASSERT_NOTOWNED(_rxq) \
|
||||
mtx_assert(&(_rxq)->vxrxq_mtx, MA_NOTOWNED)
|
||||
|
||||
struct vmxnet3_statistics {
|
||||
uint32_t vmst_defragged;
|
||||
uint32_t vmst_defrag_failed;
|
||||
uint32_t vmst_mgetcl_failed;
|
||||
uint32_t vmst_mbuf_load_failed;
|
||||
};
|
||||
|
||||
struct vmxnet3_interrupt {
|
||||
struct resource *vmxi_irq;
|
||||
int vmxi_rid;
|
||||
void *vmxi_handler;
|
||||
};
|
||||
|
||||
struct vmxnet3_softc {
|
||||
device_t vmx_dev;
|
||||
if_ctx_t vmx_ctx;
|
||||
if_shared_ctx_t vmx_sctx;
|
||||
if_softc_ctx_t vmx_scctx;
|
||||
struct ifnet *vmx_ifp;
|
||||
struct vmxnet3_driver_shared *vmx_ds;
|
||||
uint32_t vmx_flags;
|
||||
#define VMXNET3_FLAG_NO_MSIX 0x0001
|
||||
#define VMXNET3_FLAG_RSS 0x0002
|
||||
|
||||
struct vmxnet3_rxqueue *vmx_rxq;
|
||||
@ -215,56 +123,24 @@ struct vmxnet3_softc {
|
||||
struct resource *vmx_res1;
|
||||
bus_space_tag_t vmx_iot1;
|
||||
bus_space_handle_t vmx_ioh1;
|
||||
struct resource *vmx_msix_res;
|
||||
|
||||
int vmx_link_active;
|
||||
int vmx_link_speed;
|
||||
int vmx_if_flags;
|
||||
int vmx_ntxqueues;
|
||||
int vmx_nrxqueues;
|
||||
int vmx_ntxdescs;
|
||||
int vmx_nrxdescs;
|
||||
int vmx_max_rxsegs;
|
||||
int vmx_rx_max_chain;
|
||||
|
||||
struct vmxnet3_statistics vmx_stats;
|
||||
|
||||
int vmx_intr_type;
|
||||
int vmx_intr_mask_mode;
|
||||
int vmx_event_intr_idx;
|
||||
int vmx_nintrs;
|
||||
struct vmxnet3_interrupt vmx_intrs[VMXNET3_MAX_INTRS];
|
||||
struct if_irq vmx_event_intr_irq;
|
||||
|
||||
struct mtx vmx_mtx;
|
||||
#ifndef VMXNET3_LEGACY_TX
|
||||
struct taskqueue *vmx_tq;
|
||||
#endif
|
||||
uint8_t *vmx_mcast;
|
||||
void *vmx_qs;
|
||||
struct vmxnet3_rss_shared *vmx_rss;
|
||||
struct callout vmx_tick;
|
||||
struct vmxnet3_dma_alloc vmx_ds_dma;
|
||||
struct vmxnet3_dma_alloc vmx_qs_dma;
|
||||
struct vmxnet3_dma_alloc vmx_mcast_dma;
|
||||
struct vmxnet3_dma_alloc vmx_rss_dma;
|
||||
struct ifmedia vmx_media;
|
||||
int vmx_max_ntxqueues;
|
||||
int vmx_max_nrxqueues;
|
||||
eventhandler_tag vmx_vlan_attach;
|
||||
eventhandler_tag vmx_vlan_detach;
|
||||
struct iflib_dma_info vmx_ds_dma;
|
||||
struct iflib_dma_info vmx_qs_dma;
|
||||
struct iflib_dma_info vmx_mcast_dma;
|
||||
struct iflib_dma_info vmx_rss_dma;
|
||||
struct ifmedia *vmx_media;
|
||||
uint32_t vmx_vlan_filter[4096/32];
|
||||
uint8_t vmx_lladdr[ETHER_ADDR_LEN];
|
||||
};
|
||||
|
||||
#define VMXNET3_CORE_LOCK_INIT(_sc, _name) \
|
||||
mtx_init(&(_sc)->vmx_mtx, _name, "VMXNET3 Lock", MTX_DEF)
|
||||
#define VMXNET3_CORE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->vmx_mtx)
|
||||
#define VMXNET3_CORE_LOCK(_sc) mtx_lock(&(_sc)->vmx_mtx)
|
||||
#define VMXNET3_CORE_UNLOCK(_sc) mtx_unlock(&(_sc)->vmx_mtx)
|
||||
#define VMXNET3_CORE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->vmx_mtx, MA_OWNED)
|
||||
#define VMXNET3_CORE_LOCK_ASSERT_NOTOWNED(_sc) \
|
||||
mtx_assert(&(_sc)->vmx_mtx, MA_NOTOWNED)
|
||||
|
||||
/*
|
||||
* Our driver version we report to the hypervisor; we just keep
|
||||
* this value constant.
|
||||
@ -275,21 +151,28 @@ struct vmxnet3_softc {
|
||||
* Max descriptors per Tx packet. We must limit the size of the
|
||||
* any TSO packets based on the number of segments.
|
||||
*/
|
||||
#define VMXNET3_TX_MAXSEGS 32
|
||||
#define VMXNET3_TX_MAXSEGS 32 /* 64K @ 2K segment size */
|
||||
#define VMXNET3_TX_MAXSIZE (VMXNET3_TX_MAXSEGS * MCLBYTES)
|
||||
#define VMXNET3_TSO_MAXSIZE (VMXNET3_TX_MAXSIZE - ETHER_VLAN_ENCAP_LEN)
|
||||
|
||||
/*
|
||||
* Maximum support Tx segments size. The length field in the
|
||||
* Maximum supported Tx segment size. The length field in the
|
||||
* Tx descriptor is 14 bits.
|
||||
*
|
||||
* XXX It's possible a descriptor length field of 0 means 2^14, but this
|
||||
* isn't confirmed, so limit to 2^14 - 1 for now.
|
||||
*/
|
||||
#define VMXNET3_TX_MAXSEGSIZE (1 << 14)
|
||||
#define VMXNET3_TX_MAXSEGSIZE ((1 << 14) - 1)
|
||||
|
||||
/*
|
||||
* The maximum number of Rx segments we accept. When LRO is enabled,
|
||||
* this allows us to receive the maximum sized frame with one MCLBYTES
|
||||
* cluster followed by 16 MJUMPAGESIZE clusters.
|
||||
* Maximum supported Rx segment size. The length field in the
|
||||
* Rx descriptor is 14 bits.
|
||||
*
|
||||
* The reference drivers skip zero-length descriptors, which seems to be a
|
||||
* strong indication that on the receive side, a descriptor length field of
|
||||
* zero does not mean 2^14.
|
||||
*/
|
||||
#define VMXNET3_MAX_RX_SEGS 17
|
||||
#define VMXNET3_RX_MAXSEGSIZE ((1 << 14) - 1)
|
||||
|
||||
/*
|
||||
* Predetermined size of the multicast MACs filter table. If the
|
||||
@ -298,17 +181,6 @@ struct vmxnet3_softc {
|
||||
*/
|
||||
#define VMXNET3_MULTICAST_MAX 32
|
||||
|
||||
/*
|
||||
* Our Tx watchdog timeout.
|
||||
*/
|
||||
#define VMXNET3_WATCHDOG_TIMEOUT 5
|
||||
|
||||
/*
|
||||
* Number of slots in the Tx bufrings. This value matches most other
|
||||
* multiqueue drivers.
|
||||
*/
|
||||
#define VMXNET3_DEF_BUFRING_SIZE 4096
|
||||
|
||||
/*
|
||||
* IP protocols that we can perform Tx checksum offloading of.
|
||||
*/
|
||||
@ -318,28 +190,4 @@ struct vmxnet3_softc {
|
||||
#define VMXNET3_CSUM_ALL_OFFLOAD \
|
||||
(VMXNET3_CSUM_OFFLOAD | VMXNET3_CSUM_OFFLOAD_IPV6 | CSUM_TSO)
|
||||
|
||||
/*
|
||||
* Compat macros to keep this driver compiling on old releases.
|
||||
*/
|
||||
|
||||
#if !defined(SYSCTL_ADD_UQUAD)
|
||||
#define SYSCTL_ADD_UQUAD SYSCTL_ADD_QUAD
|
||||
#endif
|
||||
|
||||
#if !defined(IFCAP_TXCSUM_IPV6)
|
||||
#define IFCAP_TXCSUM_IPV6 0
|
||||
#endif
|
||||
|
||||
#if !defined(IFCAP_RXCSUM_IPV6)
|
||||
#define IFCAP_RXCSUM_IPV6 0
|
||||
#endif
|
||||
|
||||
#if !defined(CSUM_TCP_IPV6)
|
||||
#define CSUM_TCP_IPV6 0
|
||||
#endif
|
||||
|
||||
#if !defined(CSUM_UDP_IPV6)
|
||||
#define CSUM_UDP_IPV6 0
|
||||
#endif
|
||||
|
||||
#endif /* _IF_VMXVAR_H */
|
||||
|
@ -3614,8 +3614,7 @@ nfssvc_srvcall(struct thread *p, struct nfssvc_args *uap, struct ucred *cred)
|
||||
error = EPERM;
|
||||
if (!error) {
|
||||
len = sizeof (struct nfsd_dumpclients) * dumplist.ndl_size;
|
||||
dumpclients = (struct nfsd_dumpclients *)malloc(len,
|
||||
M_TEMP, M_WAITOK);
|
||||
dumpclients = malloc(len, M_TEMP, M_WAITOK | M_ZERO);
|
||||
nfsrv_dumpclients(dumpclients, dumplist.ndl_size);
|
||||
error = copyout(dumpclients,
|
||||
CAST_USER_ADDR_T(dumplist.ndl_list), len);
|
||||
@ -3633,8 +3632,7 @@ nfssvc_srvcall(struct thread *p, struct nfssvc_args *uap, struct ucred *cred)
|
||||
if (!error) {
|
||||
len = sizeof (struct nfsd_dumplocks) *
|
||||
dumplocklist.ndllck_size;
|
||||
dumplocks = (struct nfsd_dumplocks *)malloc(len,
|
||||
M_TEMP, M_WAITOK);
|
||||
dumplocks = malloc(len, M_TEMP, M_WAITOK | M_ZERO);
|
||||
nfsrv_dumplocks(nd.ni_vp, dumplocks,
|
||||
dumplocklist.ndllck_size, p);
|
||||
vput(nd.ni_vp);
|
||||
|
@ -1120,8 +1120,8 @@ smbfs_advlock(ap)
|
||||
static int
|
||||
smbfs_pathcheck(struct smbmount *smp, const char *name, int nmlen, int nameiop)
|
||||
{
|
||||
static const char *badchars = "*/:<>;?";
|
||||
static const char *badchars83 = " +|,[]=";
|
||||
static const char *badchars = "*/:<>?";
|
||||
static const char *badchars83 = " +|,[]=;";
|
||||
const char *cp;
|
||||
int i, error;
|
||||
|
||||
|
@ -280,7 +280,6 @@ device xe # Xircom pccard Ethernet
|
||||
# Wireless NIC cards
|
||||
device wlan # 802.11 support
|
||||
options IEEE80211_DEBUG # enable debug msgs
|
||||
options IEEE80211_AMPDU_AGE # age frames in AMPDU reorder q's
|
||||
options IEEE80211_SUPPORT_MESH # enable 802.11s draft support
|
||||
device wlan_wep # 802.11 WEP support
|
||||
device wlan_ccmp # 802.11 CCMP support
|
||||
|
@ -136,7 +136,6 @@ device octm
|
||||
# Wireless NIC cards
|
||||
device wlan # 802.11 support
|
||||
options IEEE80211_DEBUG # enable debug msgs
|
||||
options IEEE80211_AMPDU_AGE # age frames in AMPDU reorder q's
|
||||
options IEEE80211_SUPPORT_MESH # enable 802.11s draft support
|
||||
device wlan_wep # 802.11 WEP support
|
||||
device wlan_ccmp # 802.11 CCMP support
|
||||
|
@ -169,7 +169,6 @@ device bge # Broadcom BCM570xx Gigabit Ethernet
|
||||
|
||||
device wlan # 802.11 support
|
||||
options IEEE80211_DEBUG # enable debug msgs
|
||||
options IEEE80211_AMPDU_AGE # age frames in AMPDU reorder q's
|
||||
options IEEE80211_SUPPORT_MESH # enable 802.11s draft support
|
||||
device wlan_wep # 802.11 WEP support
|
||||
device wlan_ccmp # 802.11 CCMP support
|
||||
|
@ -27,10 +27,7 @@
|
||||
|
||||
KMOD= if_vmx
|
||||
SRCS= if_vmx.c
|
||||
SRCS+= bus_if.h device_if.h pci_if.h opt_inet.h opt_inet6.h
|
||||
|
||||
# With VMXNET3_LEGACY_TX, the driver will use the non-multiqueue
|
||||
# capable if_start interface.
|
||||
#CFLAGS+= -DVMXNET3_LEGACY_TX
|
||||
SRCS+= bus_if.h device_if.h pci_if.h ifdi_if.h
|
||||
SRCS+= opt_inet.h opt_inet6.h
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
12
sys/net/if.c
12
sys/net/if.c
@ -168,14 +168,14 @@ struct ifmediareq32 {
|
||||
#define SIOCGIFXMEDIA32 _IOC_NEWTYPE(SIOCGIFXMEDIA, struct ifmediareq32)
|
||||
|
||||
#define _CASE_IOC_IFGROUPREQ_32(cmd) \
|
||||
case _IOC_NEWTYPE((cmd), struct ifgroupreq32):
|
||||
_IOC_NEWTYPE((cmd), struct ifgroupreq32): case
|
||||
#else /* !COMPAT_FREEBSD32 */
|
||||
#define _CASE_IOC_IFGROUPREQ_32(cmd)
|
||||
#endif /* !COMPAT_FREEBSD32 */
|
||||
|
||||
#define CASE_IOC_IFGROUPREQ(cmd) \
|
||||
_CASE_IOC_IFGROUPREQ_32(cmd) \
|
||||
case (cmd)
|
||||
(cmd)
|
||||
|
||||
union ifreq_union {
|
||||
struct ifreq ifr;
|
||||
@ -2894,7 +2894,7 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
|
||||
error = if_gethwaddr(ifp, ifr);
|
||||
break;
|
||||
|
||||
CASE_IOC_IFGROUPREQ(SIOCAIFGROUP):
|
||||
case CASE_IOC_IFGROUPREQ(SIOCAIFGROUP):
|
||||
error = priv_check(td, PRIV_NET_ADDIFGROUP);
|
||||
if (error)
|
||||
return (error);
|
||||
@ -2903,12 +2903,12 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
|
||||
return (error);
|
||||
break;
|
||||
|
||||
CASE_IOC_IFGROUPREQ(SIOCGIFGROUP):
|
||||
case CASE_IOC_IFGROUPREQ(SIOCGIFGROUP):
|
||||
if ((error = if_getgroup((struct ifgroupreq *)data, ifp)))
|
||||
return (error);
|
||||
break;
|
||||
|
||||
CASE_IOC_IFGROUPREQ(SIOCDIFGROUP):
|
||||
case CASE_IOC_IFGROUPREQ(SIOCDIFGROUP):
|
||||
error = priv_check(td, PRIV_NET_DELIFGROUP);
|
||||
if (error)
|
||||
return (error);
|
||||
@ -3063,7 +3063,7 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct thread *td)
|
||||
error = if_clone_list((struct if_clonereq *)data);
|
||||
goto out_noref;
|
||||
|
||||
CASE_IOC_IFGROUPREQ(SIOCGIFGMEMB):
|
||||
case CASE_IOC_IFGROUPREQ(SIOCGIFGMEMB):
|
||||
error = if_getgroupmembers((struct ifgroupreq *)data);
|
||||
goto out_noref;
|
||||
|
||||
|
@ -289,8 +289,6 @@ typedef struct iflib_sw_tx_desc_array {
|
||||
|
||||
/* magic number that should be high enough for any hardware */
|
||||
#define IFLIB_MAX_TX_SEGS 128
|
||||
/* bnxt supports 64 with hardware LRO enabled */
|
||||
#define IFLIB_MAX_RX_SEGS 64
|
||||
#define IFLIB_RX_COPY_THRESH 128
|
||||
#define IFLIB_MAX_RX_REFRESH 32
|
||||
/* The minimum descriptors per second before we start coalescing */
|
||||
@ -1327,16 +1325,13 @@ _iflib_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err)
|
||||
}
|
||||
|
||||
int
|
||||
iflib_dma_alloc(if_ctx_t ctx, int size, iflib_dma_info_t dma, int mapflags)
|
||||
iflib_dma_alloc_align(if_ctx_t ctx, int size, int align, iflib_dma_info_t dma, int mapflags)
|
||||
{
|
||||
int err;
|
||||
if_shared_ctx_t sctx = ctx->ifc_sctx;
|
||||
device_t dev = ctx->ifc_dev;
|
||||
|
||||
KASSERT(sctx->isc_q_align != 0, ("alignment value not initialized"));
|
||||
|
||||
err = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
|
||||
sctx->isc_q_align, 0, /* alignment, bounds */
|
||||
err = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
|
||||
align, 0, /* alignment, bounds */
|
||||
BUS_SPACE_MAXADDR, /* lowaddr */
|
||||
BUS_SPACE_MAXADDR, /* highaddr */
|
||||
NULL, NULL, /* filter, filterarg */
|
||||
@ -1386,6 +1381,16 @@ iflib_dma_alloc(if_ctx_t ctx, int size, iflib_dma_info_t dma, int mapflags)
|
||||
return (err);
|
||||
}
|
||||
|
||||
int
|
||||
iflib_dma_alloc(if_ctx_t ctx, int size, iflib_dma_info_t dma, int mapflags)
|
||||
{
|
||||
if_shared_ctx_t sctx = ctx->ifc_sctx;
|
||||
|
||||
KASSERT(sctx->isc_q_align != 0, ("alignment value not initialized"));
|
||||
|
||||
return (iflib_dma_alloc_align(ctx, size, sctx->isc_q_align, dma, mapflags));
|
||||
}
|
||||
|
||||
int
|
||||
iflib_dma_alloc_multi(if_ctx_t ctx, int *sizes, iflib_dma_info_t *dmalist, int mapflags, int count)
|
||||
{
|
||||
@ -4368,11 +4373,8 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct
|
||||
ctx->ifc_softc = sc;
|
||||
|
||||
if ((err = iflib_register(ctx)) != 0) {
|
||||
if (ctx->ifc_flags & IFC_SC_ALLOCATED)
|
||||
free(sc, M_IFLIB);
|
||||
free(ctx, M_IFLIB);
|
||||
device_printf(dev, "iflib_register failed %d\n", err);
|
||||
return (err);
|
||||
goto fail_ctx_free;
|
||||
}
|
||||
iflib_add_device_sysctl_pre(ctx);
|
||||
|
||||
@ -4382,9 +4384,8 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct
|
||||
iflib_reset_qvalues(ctx);
|
||||
CTX_LOCK(ctx);
|
||||
if ((err = IFDI_ATTACH_PRE(ctx)) != 0) {
|
||||
CTX_UNLOCK(ctx);
|
||||
device_printf(dev, "IFDI_ATTACH_PRE failed %d\n", err);
|
||||
return (err);
|
||||
goto fail_unlock;
|
||||
}
|
||||
_iflib_pre_assert(scctx);
|
||||
ctx->ifc_txrx = *scctx->isc_txrx;
|
||||
@ -4414,7 +4415,7 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct
|
||||
/* round down instead? */
|
||||
device_printf(dev, "# rx descriptors must be a power of 2\n");
|
||||
err = EINVAL;
|
||||
goto fail;
|
||||
goto fail_iflib_detach;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < sctx->isc_ntxqs; i++) {
|
||||
@ -4422,7 +4423,7 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct
|
||||
device_printf(dev,
|
||||
"# tx descriptors must be a power of 2");
|
||||
err = EINVAL;
|
||||
goto fail;
|
||||
goto fail_iflib_detach;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4492,7 +4493,7 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct
|
||||
/* Get memory for the station queues */
|
||||
if ((err = iflib_queues_alloc(ctx))) {
|
||||
device_printf(dev, "Unable to allocate queue memory\n");
|
||||
goto fail;
|
||||
goto fail_intr_free;
|
||||
}
|
||||
|
||||
if ((err = iflib_qset_structures_setup(ctx)))
|
||||
@ -4511,7 +4512,7 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct
|
||||
IFDI_INTR_DISABLE(ctx);
|
||||
if (msix > 1 && (err = IFDI_MSIX_INTR_ASSIGN(ctx, msix)) != 0) {
|
||||
device_printf(dev, "IFDI_MSIX_INTR_ASSIGN failed %d\n", err);
|
||||
goto fail_intr_free;
|
||||
goto fail_queues;
|
||||
}
|
||||
if (msix <= 1) {
|
||||
rid = 0;
|
||||
@ -4521,7 +4522,7 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct
|
||||
}
|
||||
if ((err = iflib_legacy_setup(ctx, ctx->isc_legacy_intr, ctx->ifc_softc, &rid, "irq0")) != 0) {
|
||||
device_printf(dev, "iflib_legacy_setup failed %d\n", err);
|
||||
goto fail_intr_free;
|
||||
goto fail_queues;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4557,14 +4558,18 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct
|
||||
fail_detach:
|
||||
ether_ifdetach(ctx->ifc_ifp);
|
||||
fail_intr_free:
|
||||
iflib_free_intr_mem(ctx);
|
||||
fail_queues:
|
||||
iflib_tx_structures_free(ctx);
|
||||
iflib_rx_structures_free(ctx);
|
||||
fail:
|
||||
iflib_free_intr_mem(ctx);
|
||||
fail_iflib_detach:
|
||||
IFDI_DETACH(ctx);
|
||||
fail_unlock:
|
||||
CTX_UNLOCK(ctx);
|
||||
|
||||
fail_ctx_free:
|
||||
if (ctx->ifc_flags & IFC_SC_ALLOCATED)
|
||||
free(ctx->ifc_softc, M_IFLIB);
|
||||
free(ctx, M_IFLIB);
|
||||
return (err);
|
||||
}
|
||||
|
||||
@ -4593,9 +4598,7 @@ iflib_pseudo_register(device_t dev, if_shared_ctx_t sctx, if_ctx_t *ctxp,
|
||||
|
||||
if ((err = iflib_register(ctx)) != 0) {
|
||||
device_printf(dev, "%s: iflib_register failed %d\n", __func__, err);
|
||||
free(sc, M_IFLIB);
|
||||
free(ctx, M_IFLIB);
|
||||
return (err);
|
||||
goto fail_ctx_free;
|
||||
}
|
||||
iflib_add_device_sysctl_pre(ctx);
|
||||
|
||||
@ -4609,14 +4612,14 @@ iflib_pseudo_register(device_t dev, if_shared_ctx_t sctx, if_ctx_t *ctxp,
|
||||
|
||||
if ((err = IFDI_ATTACH_PRE(ctx)) != 0) {
|
||||
device_printf(dev, "IFDI_ATTACH_PRE failed %d\n", err);
|
||||
return (err);
|
||||
goto fail_ctx_free;
|
||||
}
|
||||
if (sctx->isc_flags & IFLIB_GEN_MAC)
|
||||
iflib_gen_mac(ctx);
|
||||
if ((err = IFDI_CLONEATTACH(ctx, clctx->cc_ifc, clctx->cc_name,
|
||||
clctx->cc_params)) != 0) {
|
||||
device_printf(dev, "IFDI_CLONEATTACH failed %d\n", err);
|
||||
return (err);
|
||||
goto fail_ctx_free;
|
||||
}
|
||||
ifmedia_add(&ctx->ifc_media, IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL);
|
||||
ifmedia_add(&ctx->ifc_media, IFM_ETHER | IFM_AUTO, 0, NULL);
|
||||
@ -4674,7 +4677,7 @@ iflib_pseudo_register(device_t dev, if_shared_ctx_t sctx, if_ctx_t *ctxp,
|
||||
/* round down instead? */
|
||||
device_printf(dev, "# rx descriptors must be a power of 2\n");
|
||||
err = EINVAL;
|
||||
goto fail;
|
||||
goto fail_iflib_detach;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < sctx->isc_ntxqs; i++) {
|
||||
@ -4682,7 +4685,7 @@ iflib_pseudo_register(device_t dev, if_shared_ctx_t sctx, if_ctx_t *ctxp,
|
||||
device_printf(dev,
|
||||
"# tx descriptors must be a power of 2");
|
||||
err = EINVAL;
|
||||
goto fail;
|
||||
goto fail_iflib_detach;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4728,7 +4731,7 @@ iflib_pseudo_register(device_t dev, if_shared_ctx_t sctx, if_ctx_t *ctxp,
|
||||
/* Get memory for the station queues */
|
||||
if ((err = iflib_queues_alloc(ctx))) {
|
||||
device_printf(dev, "Unable to allocate queue memory\n");
|
||||
goto fail;
|
||||
goto fail_iflib_detach;
|
||||
}
|
||||
|
||||
if ((err = iflib_qset_structures_setup(ctx))) {
|
||||
@ -4768,8 +4771,11 @@ iflib_pseudo_register(device_t dev, if_shared_ctx_t sctx, if_ctx_t *ctxp,
|
||||
fail_queues:
|
||||
iflib_tx_structures_free(ctx);
|
||||
iflib_rx_structures_free(ctx);
|
||||
fail:
|
||||
fail_iflib_detach:
|
||||
IFDI_DETACH(ctx);
|
||||
fail_ctx_free:
|
||||
free(ctx->ifc_softc, M_IFLIB);
|
||||
free(ctx, M_IFLIB);
|
||||
return (err);
|
||||
}
|
||||
|
||||
|
@ -69,6 +69,9 @@ typedef struct if_rxd_frag {
|
||||
uint16_t irf_len;
|
||||
} *if_rxd_frag_t;
|
||||
|
||||
/* bnxt supports 64 with hardware LRO enabled */
|
||||
#define IFLIB_MAX_RX_SEGS 64
|
||||
|
||||
typedef struct if_rxd_info {
|
||||
/* set by iflib */
|
||||
uint16_t iri_qsidx; /* qset index */
|
||||
@ -428,6 +431,7 @@ void iflib_iov_intr_deferred(if_ctx_t ctx);
|
||||
void iflib_link_state_change(if_ctx_t ctx, int linkstate, uint64_t baudrate);
|
||||
|
||||
int iflib_dma_alloc(if_ctx_t ctx, int size, iflib_dma_info_t dma, int mapflags);
|
||||
int iflib_dma_alloc_align(if_ctx_t ctx, int size, int align, iflib_dma_info_t dma, int mapflags);
|
||||
void iflib_dma_free(iflib_dma_info_t dma);
|
||||
|
||||
int iflib_dma_alloc_multi(if_ctx_t ctx, int *sizes, iflib_dma_info_t *dmalist, int mapflags, int count);
|
||||
|
@ -405,8 +405,10 @@ ieee80211_ifdetach(struct ieee80211com *ic)
|
||||
* The VAP is responsible for setting and clearing
|
||||
* the VIMAGE context.
|
||||
*/
|
||||
while ((vap = TAILQ_FIRST(&ic->ic_vaps)) != NULL)
|
||||
while ((vap = TAILQ_FIRST(&ic->ic_vaps)) != NULL) {
|
||||
ieee80211_com_vdetach(vap);
|
||||
ieee80211_vap_destroy(vap);
|
||||
}
|
||||
ieee80211_waitfor_parent(ic);
|
||||
|
||||
ieee80211_sysctl_detach(ic);
|
||||
|
@ -951,9 +951,11 @@ enum {
|
||||
IEEE80211_ELEMID_ERP = 42,
|
||||
IEEE80211_ELEMID_HTCAP = 45,
|
||||
IEEE80211_ELEMID_QOS = 46,
|
||||
IEEE80211_ELEMID_RESERVED_47 = 47,
|
||||
IEEE80211_ELEMID_RSN = 48,
|
||||
IEEE80211_ELEMID_XRATES = 50,
|
||||
IEEE80211_ELEMID_APCHANREP = 51,
|
||||
IEEE80211_ELEMID_MOBILITY_DOMAIN = 54,
|
||||
IEEE80211_ELEMID_HTINFO = 61,
|
||||
IEEE80211_ELEMID_SECCHAN_OFFSET = 62,
|
||||
IEEE80211_ELEMID_RRM_ENACAPS = 70,
|
||||
|
@ -307,6 +307,55 @@ ieee80211_sysctl_vdetach(struct ieee80211vap *vap)
|
||||
}
|
||||
}
|
||||
|
||||
#define MS(_v, _f) (((_v) & _f##_M) >> _f##_S)
|
||||
int
|
||||
ieee80211_com_vincref(struct ieee80211vap *vap)
|
||||
{
|
||||
uint32_t ostate;
|
||||
|
||||
ostate = atomic_fetchadd_32(&vap->iv_com_state, IEEE80211_COM_REF_ADD);
|
||||
|
||||
if (ostate & IEEE80211_COM_DETACHED) {
|
||||
atomic_subtract_32(&vap->iv_com_state, IEEE80211_COM_REF_ADD);
|
||||
return (ENETDOWN);
|
||||
}
|
||||
|
||||
if (MS(ostate, IEEE80211_COM_REF) == IEEE80211_COM_REF_MAX) {
|
||||
atomic_subtract_32(&vap->iv_com_state, IEEE80211_COM_REF_ADD);
|
||||
return (EOVERFLOW);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
ieee80211_com_vdecref(struct ieee80211vap *vap)
|
||||
{
|
||||
uint32_t ostate;
|
||||
|
||||
ostate = atomic_fetchadd_32(&vap->iv_com_state, -IEEE80211_COM_REF_ADD);
|
||||
|
||||
KASSERT(MS(ostate, IEEE80211_COM_REF) != 0,
|
||||
("com reference counter underflow"));
|
||||
|
||||
(void) ostate;
|
||||
}
|
||||
|
||||
void
|
||||
ieee80211_com_vdetach(struct ieee80211vap *vap)
|
||||
{
|
||||
int sleep_time;
|
||||
|
||||
sleep_time = msecs_to_ticks(250);
|
||||
if (sleep_time == 0)
|
||||
sleep_time = 1;
|
||||
|
||||
atomic_set_32(&vap->iv_com_state, IEEE80211_COM_DETACHED);
|
||||
while (MS(atomic_load_32(&vap->iv_com_state), IEEE80211_COM_REF) != 0)
|
||||
pause("comref", sleep_time);
|
||||
}
|
||||
#undef MS
|
||||
|
||||
int
|
||||
ieee80211_node_dectestref(struct ieee80211_node *ni)
|
||||
{
|
||||
|
@ -224,6 +224,11 @@ typedef struct mtx ieee80211_rt_lock_t;
|
||||
*/
|
||||
#include <machine/atomic.h>
|
||||
|
||||
struct ieee80211vap;
|
||||
int ieee80211_com_vincref(struct ieee80211vap *);
|
||||
void ieee80211_com_vdecref(struct ieee80211vap *);
|
||||
void ieee80211_com_vdetach(struct ieee80211vap *);
|
||||
|
||||
#define ieee80211_node_initref(_ni) \
|
||||
do { ((_ni)->ni_refcnt = 1); } while (0)
|
||||
#define ieee80211_node_incref(_ni) \
|
||||
@ -235,7 +240,6 @@ int ieee80211_node_dectestref(struct ieee80211_node *ni);
|
||||
#define ieee80211_node_refcnt(_ni) (_ni)->ni_refcnt
|
||||
|
||||
struct ifqueue;
|
||||
struct ieee80211vap;
|
||||
void ieee80211_drain_ifq(struct ifqueue *);
|
||||
void ieee80211_flush_ifq(struct ifqueue *, struct ieee80211vap *);
|
||||
|
||||
|
@ -3480,10 +3480,14 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
{
|
||||
struct ieee80211vap *vap = ifp->if_softc;
|
||||
struct ieee80211com *ic = vap->iv_ic;
|
||||
int error = 0, wait = 0;
|
||||
int error = 0, wait = 0, ic_used;
|
||||
struct ifreq *ifr;
|
||||
struct ifaddr *ifa; /* XXX */
|
||||
|
||||
ic_used = (cmd != SIOCSIFMTU && cmd != SIOCG80211STATS);
|
||||
if (ic_used && (error = ieee80211_com_vincref(vap)) != 0)
|
||||
return (error);
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCSIFFLAGS:
|
||||
IEEE80211_LOCK(ic);
|
||||
@ -3620,5 +3624,9 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
error = ether_ioctl(ifp, cmd, data);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ic_used)
|
||||
ieee80211_com_vdecref(vap);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
@ -400,6 +400,7 @@ struct ieee80211vap {
|
||||
uint32_t iv_caps; /* capabilities */
|
||||
uint32_t iv_htcaps; /* HT capabilities */
|
||||
uint32_t iv_htextcaps; /* HT extended capabilities */
|
||||
uint32_t iv_com_state; /* com usage / detached flag */
|
||||
enum ieee80211_opmode iv_opmode; /* operation mode */
|
||||
enum ieee80211_state iv_state; /* state machine state */
|
||||
enum ieee80211_state iv_nstate; /* pending state */
|
||||
@ -685,6 +686,12 @@ MALLOC_DECLARE(M_80211_VAP);
|
||||
#define IEEE80211_VFHT_BITS \
|
||||
"\20\1VHT\2VHT40\3VHT80\4VHT80P80\5VHT160"
|
||||
|
||||
#define IEEE80211_COM_DETACHED 0x00000001 /* ieee80211_ifdetach called */
|
||||
#define IEEE80211_COM_REF_ADD 0x00000002 /* add / remove reference */
|
||||
#define IEEE80211_COM_REF_M 0xfffffffe /* reference counter bits */
|
||||
#define IEEE80211_COM_REF_S 1
|
||||
#define IEEE80211_COM_REF_MAX (IEEE80211_COM_REF_M >> IEEE80211_COM_REF_S)
|
||||
|
||||
int ic_printf(struct ieee80211com *, const char *, ...) __printflike(2, 3);
|
||||
void ieee80211_ifattach(struct ieee80211com *);
|
||||
void ieee80211_ifdetach(struct ieee80211com *);
|
||||
|
149
sys/net80211/ieee80211_wps.h
Normal file
149
sys/net80211/ieee80211_wps.h
Normal file
@ -0,0 +1,149 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
*
|
||||
* Copyright (c) 2017 J.R. Oldroyd, Open Advisors Limited
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef _NET80211_IEEE80211_WPS_H_
|
||||
#define _NET80211_IEEE80211_WPS_H_
|
||||
|
||||
/*
|
||||
* 802.11 WPS implementation definitions.
|
||||
*/
|
||||
|
||||
#define IEEE80211_WPS_ATTR_AP_CHANNEL 0x1001
|
||||
#define IEEE80211_WPS_ATTR_ASSOC_STATE 0x1002
|
||||
#define IEEE80211_WPS_ATTR_AUTH_TYPE 0x1003
|
||||
#define IEEE80211_WPS_ATTR_AUTH_TYPE_FLAGS 0x1004
|
||||
#define IEEE80211_WPS_ATTR_AUTHENTICATOR 0x1005
|
||||
#define IEEE80211_WPS_ATTR_CONFIG_METHODS 0x1008
|
||||
#define IEEE80211_WPS_ATTR_CONFIG_ERROR 0x1009
|
||||
#define IEEE80211_WPS_ATTR_CONFIRM_URL4 0x100a
|
||||
#define IEEE80211_WPS_ATTR_CONFIRM_URL6 0x100b
|
||||
#define IEEE80211_WPS_ATTR_CONN_TYPE 0x100c
|
||||
#define IEEE80211_WPS_ATTR_CONN_TYPE_FLAGS 0x100d
|
||||
#define IEEE80211_WPS_ATTR_CRED 0x100e
|
||||
#define IEEE80211_WPS_ATTR_ENCR_TYPE 0x100f
|
||||
#define IEEE80211_WPS_ATTR_ENCR_TYPE_FLAGS 0x1010
|
||||
#define IEEE80211_WPS_ATTR_DEV_NAME 0x1011
|
||||
#define IEEE80211_WPS_ATTR_DEV_PASSWORD_ID 0x1012
|
||||
#define IEEE80211_WPS_ATTR_E_HASH1 0x1014
|
||||
#define IEEE80211_WPS_ATTR_E_HASH2 0x1015
|
||||
#define IEEE80211_WPS_ATTR_E_SNONCE1 0x1016
|
||||
#define IEEE80211_WPS_ATTR_E_SNONCE2 0x1017
|
||||
#define IEEE80211_WPS_ATTR_ENCR_SETTINGS 0x1018
|
||||
#define IEEE80211_WPS_ATTR_ENROLLEE_NONCE 0x101a
|
||||
#define IEEE80211_WPS_ATTR_FEATURE_ID 0x101b
|
||||
#define IEEE80211_WPS_ATTR_IDENTITY 0x101c
|
||||
#define IEEE80211_WPS_ATTR_IDENTITY_PROOF 0x101d
|
||||
#define IEEE80211_WPS_ATTR_KEY_WRAP_AUTH 0x101e
|
||||
#define IEEE80211_WPS_ATTR_KEY_ID 0x101f
|
||||
#define IEEE80211_WPS_ATTR_MAC_ADDR 0x1020
|
||||
#define IEEE80211_WPS_ATTR_MANUFACTURER 0x1021
|
||||
#define IEEE80211_WPS_ATTR_MSG_TYPE 0x1022
|
||||
#define IEEE80211_WPS_ATTR_MODEL_NAME 0x1023
|
||||
#define IEEE80211_WPS_ATTR_MODEL_NUMBER 0x1024
|
||||
#define IEEE80211_WPS_ATTR_NETWORK_INDEX 0x1026
|
||||
#define IEEE80211_WPS_ATTR_NETWORK_KEY 0x1027
|
||||
#define IEEE80211_WPS_ATTR_NETWORK_KEY_INDEX 0x1028
|
||||
#define IEEE80211_WPS_ATTR_NEW_DEVICE_NAME 0x1029
|
||||
#define IEEE80211_WPS_ATTR_NEW_PASSWORD 0x102a
|
||||
#define IEEE80211_WPS_ATTR_OOB_DEVICE_PASSWORD 0x102c
|
||||
#define IEEE80211_WPS_ATTR_OS_VERSION 0x102d
|
||||
#define IEEE80211_WPS_ATTR_POWER_LEVEL 0x102f
|
||||
#define IEEE80211_WPS_ATTR_PSK_CURRENT 0x1030
|
||||
#define IEEE80211_WPS_ATTR_PSK_MAX 0x1031
|
||||
#define IEEE80211_WPS_ATTR_PUBLIC_KEY 0x1032
|
||||
#define IEEE80211_WPS_ATTR_RADIO_ENABLE 0x1033
|
||||
#define IEEE80211_WPS_ATTR_REBOOT 0x1034
|
||||
#define IEEE80211_WPS_ATTR_REGISTRAR_CURRENT 0x1035
|
||||
#define IEEE80211_WPS_ATTR_REGISTRAR_ESTBLSHD 0x1036
|
||||
#define IEEE80211_WPS_ATTR_REGISTRAR_LIST 0x1037
|
||||
#define IEEE80211_WPS_ATTR_REGISTRAR_MAX 0x1038
|
||||
#define IEEE80211_WPS_ATTR_REGISTRAR_NONCE 0x1039
|
||||
#define IEEE80211_WPS_ATTR_REQUEST_TYPE 0x103a
|
||||
#define IEEE80211_WPS_ATTR_RESPONSE_TYPE 0x103b
|
||||
#define IEEE80211_WPS_ATTR_RF_BANDS 0x103c
|
||||
#define IEEE80211_WPS_ATTR_R_HASH1 0x103d
|
||||
#define IEEE80211_WPS_ATTR_R_HASH2 0x103e
|
||||
#define IEEE80211_WPS_ATTR_R_SNONCE1 0x103f
|
||||
#define IEEE80211_WPS_ATTR_R_SNONCE2 0x1040
|
||||
#define IEEE80211_WPS_ATTR_SELECTED_REGISTRAR 0x1041
|
||||
#define IEEE80211_WPS_ATTR_SERIAL_NUMBER 0x1042
|
||||
#define IEEE80211_WPS_ATTR_WPS_STATE 0x1044
|
||||
#define IEEE80211_WPS_ATTR_SSID 0x1045
|
||||
#define IEEE80211_WPS_ATTR_TOTAL_NETWORKS 0x1046
|
||||
#define IEEE80211_WPS_ATTR_UUID_E 0x1047
|
||||
#define IEEE80211_WPS_ATTR_UUID_R 0x1048
|
||||
#define IEEE80211_WPS_ATTR_VENDOR_EXT 0x1049
|
||||
#define IEEE80211_WPS_ATTR_VERSION 0x104a
|
||||
#define IEEE80211_WPS_ATTR_X509_CERT_REQ 0x104b
|
||||
#define IEEE80211_WPS_ATTR_X509_CERT 0x104c
|
||||
#define IEEE80211_WPS_ATTR_EAP_IDENTITY 0x104d
|
||||
#define IEEE80211_WPS_ATTR_MSG_COUNTER 0x104e
|
||||
#define IEEE80211_WPS_ATTR_PUBKEY_HASH 0x104f
|
||||
#define IEEE80211_WPS_ATTR_REKEY_KEY 0x1050
|
||||
#define IEEE80211_WPS_ATTR_KEY_LIFETIME 0x1051
|
||||
#define IEEE80211_WPS_ATTR_PERMITTED_CONFIG_METHODS 0x1052
|
||||
#define IEEE80211_WPS_ATTR_SELECTED_REGISTRAR_CONFIG_METHODS 0x1053
|
||||
#define IEEE80211_WPS_ATTR_PRIMARY_DEV_TYPE 0x1054
|
||||
#define IEEE80211_WPS_ATTR_SECONDARY_DEV_TYPE_LIST 0x1055
|
||||
#define IEEE80211_WPS_ATTR_PORTABLE_DEV 0x1056
|
||||
#define IEEE80211_WPS_ATTR_AP_SETUP_LOCKED 0x1057
|
||||
#define IEEE80211_WPS_ATTR_APPLICATION_EXT 0x1058
|
||||
#define IEEE80211_WPS_ATTR_EAP_TYPE 0x1059
|
||||
#define IEEE80211_WPS_ATTR_IV 0x1060
|
||||
#define IEEE80211_WPS_ATTR_KEY_PROVIDED_AUTO 0x1061
|
||||
#define IEEE80211_WPS_ATTR_802_1X_ENABLED 0x1062
|
||||
#define IEEE80211_WPS_ATTR_AP_SESSION_KEY 0x1063
|
||||
#define IEEE80211_WPS_ATTR_WEP_TRANSMIT_KEY 0x1064
|
||||
#define IEEE80211_WPS_ATTR_REQUESTED_DEV_TYPE 0x106a
|
||||
#define IEEE80211_WPS_ATTR_EXTENSIBILITY_TEST 0x10fa /* _NOT_ defined in the spec */
|
||||
|
||||
/* RF bands bitmask */
|
||||
#define IEEE80211_WPS_RF_BAND_24GHZ 0x01
|
||||
#define IEEE80211_WPS_RF_BAND_50GHZ 0x02
|
||||
#define IEEE80211_WPS_RF_BAND_600GHZ 0x04
|
||||
|
||||
/* Config methods bitmask */
|
||||
#define IEEE80211_WPS_CONFIG_USBA 0x0001
|
||||
#define IEEE80211_WPS_CONFIG_ETHERNET 0x0002
|
||||
#define IEEE80211_WPS_CONFIG_LABEL 0x0004
|
||||
#define IEEE80211_WPS_CONFIG_DISPLAY 0x0008
|
||||
#define IEEE80211_WPS_CONFIG_EXT_NFC_TOKEN 0x0010
|
||||
#define IEEE80211_WPS_CONFIG_INT_NFC_TOKEN 0x0020
|
||||
#define IEEE80211_WPS_CONFIG_NFC_INTERFACE 0x0040
|
||||
#define IEEE80211_WPS_CONFIG_PUSHBUTTON 0x0080
|
||||
#define IEEE80211_WPS_CONFIG_KEYPAD 0x0100
|
||||
#define IEEE80211_WPS_CONFIG_VIRT_PUSHBUTTON 0x0200
|
||||
#define IEEE80211_WPS_CONFIG_PHY_PUSHBUTTON 0x0400
|
||||
#define IEEE80211_WPS_CONFIG_P2PS 0x1000
|
||||
#define IEEE80211_WPS_CONFIG_VIRT_DISPLAY 0x2000
|
||||
#define IEEE80211_WPS_CONFIG_PHY_DISPLAY 0x4000
|
||||
|
||||
/* Wi-Fi Protected Setup state */
|
||||
#define IEEE80211_WPS_STATE_NOT_CONFIGURED 0x01
|
||||
#define IEEE80211_WPS_STATE_CONFIGURED 0x02
|
||||
#endif /* _NET80211_IEEE80211_WPS_H_ */
|
@ -3577,14 +3577,18 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
struct pf_src_node *n, *p, *pstore;
|
||||
uint32_t i, nr = 0;
|
||||
|
||||
for (i = 0, sh = V_pf_srchash; i <= pf_srchashmask;
|
||||
i++, sh++) {
|
||||
PF_HASHROW_LOCK(sh);
|
||||
LIST_FOREACH(n, &sh->nodes, entry)
|
||||
nr++;
|
||||
PF_HASHROW_UNLOCK(sh);
|
||||
}
|
||||
|
||||
psn->psn_len = min(psn->psn_len,
|
||||
sizeof(struct pf_src_node) * nr);
|
||||
|
||||
if (psn->psn_len == 0) {
|
||||
for (i = 0, sh = V_pf_srchash; i <= pf_srchashmask;
|
||||
i++, sh++) {
|
||||
PF_HASHROW_LOCK(sh);
|
||||
LIST_FOREACH(n, &sh->nodes, entry)
|
||||
nr++;
|
||||
PF_HASHROW_UNLOCK(sh);
|
||||
}
|
||||
psn->psn_len = sizeof(struct pf_src_node) * nr;
|
||||
break;
|
||||
}
|
||||
|
@ -155,7 +155,8 @@
|
||||
#define SATP_MODE_SV39 (8ULL << SATP_MODE_S)
|
||||
#define SATP_MODE_SV48 (9ULL << SATP_MODE_S)
|
||||
|
||||
#define XLEN 8
|
||||
#define XLEN __riscv_xlen
|
||||
#define XLEN_BYTES (XLEN / 8)
|
||||
#define INSN_SIZE 4
|
||||
#define INSN_C_SIZE 2
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2015-2018 Ruslan Bukin <br@bsdpad.com>
|
||||
* Copyright (c) 2019 Mitchell Horne
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by SRI International and the
|
||||
@ -51,61 +52,95 @@ copyio_fault_nopcb:
|
||||
ret
|
||||
END(copyio_fault)
|
||||
|
||||
/*
|
||||
* copycommon - common copy routine
|
||||
*
|
||||
* a0 - Source address
|
||||
* a1 - Destination address
|
||||
* a2 - Size of copy
|
||||
*/
|
||||
.macro copycommon
|
||||
la a6, copyio_fault /* Get the handler address */
|
||||
SET_FAULT_HANDLER(a6, a7) /* Set the handler */
|
||||
ENTER_USER_ACCESS(a7)
|
||||
|
||||
li t2, XLEN_BYTES
|
||||
blt a2, t2, 3f /* Byte-copy if len < XLEN_BYTES */
|
||||
|
||||
/*
|
||||
* Compare lower bits of src and dest.
|
||||
* If they are aligned with each other, we can do word copy.
|
||||
*/
|
||||
andi t0, a0, (XLEN_BYTES-1) /* Low bits of src */
|
||||
andi t1, a1, (XLEN_BYTES-1) /* Low bits of dest */
|
||||
bne t0, t1, 3f /* Misaligned. Go to byte copy */
|
||||
beqz t0, 2f /* Already word-aligned, skip ahead */
|
||||
|
||||
/* Byte copy until the first word-aligned address */
|
||||
1: lb a4, 0(a0) /* Load byte from src */
|
||||
addi a0, a0, 1
|
||||
sb a4, 0(a1) /* Store byte in dest */
|
||||
addi a1, a1, 1
|
||||
addi a2, a2, -1 /* len-- */
|
||||
andi t0, a0, (XLEN_BYTES-1)
|
||||
bnez t0, 1b
|
||||
|
||||
/* Copy words */
|
||||
2: ld a4, 0(a0) /* Load word from src */
|
||||
addi a0, a0, XLEN_BYTES
|
||||
sd a4, 0(a1) /* Store word in dest */
|
||||
addi a1, a1, XLEN_BYTES
|
||||
addi a2, a2, -XLEN_BYTES /* len -= XLEN_BYTES */
|
||||
bgeu a2, t2, 2b /* Again if len >= XLEN_BYTES */
|
||||
|
||||
/* Check if we're finished */
|
||||
beqz a2, 4f
|
||||
|
||||
/* Copy any remaining bytes */
|
||||
3: lb a4, 0(a0) /* Load byte from src */
|
||||
addi a0, a0, 1
|
||||
sb a4, 0(a1) /* Store byte in dest */
|
||||
addi a1, a1, 1
|
||||
addi a2, a2, -1 /* len-- */
|
||||
bnez a2, 3b
|
||||
|
||||
4: EXIT_USER_ACCESS(a7)
|
||||
SET_FAULT_HANDLER(x0, a7) /* Clear the handler */
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Copies from a kernel to user address
|
||||
*
|
||||
* int copyout(const void *kaddr, void *udaddr, size_t len)
|
||||
*/
|
||||
ENTRY(copyout)
|
||||
beqz a2, 2f /* If len == 0 then skip loop */
|
||||
beqz a2, copyout_end /* If len == 0 then skip loop */
|
||||
add a3, a1, a2
|
||||
li a4, VM_MAXUSER_ADDRESS
|
||||
bgt a3, a4, copyio_fault_nopcb
|
||||
|
||||
la a6, copyio_fault /* Get the handler address */
|
||||
SET_FAULT_HANDLER(a6, a7) /* Set the handler */
|
||||
ENTER_USER_ACCESS(a7)
|
||||
copycommon
|
||||
|
||||
1: lb a4, 0(a0) /* Load from kaddr */
|
||||
addi a0, a0, 1
|
||||
sb a4, 0(a1) /* Store in uaddr */
|
||||
addi a1, a1, 1
|
||||
addi a2, a2, -1 /* len-- */
|
||||
bnez a2, 1b
|
||||
|
||||
EXIT_USER_ACCESS(a7)
|
||||
SET_FAULT_HANDLER(x0, a7) /* Clear the handler */
|
||||
|
||||
2: li a0, 0 /* return 0 */
|
||||
copyout_end:
|
||||
li a0, 0 /* return 0 */
|
||||
ret
|
||||
END(copyout)
|
||||
|
||||
/*
|
||||
* Copies from a user to kernel address
|
||||
*
|
||||
* int copyin(const void *uaddr, void *kdaddr, size_t len)
|
||||
* int copyin(const void *uaddr, void *kaddr, size_t len)
|
||||
*/
|
||||
ENTRY(copyin)
|
||||
beqz a2, 2f /* If len == 0 then skip loop */
|
||||
beqz a2, copyin_end /* If len == 0 then skip loop */
|
||||
add a3, a0, a2
|
||||
li a4, VM_MAXUSER_ADDRESS
|
||||
bgt a3, a4, copyio_fault_nopcb
|
||||
|
||||
la a6, copyio_fault /* Get the handler address */
|
||||
SET_FAULT_HANDLER(a6, a7) /* Set the handler */
|
||||
ENTER_USER_ACCESS(a7)
|
||||
copycommon
|
||||
|
||||
1: lb a4, 0(a0) /* Load from uaddr */
|
||||
addi a0, a0, 1
|
||||
sb a4, 0(a1) /* Store in kaddr */
|
||||
addi a1, a1, 1
|
||||
addi a2, a2, -1 /* len-- */
|
||||
bnez a2, 1b
|
||||
|
||||
EXIT_USER_ACCESS(a7)
|
||||
SET_FAULT_HANDLER(x0, a7) /* Clear the handler */
|
||||
|
||||
2: li a0, 0 /* return 0 */
|
||||
copyin_end:
|
||||
li a0, 0 /* return 0 */
|
||||
ret
|
||||
END(copyin)
|
||||
|
||||
|
@ -217,7 +217,6 @@ device xl # 3Com 3c90x (``Boomerang'', ``Cyclone'')
|
||||
# Wireless NIC cards
|
||||
device wlan # 802.11 support
|
||||
options IEEE80211_DEBUG # enable debug msgs
|
||||
options IEEE80211_AMPDU_AGE # age frames in AMPDU reorder q's
|
||||
options IEEE80211_SUPPORT_MESH # enable 802.11s D3.0 support
|
||||
device wlan_wep # 802.11 WEP support
|
||||
device wlan_ccmp # 802.11 CCMP support
|
||||
|
@ -60,7 +60,7 @@
|
||||
* in the range 5 to 9.
|
||||
*/
|
||||
#undef __FreeBSD_version
|
||||
#define __FreeBSD_version 1300008 /* Master, propagated to newvers */
|
||||
#define __FreeBSD_version 1300009 /* Master, propagated to newvers */
|
||||
|
||||
/*
|
||||
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
|
||||
|
@ -54,7 +54,6 @@ void rm_init_flags(struct rmlock *rm, const char *name, int opts);
|
||||
void rm_destroy(struct rmlock *rm);
|
||||
int rm_wowned(const struct rmlock *rm);
|
||||
void rm_sysinit(void *arg);
|
||||
void rm_sysinit_flags(void *arg);
|
||||
|
||||
void _rm_wlock_debug(struct rmlock *rm, const char *file, int line);
|
||||
void _rm_wunlock_debug(struct rmlock *rm, const char *file, int line);
|
||||
|
@ -130,7 +130,6 @@
|
||||
void _rw_init_flags(volatile uintptr_t *c, const char *name, int opts);
|
||||
void _rw_destroy(volatile uintptr_t *c);
|
||||
void rw_sysinit(void *arg);
|
||||
void rw_sysinit_flags(void *arg);
|
||||
int _rw_wowned(const volatile uintptr_t *c);
|
||||
void _rw_wlock_cookie(volatile uintptr_t *c, const char *file, int line);
|
||||
int __rw_try_wlock_int(struct rwlock *rw LOCK_FILE_LINE_ARG_DEF);
|
||||
|
@ -753,6 +753,38 @@ ATF_TC_CLEANUP(commit, tc)
|
||||
COMMON_CLEANUP();
|
||||
}
|
||||
|
||||
ATF_TC_WITH_CLEANUP(getsrcnodes);
|
||||
ATF_TC_HEAD(getsrcnodes, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "require.user", "root");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(getsrcnodes, tc)
|
||||
{
|
||||
struct pfioc_src_nodes psn;
|
||||
|
||||
COMMON_HEAD();
|
||||
|
||||
bzero(&psn, sizeof(psn));
|
||||
|
||||
psn.psn_len = -1;
|
||||
if (ioctl(dev, DIOCGETSRCNODES, &psn) != 0)
|
||||
atf_tc_fail("request with size -1 failed");
|
||||
|
||||
psn.psn_len = 1 << 30;
|
||||
if (ioctl(dev, DIOCGETSRCNODES, &psn) != 0)
|
||||
atf_tc_fail("request with size << 30 failed");
|
||||
|
||||
psn.psn_len = 1 << 31;
|
||||
if (ioctl(dev, DIOCGETSRCNODES, &psn) != 0)
|
||||
atf_tc_fail("request with size << 30 failed");
|
||||
}
|
||||
|
||||
ATF_TC_CLEANUP(getsrcnodes, tc)
|
||||
{
|
||||
COMMON_CLEANUP();
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, addtables);
|
||||
@ -772,6 +804,7 @@ ATF_TP_ADD_TCS(tp)
|
||||
ATF_TP_ADD_TC(tp, cxbegin);
|
||||
ATF_TP_ADD_TC(tp, cxrollback);
|
||||
ATF_TP_ADD_TC(tp, commit);
|
||||
ATF_TP_ADD_TC(tp, getsrcnodes);
|
||||
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
@ -7465,6 +7465,8 @@ OLD_FILES+=usr/share/man/man8/pppctl.8.gz
|
||||
.endif
|
||||
|
||||
.if ${MK_PROFILE} == no
|
||||
OLD_FILES+=usr/lib/lib80211_p.a
|
||||
OLD_FILES+=usr/lib/libBlocksRuntime_p.a
|
||||
OLD_FILES+=usr/lib/libalias_cuseeme_p.a
|
||||
OLD_FILES+=usr/lib/libalias_dummy_p.a
|
||||
OLD_FILES+=usr/lib/libalias_ftp_p.a
|
||||
@ -7476,40 +7478,64 @@ OLD_FILES+=usr/lib/libalias_skinny_p.a
|
||||
OLD_FILES+=usr/lib/libalias_smedia_p.a
|
||||
OLD_FILES+=usr/lib/libarchive_p.a
|
||||
OLD_FILES+=usr/lib/libasn1_p.a
|
||||
OLD_FILES+=usr/lib/libauditd_p.a
|
||||
OLD_FILES+=usr/lib/libavl_p.a
|
||||
OLD_FILES+=usr/lib/libbe_p.a
|
||||
OLD_FILES+=usr/lib/libbegemot_p.a
|
||||
OLD_FILES+=usr/lib/libblacklist_p.a
|
||||
OLD_FILES+=usr/lib/libbluetooth_p.a
|
||||
OLD_FILES+=usr/lib/libbsdxml_p.a
|
||||
OLD_FILES+=usr/lib/libbsm_p.a
|
||||
OLD_FILES+=usr/lib/libbsnmp_p.a
|
||||
OLD_FILES+=usr/lib/libbz2_p.a
|
||||
OLD_FILES+=usr/lib/libc++_p.a
|
||||
OLD_FILES+=usr/lib/libc_p.a
|
||||
OLD_FILES+=usr/lib/libcalendar_p.a
|
||||
OLD_FILES+=usr/lib/libcam_p.a
|
||||
OLD_FILES+=usr/lib/libcom_err_p.a
|
||||
OLD_FILES+=usr/lib/libcompat_p.a
|
||||
OLD_FILES+=usr/lib/libcompiler_rt_p.a
|
||||
OLD_FILES+=usr/lib/libcrypt_p.a
|
||||
OLD_FILES+=usr/lib/libcrypto_p.a
|
||||
OLD_FILES+=usr/lib/libctf_p.a
|
||||
OLD_FILES+=usr/lib/libcurses_p.a
|
||||
OLD_FILES+=usr/lib/libcursesw_p.a
|
||||
OLD_FILES+=usr/lib/libcuse_p.a
|
||||
OLD_FILES+=usr/lib/libcxxrt_p.a
|
||||
OLD_FILES+=usr/lib/libdevctl_p.a
|
||||
OLD_FILES+=usr/lib/libdevinfo_p.a
|
||||
OLD_FILES+=usr/lib/libdevstat_p.a
|
||||
OLD_FILES+=usr/lib/libdialog_p.a
|
||||
OLD_FILES+=usr/lib/libdl_p.a
|
||||
OLD_FILES+=usr/lib/libdpv_p.a
|
||||
OLD_FILES+=usr/lib/libdtrace_p.a
|
||||
OLD_FILES+=usr/lib/libdwarf_p.a
|
||||
OLD_FILES+=usr/lib/libedit_p.a
|
||||
OLD_FILES+=usr/lib/libefivar_p.a
|
||||
OLD_FILES+=usr/lib/libelf_p.a
|
||||
OLD_FILES+=usr/lib/libexecinfo_p.a
|
||||
OLD_FILES+=usr/lib/libfetch_p.a
|
||||
OLD_FILES+=usr/lib/libfigpar_p.a
|
||||
OLD_FILES+=usr/lib/libfl_p.a
|
||||
OLD_FILES+=usr/lib/libform_p.a
|
||||
OLD_FILES+=usr/lib/libformw_p.a
|
||||
OLD_FILES+=usr/lib/libgcc_eh_p.a
|
||||
OLD_FILES+=usr/lib/libgcc_p.a
|
||||
OLD_FILES+=usr/lib/libgeom_p.a
|
||||
OLD_FILES+=usr/lib/libgnuregex_p.a
|
||||
OLD_FILES+=usr/lib/libgpio_p.a
|
||||
OLD_FILES+=usr/lib/libgssapi_krb5_p.a
|
||||
OLD_FILES+=usr/lib/libgssapi_ntlm_p.a
|
||||
OLD_FILES+=usr/lib/libgssapi_p.a
|
||||
OLD_FILES+=usr/lib/libgssapi_spnego_p.a
|
||||
OLD_FILES+=usr/lib/libhdb_p.a
|
||||
OLD_FILES+=usr/lib/libheimbase_p.a
|
||||
OLD_FILES+=usr/lib/libheimntlm_p.a
|
||||
OLD_FILES+=usr/lib/libheimsqlite_p.a
|
||||
OLD_FILES+=usr/lib/libhistory_p.a
|
||||
OLD_FILES+=usr/lib/libhx509_p.a
|
||||
OLD_FILES+=usr/lib/libipsec_p.a
|
||||
OLD_FILES+=usr/lib/libipt_p.a
|
||||
OLD_FILES+=usr/lib/libjail_p.a
|
||||
OLD_FILES+=usr/lib/libkadm5clnt_p.a
|
||||
OLD_FILES+=usr/lib/libkadm5srv_p.a
|
||||
@ -7520,6 +7546,7 @@ OLD_FILES+=usr/lib/libkrb5_p.a
|
||||
OLD_FILES+=usr/lib/libkvm_p.a
|
||||
OLD_FILES+=usr/lib/libl_p.a
|
||||
OLD_FILES+=usr/lib/libln_p.a
|
||||
OLD_FILES+=usr/lib/liblzma_p.a
|
||||
OLD_FILES+=usr/lib/libm_p.a
|
||||
OLD_FILES+=usr/lib/libmagic_p.a
|
||||
OLD_FILES+=usr/lib/libmd_p.a
|
||||
@ -7528,26 +7555,52 @@ OLD_FILES+=usr/lib/libmenu_p.a
|
||||
OLD_FILES+=usr/lib/libmenuw_p.a
|
||||
OLD_FILES+=usr/lib/libmilter_p.a
|
||||
OLD_FILES+=usr/lib/libmp_p.a
|
||||
OLD_FILES+=usr/lib/libmt_p.a
|
||||
OLD_FILES+=usr/lib/libncurses_p.a
|
||||
OLD_FILES+=usr/lib/libncursesw_p.a
|
||||
OLD_FILES+=usr/lib/libnetgraph_p.a
|
||||
OLD_FILES+=usr/lib/libngatm_p.a
|
||||
OLD_FILES+=usr/lib/libnv_p.a
|
||||
OLD_FILES+=usr/lib/libnvpair_p.a
|
||||
OLD_FILES+=usr/lib/libopencsd_p.a
|
||||
OLD_FILES+=usr/lib/libopie_p.a
|
||||
OLD_FILES+=usr/lib/libpanel_p.a
|
||||
OLD_FILES+=usr/lib/libpanelw_p.a
|
||||
OLD_FILES+=usr/lib/libpathconv_p.a
|
||||
OLD_FILES+=usr/lib/libpcap_p.a
|
||||
OLD_FILES+=usr/lib/libpjdlog_p.a
|
||||
OLD_FILES+=usr/lib/libpmc_p.a
|
||||
OLD_FILES+=usr/lib/libprivatebsdstat_p.a
|
||||
OLD_FILES+=usr/lib/libprivatedevdctl_p.a
|
||||
OLD_FILES+=usr/lib/libprivateevent_p.a
|
||||
OLD_FILES+=usr/lib/libprivateheimipcc_p.a
|
||||
OLD_FILES+=usr/lib/libprivateheimipcs_p.a
|
||||
OLD_FILES+=usr/lib/libprivateifconfig_p.a
|
||||
OLD_FILES+=usr/lib/libprivateldns_p.a
|
||||
OLD_FILES+=usr/lib/libprivatesqlite3_p.a
|
||||
OLD_FILES+=usr/lib/libprivatessh_p.a
|
||||
OLD_FILES+=usr/lib/libprivateucl_p.a
|
||||
OLD_FILES+=usr/lib/libprivateunbound_p.a
|
||||
OLD_FILES+=usr/lib/libprivatezstd_p.a
|
||||
OLD_FILES+=usr/lib/libproc_p.a
|
||||
OLD_FILES+=usr/lib/libprocstat_p.a
|
||||
OLD_FILES+=usr/lib/libpthread_p.a
|
||||
OLD_FILES+=usr/lib/libradius_p.a
|
||||
OLD_FILES+=usr/lib/libregex_p.a
|
||||
OLD_FILES+=usr/lib/libroken_p.a
|
||||
OLD_FILES+=usr/lib/librpcsvc_p.a
|
||||
OLD_FILES+=usr/lib/librss_p.a
|
||||
OLD_FILES+=usr/lib/librt_p.a
|
||||
OLD_FILES+=usr/lib/librtld_db_p.a
|
||||
OLD_FILES+=usr/lib/libsbuf_p.a
|
||||
OLD_FILES+=usr/lib/libsdp_p.a
|
||||
OLD_FILES+=usr/lib/libsmb_p.a
|
||||
OLD_FILES+=usr/lib/libssl_p.a
|
||||
OLD_FILES+=usr/lib/libstdbuf_p.a
|
||||
OLD_FILES+=usr/lib/libstdc++_p.a
|
||||
OLD_FILES+=usr/lib/libstdthreads_p.a
|
||||
OLD_FILES+=usr/lib/libsupc++_p.a
|
||||
OLD_FILES+=usr/lib/libsysdecode_p.a
|
||||
OLD_FILES+=usr/lib/libtacplus_p.a
|
||||
OLD_FILES+=usr/lib/libtermcap_p.a
|
||||
OLD_FILES+=usr/lib/libtermcapw_p.a
|
||||
@ -7559,14 +7612,23 @@ OLD_FILES+=usr/lib/libtinfo_p.a
|
||||
OLD_FILES+=usr/lib/libtinfow_p.a
|
||||
OLD_FILES+=usr/lib/libufs_p.a
|
||||
OLD_FILES+=usr/lib/libugidfw_p.a
|
||||
OLD_FILES+=usr/lib/libulog_p.a
|
||||
OLD_FILES+=usr/lib/libumem_p.a
|
||||
OLD_FILES+=usr/lib/libusb_p.a
|
||||
OLD_FILES+=usr/lib/libusbhid_p.a
|
||||
OLD_FILES+=usr/lib/libutempter_p.a
|
||||
OLD_FILES+=usr/lib/libutil_p.a
|
||||
OLD_FILES+=usr/lib/libuutil_p.a
|
||||
OLD_FILES+=usr/lib/libvgl_p.a
|
||||
OLD_FILES+=usr/lib/libvmmapi_p.a
|
||||
OLD_FILES+=usr/lib/libwind_p.a
|
||||
OLD_FILES+=usr/lib/libwrap_p.a
|
||||
OLD_FILES+=usr/lib/libxo_p.a
|
||||
OLD_FILES+=usr/lib/liby_p.a
|
||||
OLD_FILES+=usr/lib/libypclnt_p.a
|
||||
OLD_FILES+=usr/lib/libz_p.a
|
||||
OLD_FILES+=usr/lib/libzfs_core_p.a
|
||||
OLD_FILES+=usr/lib/libzfs_p.a
|
||||
OLD_FILES+=usr/lib/private/libldns_p.a
|
||||
OLD_FILES+=usr/lib/private/libssh_p.a
|
||||
.endif
|
||||
|
@ -54,7 +54,6 @@ device miibus
|
||||
device vr
|
||||
device wlan
|
||||
options IEEE80211_DEBUG
|
||||
options IEEE80211_AMPDU_AGE
|
||||
options IEEE80211_SUPPORT_MESH
|
||||
device wlan_wep
|
||||
device wlan_ccmp
|
||||
|
@ -116,16 +116,14 @@ main(int argc, char *argv[])
|
||||
if (argc < 2 || argc > 4)
|
||||
usage();
|
||||
|
||||
if (caph_limit_stdio() == -1)
|
||||
err(ERR_EXIT, "failed to limit stdio");
|
||||
|
||||
/* Backward compatibility -- handle "-" meaning stdin. */
|
||||
special = 0;
|
||||
if (strcmp(file1 = argv[0], "-") == 0) {
|
||||
special = 1;
|
||||
fd1 = STDIN_FILENO;
|
||||
fd1 = 0;
|
||||
file1 = "stdin";
|
||||
} else if ((fd1 = open(file1, oflag, 0)) < 0 && errno != EMLINK) {
|
||||
}
|
||||
else if ((fd1 = open(file1, oflag, 0)) < 0 && errno != EMLINK) {
|
||||
if (!sflag)
|
||||
err(ERR_EXIT, "%s", file1);
|
||||
else
|
||||
@ -136,9 +134,10 @@ main(int argc, char *argv[])
|
||||
errx(ERR_EXIT,
|
||||
"standard input may only be specified once");
|
||||
special = 1;
|
||||
fd2 = STDIN_FILENO;
|
||||
fd2 = 0;
|
||||
file2 = "stdin";
|
||||
} else if ((fd2 = open(file2, oflag, 0)) < 0 && errno != EMLINK) {
|
||||
}
|
||||
else if ((fd2 = open(file2, oflag, 0)) < 0 && errno != EMLINK) {
|
||||
if (!sflag)
|
||||
err(ERR_EXIT, "%s", file2);
|
||||
else
|
||||
@ -176,6 +175,16 @@ main(int argc, char *argv[])
|
||||
if (caph_fcntls_limit(fd2, fcntls) < 0)
|
||||
err(ERR_EXIT, "unable to limit fcntls for %s", file2);
|
||||
|
||||
if (!special) {
|
||||
cap_rights_init(&rights);
|
||||
if (caph_rights_limit(STDIN_FILENO, &rights) < 0) {
|
||||
err(ERR_EXIT, "unable to limit stdio");
|
||||
}
|
||||
}
|
||||
|
||||
if (caph_limit_stdout() == -1 || caph_limit_stderr() == -1)
|
||||
err(ERR_EXIT, "unable to limit stdio");
|
||||
|
||||
caph_cache_catpages();
|
||||
|
||||
if (caph_enter() < 0)
|
||||
|
@ -31,11 +31,10 @@ special_head() {
|
||||
special_body() {
|
||||
echo 0123456789abcdef > a
|
||||
echo 0123456789abcdeg > b
|
||||
cat a | atf_check -s exit:0 cmp a -
|
||||
cat a | atf_check -s exit:0 cmp - a
|
||||
cat b | atf_check -s not-exit:0 cmp a -
|
||||
cat b | atf_check -s not-exit:0 cmp - a
|
||||
true
|
||||
atf_check -s exit:0 -o empty -e empty -x "cat a | cmp a -"
|
||||
atf_check -s exit:0 -o empty -e empty -x "cat a | cmp - a"
|
||||
atf_check -s exit:1 -o not-empty -e empty -x "cat b | cmp a -"
|
||||
atf_check -s exit:1 -o not-empty -e empty -x "cat b | cmp - a"
|
||||
}
|
||||
|
||||
atf_test_case symlink
|
||||
|
@ -193,6 +193,11 @@ dsmatchselect(const char *args, devstat_select_mode select_mode, int maxshowdevs
|
||||
int i;
|
||||
int retval = 0;
|
||||
|
||||
if (!args) {
|
||||
warnx("dsmatchselect: no arguments");
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Break the (pipe delimited) input string out into separate
|
||||
* strings.
|
||||
@ -251,6 +256,11 @@ dsselect(const char *args, devstat_select_mode select_mode, int maxshowdevs,
|
||||
int i;
|
||||
int retval = 0;
|
||||
|
||||
if (!args) {
|
||||
warnx("dsselect: no argument");
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we've gone through this code before, free previously
|
||||
* allocated resources.
|
||||
|
@ -158,7 +158,7 @@ by careless unit definitions.
|
||||
Comments in the unit definition file
|
||||
begin with a '#' or '/' character at the beginning of a line.
|
||||
.Pp
|
||||
Prefixes are defined in the same was as standard units, but with
|
||||
Prefixes are defined in the same way as standard units, but with
|
||||
a trailing dash at the end of the prefix name.
|
||||
If a unit is not found
|
||||
even after removing trailing 's' or 'es', then it will be checked
|
||||
|
@ -310,6 +310,7 @@ config_SourceRelease () {
|
||||
if echo ${UNAME_r} | grep -qE '^[0-9.]+$'; then
|
||||
UNAME_r="${UNAME_r}-RELEASE"
|
||||
fi
|
||||
export UNAME_r
|
||||
}
|
||||
|
||||
# Define what happens to output of utilities
|
||||
@ -667,17 +668,23 @@ fetchupgrade_check_params () {
|
||||
FETCHDIR=${RELNUM}/${ARCH}
|
||||
PATCHDIR=${RELNUM}/${ARCH}/bp
|
||||
|
||||
# Disallow upgrade from a version that is not `-RELEASE`
|
||||
if ! echo "${RELNUM}" | grep -qE -- "-RELEASE$"; then
|
||||
echo -n "`basename $0`: "
|
||||
cat <<- EOF
|
||||
Cannot upgrade from a version that is not a '-RELEASE' using `basename $0`.
|
||||
Instead, FreeBSD can be directly upgraded by source or upgraded to a
|
||||
RELEASE/RELENG version prior to running `basename $0`.
|
||||
EOF
|
||||
echo "System version: ${RELNUM}"
|
||||
exit 1
|
||||
fi
|
||||
# Disallow upgrade from a version that is not a release
|
||||
case ${RELNUM} in
|
||||
*-RELEASE | *-ALPHA* | *-BETA* | *-RC*)
|
||||
;;
|
||||
*)
|
||||
echo -n "`basename $0`: "
|
||||
cat <<- EOF
|
||||
Cannot upgrade from a version that is not a release
|
||||
(including alpha, beta and release candidates)
|
||||
using `basename $0`. Instead, FreeBSD can be directly
|
||||
upgraded by source or upgraded to a RELEASE/RELENG version
|
||||
prior to running `basename $0`.
|
||||
Currently running: ${RELNUM}
|
||||
EOF
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Figure out what directory contains the running kernel
|
||||
BOOTFILE=`sysctl -n kern.bootfile`
|
||||
@ -2917,10 +2924,11 @@ Kernel updates have been installed. Please reboot and run
|
||||
install_from_index INDEX-NEW || return 1
|
||||
install_delete INDEX-OLD INDEX-NEW || return 1
|
||||
|
||||
# Rebuild /etc/spwd.db and /etc/pwd.db if necessary.
|
||||
# Rebuild generated pwd files.
|
||||
if [ ${BASEDIR}/etc/master.passwd -nt ${BASEDIR}/etc/spwd.db ] ||
|
||||
[ ${BASEDIR}/etc/master.passwd -nt ${BASEDIR}/etc/pwd.db ]; then
|
||||
pwd_mkdb -d ${BASEDIR}/etc ${BASEDIR}/etc/master.passwd
|
||||
[ ${BASEDIR}/etc/master.passwd -nt ${BASEDIR}/etc/pwd.db ] ||
|
||||
[ ${BASEDIR}/etc/master.passwd -nt ${BASEDIR}/etc/passwd ]; then
|
||||
pwd_mkdb -d ${BASEDIR}/etc -p ${BASEDIR}/etc/master.passwd
|
||||
fi
|
||||
|
||||
# Rebuild /etc/login.conf.db if necessary.
|
||||
|
@ -241,8 +241,7 @@ get_font(void)
|
||||
if (strcmp(buf, "NO")) {
|
||||
if (fnt)
|
||||
free(fnt);
|
||||
fnt = (char *) malloc(strlen(buf) + 1);
|
||||
strcpy(fnt, buf);
|
||||
fnt = strdup(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user