freebsd_network: Adaptations in preparation for the OpenBSD layer.

Most of these changes however add things that FreeBSD has (with a few
exceptions noted in comments) which the OpenBSD shim layer merely needs
to make use of.

(FreeBSD used to have support for IFF_NEEDSGIANT but removed it. The
support instated here is very similar to what FreeBSD used to have.)
This commit is contained in:
Augustin Cavalier
2022-06-09 01:28:54 -04:00
parent 6a9406a172
commit 8548a4adc6
22 changed files with 309 additions and 69 deletions
+1
View File
@@ -25,6 +25,7 @@ KernelStaticLibrary libfreebsd_network.a :
fbsd_subr_bufring.c fbsd_subr_bufring.c
fbsd_subr_sbuf.c fbsd_subr_sbuf.c
fbsd_time.c fbsd_time.c
fbsd_timingsafe.c
fbsd_usb_error.c fbsd_usb_error.c
fbsd_usb_util.c fbsd_usb_util.c
fbsd_usb_lookup.c fbsd_usb_lookup.c
+23 -2
View File
@@ -297,6 +297,23 @@ rman_get_virtual(struct resource *res)
} }
bus_addr_t
rman_get_start(struct resource *res)
{
return res->r_bushandle;
}
bus_size_t
rman_get_size(struct resource *res)
{
area_info info;
if (get_area_info(res->r_mapped_area, &info) != B_OK)
return 0;
return info.size;
}
// #pragma mark - Interrupt handling // #pragma mark - Interrupt handling
@@ -329,7 +346,13 @@ intr_handler(void *data)
//device_printf(intr->dev, "in soft interrupt handler.\n"); //device_printf(intr->dev, "in soft interrupt handler.\n");
atomic_or(&intr->handling, 1); atomic_or(&intr->handling, 1);
if ((intr->flags & INTR_MPSAFE) == 0)
mtx_lock(&Giant);
intr->handler(intr->arg); intr->handler(intr->arg);
if ((intr->flags & INTR_MPSAFE) == 0)
mtx_unlock(&Giant);
atomic_and(&intr->handling, 0); atomic_and(&intr->handling, 0);
HAIKU_REENABLE_INTERRUPTS(intr->dev); HAIKU_REENABLE_INTERRUPTS(intr->dev);
} }
@@ -355,8 +378,6 @@ int
bus_setup_intr(device_t dev, struct resource *res, int flags, bus_setup_intr(device_t dev, struct resource *res, int flags,
driver_filter_t* filter, driver_intr_t handler, void *arg, void **_cookie) driver_filter_t* filter, driver_intr_t handler, void *arg, void **_cookie)
{ {
/* TODO check MPSAFE etc */
struct internal_intr *intr = (struct internal_intr *)malloc( struct internal_intr *intr = (struct internal_intr *)malloc(
sizeof(struct internal_intr)); sizeof(struct internal_intr));
char semName[64]; char semName[64];
+10
View File
@@ -5,6 +5,7 @@
#include <OS.h> #include <OS.h>
#include <compat/sys/kernel.h> #include <compat/sys/kernel.h>
#include <compat/sys/time.h>
int32_t int32_t
@@ -12,3 +13,12 @@ _get_ticks()
{ {
return USEC_2_TICKS(system_time()); return USEC_2_TICKS(system_time());
} }
void
getmicrouptime(struct timeval *tvp)
{
bigtime_t usecs = system_time();
tvp->tv_sec = usecs / 1000000;
tvp->tv_usec = usecs % 1000000;
}
@@ -70,6 +70,7 @@
#define IFF_MONITOR 0x00400000 /* (n) user-requested monitor mode */ #define IFF_MONITOR 0x00400000 /* (n) user-requested monitor mode */
#define IFF_PPROMISC 0x00800000 /* (n) user-requested promisc mode */ #define IFF_PPROMISC 0x00800000 /* (n) user-requested promisc mode */
#define IFF_NOGROUP 0x01000000 /* (n) interface is not part of any groups */ #define IFF_NOGROUP 0x01000000 /* (n) interface is not part of any groups */
#define IFF_NEEDSGIANT 0x02000000 /* (i) hold Giant over hook calls (OpenBSD compatibility) */
#define LINK_STATE_UNKNOWN 0 #define LINK_STATE_UNKNOWN 0
#define LINK_STATE_DOWN 1 #define LINK_STATE_DOWN 1
@@ -258,7 +258,6 @@ struct ifnet {
void *if_afdata[AF_MAX]; void *if_afdata[AF_MAX];
int if_afdata_initialized; int if_afdata_initialized;
struct mtx if_afdata_mtx; struct mtx if_afdata_mtx;
struct task if_starttask; /* task for IFF_NEEDSGIANT */
struct task if_linktask; /* task for link change events */ struct task if_linktask; /* task for link change events */
struct mtx if_addr_mtx; /* mutex to protect address lists */ struct mtx if_addr_mtx; /* mutex to protect address lists */
@@ -752,6 +751,10 @@ int ifioctl(struct socket *, u_long, caddr_t, struct thread *);
int ifpromisc(struct ifnet *, int); int ifpromisc(struct ifnet *, int);
struct ifnet *ifunit(const char *); struct ifnet *ifunit(const char *);
/* Haiku extension for OpenBSD compat */
int if_alloc_inplace(struct ifnet *ifp, u_char type);
void if_free_inplace(struct ifnet *ifp);
struct ifaddr *ifa_ifwithaddr(struct sockaddr *); struct ifaddr *ifa_ifwithaddr(struct sockaddr *);
struct ifaddr *ifa_ifwithbroadaddr(struct sockaddr *); struct ifaddr *ifa_ifwithbroadaddr(struct sockaddr *);
struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *); struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *);
@@ -13,12 +13,17 @@
typedef void (*task_fn_t)(void *context, int pending); typedef void (*task_fn_t)(void *context, int pending);
struct task { struct task {
int ta_pending;
int ta_priority; int ta_priority;
int ta_flags;
task_fn_t ta_handler; task_fn_t ta_handler;
void *ta_argument; void *ta_argument;
int ta_pending;
struct list_link ta_link; struct list_link ta_link;
}; };
#define TASK_NEEDSGIANT (1 << 0) /* Haiku extension, OpenBSD compatibility */
#endif #endif
@@ -269,7 +269,7 @@ buf_ring_advance_sc(struct buf_ring *br)
static __inline void static __inline void
buf_ring_putback_sc(struct buf_ring *br, void *_new) buf_ring_putback_sc(struct buf_ring *br, void *_new)
{ {
KASSERT(br->br_cons_head != br->br_prod_tail, KASSERT_FREEBSD(br->br_cons_head != br->br_prod_tail,
("Buf-Ring has none in putback")) ; ("Buf-Ring has none in putback")) ;
br->br_ring[br->br_cons_head] = _new; br->br_ring[br->br_cons_head] = _new;
} }
@@ -207,8 +207,11 @@ enum {
FBSD_SWI_TASKQUEUE = 1 << 2, FBSD_SWI_TASKQUEUE = 1 << 2,
FBSD_THREAD_TASKQUEUE = 1 << 3, FBSD_THREAD_TASKQUEUE = 1 << 3,
FBSD_WLAN_FEATURE = 1 << 4, FBSD_WLAN_FEATURE = 1 << 4,
FBSD_WLAN = FBSD_WLAN_FEATURE | FBSD_TASKQUEUES FBSD_WLAN = FBSD_WLAN_FEATURE | FBSD_TASKQUEUES
| FBSD_THREAD_TASKQUEUE, | FBSD_THREAD_TASKQUEUE,
OBSD_WLAN = FBSD_WLAN_FEATURE | FBSD_TASKQUEUES
| FBSD_FAST_TASKQUEUE,
}; };
#define HAIKU_DRIVER_REQUIREMENTS(flags) \ #define HAIKU_DRIVER_REQUIREMENTS(flags) \
@@ -16,6 +16,9 @@ extern int random(void);
u_int read_random(void *, u_int); u_int read_random(void *, u_int);
void arc4rand(void *ptr, u_int len, int reseed); void arc4rand(void *ptr, u_int len, int reseed);
uint32_t arc4random(void); uint32_t arc4random(void);
void arc4random_buf(void *ptr, size_t len);
int timingsafe_bcmp(const void *, const void *, size_t);
static __inline int imax(int a, int b) { return (a > b ? a : b); } static __inline int imax(int a, int b) { return (a > b ? a : b); }
static __inline int imin(int a, int b) { return (a < b ? a : b); } static __inline int imin(int a, int b) { return (a < b ? a : b); }
@@ -43,7 +43,7 @@ void _kernel_contigfree(void *addr, unsigned long size);
#define kernel_malloc(size, base, flags) \ #define kernel_malloc(size, base, flags) \
_kernel_malloc(size, flags) _kernel_malloc(size, flags)
#define kernel_free(ptr, base) \ #define kernel_free(ptr, tag) \
_kernel_free(ptr) _kernel_free(ptr)
#define kernel_contigmalloc(size, type, flags, low, high, alignment, boundary) \ #define kernel_contigmalloc(size, type, flags, low, high, alignment, boundary) \
@@ -212,6 +212,16 @@ m_cljset(struct mbuf *m, void *cl, int type)
m->m_flags |= M_EXT; m->m_flags |= M_EXT;
} }
/* These are for OpenBSD compatibility. */
#define MTAG_ABI_COMPAT 0 /* compatibility ABI */
static __inline struct m_tag *
m_tag_find(struct mbuf *m, uint16_t type, struct m_tag *start)
{
return (SLIST_EMPTY(&m->m_pkthdr.tags) ? (struct m_tag *)NULL :
m_tag_locate(m, MTAG_ABI_COMPAT, type, start));
}
/* mbufq */ /* mbufq */
struct mbufq { struct mbufq {
@@ -215,6 +215,12 @@ struct pkthdr {
uint8_t rsstype; /* hash type */ uint8_t rsstype; /* hash type */
uint16_t tso_segsz; uint16_t tso_segsz;
uint16_t ether_vtag; uint16_t ether_vtag;
/* Layer specific non-persistent local storage for reassembly, etc. */
union {
uintptr_t unintptr[1];
void* ptr;
} PH_loc;
}; };
struct m_tag { struct m_tag {
@@ -1,9 +1,3 @@
/*
* Copyright 2007, Hugo Santos. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
/*- /*-
* Copyright 1998 Massachusetts Institute of Technology * Copyright 1998 Massachusetts Institute of Technology
* *
@@ -61,30 +55,7 @@ bus_space_handle_t rman_get_bushandle(struct resource *);
bus_space_tag_t rman_get_bustag(struct resource *); bus_space_tag_t rman_get_bustag(struct resource *);
int rman_get_rid(struct resource *); int rman_get_rid(struct resource *);
void* rman_get_virtual(struct resource *); void* rman_get_virtual(struct resource *);
bus_addr_t rman_get_start(struct resource *);
bus_size_t rman_get_size(struct resource *);
static inline u_long
rman_get_start(struct resource *resourcePointer)
{
return resourcePointer->r_bushandle;
}
static inline uint32_t
rman_make_alignment_flags(uint32_t size)
{
int i;
/*
* Find the hightest bit set, and add one if more than one bit
* set. We're effectively computing the ceil(log2(size)) here.
*/
for (i = 31; i > 0; i--)
if ((1 << i) & size)
break;
if (~(1 << i) & size)
i++;
return RF_ALIGNMENT_LOG2(i);
}
#endif /* _FBSD_COMPAT_SYS_RMAN_H_ */ #endif /* _FBSD_COMPAT_SYS_RMAN_H_ */
@@ -1,5 +1,5 @@
/* /*
* Copyright 2009 Haiku Inc. All rights reserved. * Copyright 2009-2022, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef _FBSD_COMPAT_SYS_SYSLOG_H_ #ifndef _FBSD_COMPAT_SYS_SYSLOG_H_
@@ -7,5 +7,7 @@
#define LOG_ERR 3 /* error conditions */ #define LOG_ERR 3 /* error conditions */
#define LOG_WARNING 4 /* warning conditions */
#endif /* _FBSD_COMPAT_SYS_SYSLOG_H_ */ #endif /* _FBSD_COMPAT_SYS_SYSLOG_H_ */
@@ -41,13 +41,14 @@ int printf(const char *format, ...) __printflike(1, 2);
#endif #endif
#ifdef INVARIANTS #ifdef INVARIANTS
#define KASSERT(cond,msg) do { \ #define KASSERT_FREEBSD(cond,msg) do { \
if (!(cond)) \ if (!(cond)) \
panic msg; \ panic msg; \
} while (0) } while (0)
#define KASSERT(cond,msg) KASSERT_FREEBSD(cond,msg)
#else #else
#define KASSERT(exp,msg) do { \ #define KASSERT_FREEBSD(exp,msg) do {} while (0)
} while (0) #define KASSERT(cond,msg) KASSERT_FREEBSD(cond,msg)
#endif #endif
#define DELAY(n) \ #define DELAY(n) \
@@ -1,6 +1,39 @@
/* /*
* Copyright 2020, Haiku, Inc. All rights reserved. * Copyright 2020-2022, Haiku, Inc. All rights reserved.
* All rights reserved. Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 1982, 1986, 1993
* The Regents of the University of California. 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.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
*
* @(#)time.h 8.5 (Berkeley) 5/4/95
* $FreeBSD$
*/ */
#ifndef _FBSD_COMPAT_SYS_TIME_H_ #ifndef _FBSD_COMPAT_SYS_TIME_H_
#define _FBSD_COMPAT_SYS_TIME_H_ #define _FBSD_COMPAT_SYS_TIME_H_
@@ -21,7 +54,21 @@
#define time_uptime USEC_2_TICKS(system_time()) #define time_uptime USEC_2_TICKS(system_time())
int ppsratecheck(struct timeval*, int*, int); /* Operations on timevals. */
#define timevalclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0)
#define timevalisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
#define timevalcmp(tvp, uvp, cmp) \
(((tvp)->tv_sec == (uvp)->tv_sec) ? \
((tvp)->tv_usec cmp (uvp)->tv_usec) : \
((tvp)->tv_sec cmp (uvp)->tv_sec))
void getmicrouptime(struct timeval *tvp);
int ppsratecheck(struct timeval *, int *, int);
int ratecheck(struct timeval *, const struct timeval *);
void timevaladd(struct timeval *t1, const struct timeval *t2);
void timevalsub(struct timeval *t1, const struct timeval *t2);
#endif /* _FBSD_COMPAT_SYS_TIME_H_ */ #endif /* _FBSD_COMPAT_SYS_TIME_H_ */
+29 -6
View File
@@ -49,6 +49,8 @@ compat_open(const char *name, uint32 flags, void **cookie)
return B_BUSY; return B_BUSY;
} }
IFF_LOCKGIANT(ifp);
ifp->if_init(ifp->if_softc); ifp->if_init(ifp->if_softc);
if (!HAIKU_DRIVER_REQUIRES(FBSD_WLAN_FEATURE)) { if (!HAIKU_DRIVER_REQUIRES(FBSD_WLAN_FEATURE)) {
@@ -68,6 +70,8 @@ compat_open(const char *name, uint32 flags, void **cookie)
ifp->flags &= ~DEVICE_CLOSED; ifp->flags &= ~DEVICE_CLOSED;
ifp->if_ioctl(ifp, SIOCSIFFLAGS, NULL); ifp->if_ioctl(ifp, SIOCSIFFLAGS, NULL);
IFF_UNLOCKGIANT(ifp);
*cookie = ifp; *cookie = ifp;
return B_OK; return B_OK;
} }
@@ -184,7 +188,11 @@ compat_write(void *cookie, off_t position, const void *buffer,
memcpy(mtod(mb, void *), buffer, mb->m_len); memcpy(mtod(mb, void *), buffer, mb->m_len);
*numBytes = length; *numBytes = length;
return ifp->if_output(ifp, mb, NULL, NULL); IFF_LOCKGIANT(ifp);
int result = ifp->if_output(ifp, mb, NULL, NULL);
IFF_UNLOCKGIANT(ifp);
return result;
} }
@@ -192,6 +200,7 @@ static status_t
compat_control(void *cookie, uint32 op, void *arg, size_t length) compat_control(void *cookie, uint32 op, void *arg, size_t length)
{ {
struct ifnet *ifp = cookie; struct ifnet *ifp = cookie;
status_t status;
//if_printf(ifp, "compat_control(op %lu, %p, [%lu])\n", op, //if_printf(ifp, "compat_control(op %lu, %p, [%lu])\n", op,
// arg, length); // arg, length);
@@ -228,7 +237,11 @@ compat_control(void *cookie, uint32 op, void *arg, size_t length)
ifp->if_flags |= IFF_PROMISC; ifp->if_flags |= IFF_PROMISC;
else else
ifp->if_flags &= ~IFF_PROMISC; ifp->if_flags &= ~IFF_PROMISC;
return ifp->if_ioctl(ifp, SIOCSIFFLAGS, NULL);
IFF_LOCKGIANT(ifp);
status = ifp->if_ioctl(ifp, SIOCSIFFLAGS, NULL);
IFF_UNLOCKGIANT(ifp);
return status;
} }
case ETHER_GETFRAMESIZE: case ETHER_GETFRAMESIZE:
@@ -273,10 +286,13 @@ compat_control(void *cookie, uint32 op, void *arg, size_t length)
if (user_memcpy(LLADDR(&address), arg, ETHER_ADDR_LEN) < B_OK) if (user_memcpy(LLADDR(&address), arg, ETHER_ADDR_LEN) < B_OK)
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
IFF_LOCKGIANT(ifp);
if (op == ETHER_ADDMULTI) if (op == ETHER_ADDMULTI)
return if_addmulti(ifp, (struct sockaddr *)&address, NULL); status = if_addmulti(ifp, (struct sockaddr *)&address, NULL);
else
return if_delmulti(ifp, (struct sockaddr *)&address); status = if_delmulti(ifp, (struct sockaddr *)&address);
IFF_UNLOCKGIANT(ifp);
return status;
} }
case ETHER_GET_LINK_STATE: case ETHER_GET_LINK_STATE:
@@ -289,7 +305,9 @@ compat_control(void *cookie, uint32 op, void *arg, size_t length)
return EINVAL; return EINVAL;
memset(&mediareq, 0, sizeof(mediareq)); memset(&mediareq, 0, sizeof(mediareq));
IFF_LOCKGIANT(ifp);
status = ifp->if_ioctl(ifp, SIOCGIFMEDIA, (caddr_t)&mediareq); status = ifp->if_ioctl(ifp, SIOCGIFMEDIA, (caddr_t)&mediareq);
IFF_UNLOCKGIANT(ifp);
if (status < B_OK) if (status < B_OK)
return status; return status;
@@ -313,7 +331,12 @@ compat_control(void *cookie, uint32 op, void *arg, size_t length)
case SIOCSIFMEDIA: case SIOCSIFMEDIA:
case SIOCGIFMEDIA: case SIOCGIFMEDIA:
case SIOCSIFMTU: case SIOCSIFMTU:
return ifp->if_ioctl(ifp, op, (caddr_t)arg); {
IFF_LOCKGIANT(ifp);
status = ifp->if_ioctl(ifp, op, (caddr_t)arg);
IFF_UNLOCKGIANT(ifp);
return status;
}
} }
return wlan_control(cookie, op, arg, length); return wlan_control(cookie, op, arg, length);
+80 -1
View File
@@ -31,6 +31,46 @@
#include <sys/kernel.h> #include <sys/kernel.h>
#include <sys/time.h> #include <sys/time.h>
/*
* ratecheck(): simple time-based rate-limit checking.
*/
int
ratecheck(struct timeval *lasttime, const struct timeval *mininterval)
{
struct timeval tv, delta;
int rv = 0;
getmicrouptime(&tv); /* NB: 10ms precision */
delta = tv;
timevalsub(&delta, lasttime);
/*
* check for 0,0 is so that the message will be seen at least once,
* even if interval is huge.
*/
if (timevalcmp(&delta, mininterval, >=) ||
(lasttime->tv_sec == 0 && lasttime->tv_usec == 0)) {
*lasttime = tv;
rv = 1;
}
return (rv);
}
/*
* ppsratecheck(): packets (or events) per second limitation.
*
* Return 0 if the limit is to be enforced (e.g. the caller
* should drop a packet because of the rate limitation).
*
* maxpps of 0 always causes zero to be returned. maxpps of -1
* always causes 1 to be returned; this effectively defeats rate
* limiting.
*
* Note that we maintain the struct timeval for compatibility
* with other bsd systems. We reuse the storage and just monitor
* clock ticks for minimal overhead.
*/
int int
ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps) ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps)
{ {
@@ -48,6 +88,45 @@ ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps)
return (maxpps != 0); return (maxpps != 0);
} else { } else {
(*curpps)++; /* NB: ignore potential overflow */ (*curpps)++; /* NB: ignore potential overflow */
return (maxpps < 0 || *curpps < maxpps); return (maxpps < 0 || *curpps <= maxpps);
} }
} }
static void
timevalfix(struct timeval *t1)
{
if (t1->tv_usec < 0) {
t1->tv_sec--;
t1->tv_usec += 1000000;
}
if (t1->tv_usec >= 1000000) {
t1->tv_sec++;
t1->tv_usec -= 1000000;
}
}
/*
* Add and subtract routines for timevals.
* N.B.: subtract routine doesn't deal with
* results which are before the beginning,
* it just gets very confused in this case.
* Caveat emptor.
*/
void
timevaladd(struct timeval *t1, const struct timeval *t2)
{
t1->tv_sec += t2->tv_sec;
t1->tv_usec += t2->tv_usec;
timevalfix(t1);
}
void
timevalsub(struct timeval *t1, const struct timeval *t2)
{
t1->tv_sec -= t2->tv_sec;
t1->tv_usec -= t2->tv_usec;
timevalfix(t1);
}
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2010 Damien Miller. All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/libkern.h>
int
timingsafe_bcmp(const void *b1, const void *b2, size_t n)
{
const unsigned char *p1 = b1, *p2 = b2;
int ret = 0;
for (; n > 0; n--)
ret |= *p1++ ^ *p2++;
return (ret != 0);
}
+29 -16
View File
@@ -149,21 +149,17 @@ ifindex_free_locked(u_short idx)
} }
struct ifnet * int
if_alloc(u_char type) if_alloc_inplace(struct ifnet *ifp, u_char type)
{ {
char semName[64]; char semName[64];
u_short index; u_short index;
struct ifnet *ifp = _kernel_malloc(sizeof(struct ifnet), M_ZERO);
if (ifp == NULL)
return NULL;
snprintf(semName, sizeof(semName), "%s receive", gDriverName); snprintf(semName, sizeof(semName), "%s receive", gDriverName);
ifp->receive_sem = create_sem(0, semName); ifp->receive_sem = create_sem(0, semName);
if (ifp->receive_sem < B_OK) if (ifp->receive_sem < B_OK)
goto err1; return ifp->receive_sem;
ifp->link_state_sem = -1; ifp->link_state_sem = -1;
ifp->open_count = 0; ifp->open_count = 0;
@@ -188,7 +184,7 @@ if_alloc(u_char type)
ifnet_setbyindex(ifp->if_index, ifp); ifnet_setbyindex(ifp->if_index, ifp);
IF_ADDR_LOCK_INIT(ifp); IF_ADDR_LOCK_INIT(ifp);
return ifp; return 0;
err3: err3:
switch (type) { switch (type) {
@@ -200,14 +196,28 @@ err3:
err2: err2:
delete_sem(ifp->receive_sem); delete_sem(ifp->receive_sem);
err1: return -1;
_kernel_free(ifp); }
return NULL;
struct ifnet *
if_alloc(u_char type)
{
struct ifnet *ifp = _kernel_malloc(sizeof(struct ifnet), M_ZERO);
if (ifp == NULL)
return NULL;
if (if_alloc_inplace(ifp, type) != 0) {
_kernel_free(ifp);
return NULL;
}
return ifp;
} }
void void
if_free(struct ifnet *ifp) if_free_inplace(struct ifnet *ifp)
{ {
// IEEE80211 devices won't be in this list, // IEEE80211 devices won't be in this list,
// so don't try to remove them. // so don't try to remove them.
@@ -227,6 +237,13 @@ if_free(struct ifnet *ifp)
delete_sem(ifp->receive_sem); delete_sem(ifp->receive_sem);
ifq_uninit(&ifp->receive_queue); ifq_uninit(&ifp->receive_queue);
}
void
if_free(struct ifnet *ifp)
{
if_free_inplace(ifp);
_kernel_free(ifp); _kernel_free(ifp);
} }
@@ -397,10 +414,6 @@ if_detach(struct ifnet *ifp)
void void
if_start(struct ifnet *ifp) if_start(struct ifnet *ifp)
{ {
#ifdef IFF_NEEDSGIANT
if (ifp->if_flags & IFF_NEEDSGIANT)
panic("freebsd compat.: unsupported giant requirement");
#endif
ifp->if_start(ifp); ifp->if_start(ifp);
} }
+8 -2
View File
@@ -1,6 +1,5 @@
/* /*
* Copyright 2009, Colin Günther, coling@gmx.de. All rights reserved. * Copyright 2018-2022, Haiku, Inc. All rights reserved.
* Copyright 2018, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
@@ -36,3 +35,10 @@ arc4random(void)
arc4rand(&ret, sizeof ret, 0); arc4rand(&ret, sizeof ret, 0);
return ret; return ret;
} }
void
arc4random_buf(void *ptr, size_t len)
{
arc4rand(ptr, len, 0);
}
@@ -127,7 +127,13 @@ tq_handle_thread(void *data)
pending = t->ta_pending; pending = t->ta_pending;
t->ta_pending = 0; t->ta_pending = 0;
if ((t->ta_flags & TASK_NEEDSGIANT) != 0)
mtx_lock(&Giant);
t->ta_handler(t->ta_argument, pending); t->ta_handler(t->ta_argument, pending);
if ((t->ta_flags & TASK_NEEDSGIANT) != 0)
mtx_unlock(&Giant);
} }
return 0; return 0;
@@ -489,6 +495,7 @@ void
task_init(struct task *task, int prio, task_fn_t handler, void *context) task_init(struct task *task, int prio, task_fn_t handler, void *context)
{ {
task->ta_priority = prio; task->ta_priority = prio;
task->ta_flags = 0;
task->ta_handler = handler; task->ta_handler = handler;
task->ta_argument = context; task->ta_argument = context;
task->ta_pending = 0; task->ta_pending = 0;