diff --git a/src/libs/compat/freebsd_network/Jamfile b/src/libs/compat/freebsd_network/Jamfile index fe1e326d21..9bfc4d236a 100644 --- a/src/libs/compat/freebsd_network/Jamfile +++ b/src/libs/compat/freebsd_network/Jamfile @@ -12,6 +12,7 @@ Library libfreebsd_network.a : busdma_machdep.c compat.c device.c + if.c if_media.c mbuf.c mutex.c diff --git a/src/libs/compat/freebsd_network/compat/altq/if_altq.h b/src/libs/compat/freebsd_network/compat/altq/if_altq.h index 701894cb85..ba77f41b7d 100644 --- a/src/libs/compat/freebsd_network/compat/altq/if_altq.h +++ b/src/libs/compat/freebsd_network/compat/altq/if_altq.h @@ -10,6 +10,7 @@ struct ifaltq { int ifq_len; int ifq_maxlen; + int ifq_drops; struct mtx ifq_mtx; struct mbuf * ifq_drv_head; @@ -25,6 +26,8 @@ struct ifaltq { #define ALTDQ_REMOVE 1 #define ALTQ_IS_ENABLED(ifq) 0 +#define ALTQ_ENQUEUE(ifr, m, foo, error) \ + do { m_freem(m); error = -1; } while (0) #define ALTQ_DEQUEUE(ifr, m) (m) = NULL #define TBR_IS_ENABLED(ifq) 0 diff --git a/src/libs/compat/freebsd_network/compat/sys/mbuf.h b/src/libs/compat/freebsd_network/compat/sys/mbuf.h index c43dfbb513..3692db1a84 100644 --- a/src/libs/compat/freebsd_network/compat/sys/mbuf.h +++ b/src/libs/compat/freebsd_network/compat/sys/mbuf.h @@ -66,6 +66,9 @@ struct mbuf { #define M_EXT 0x0001 #define M_PKTHDR 0x0002 +#define M_BCAST 0x0200 +#define M_MCAST 0x0400 + #define CSUM_IP 0x0001 #define CSUM_TCP 0x0002 #define CSUM_UDP 0x0004 diff --git a/src/libs/compat/freebsd_network/if.c b/src/libs/compat/freebsd_network/if.c new file mode 100644 index 0000000000..eea124dc50 --- /dev/null +++ b/src/libs/compat/freebsd_network/if.c @@ -0,0 +1,151 @@ +/* + * Copyright 2007, Hugo Santos. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Hugo Santos, hugosantos@gmail.com + * + * Some of this code is based on previous work by Marcus Overhagen. + */ + +#include "device.h" + +#include +#include + +#include +#include + +#include +#include +#include + +#include + +struct ifnet * +if_alloc(u_char type) +{ + struct ifnet *ifp = _kernel_malloc(sizeof(struct ifnet), M_ZERO); + if (ifp == NULL) + return NULL; + + ifp->if_type = type; + + IF_ADDR_LOCK_INIT(ifp); + return ifp; +} + + +void +if_free(struct ifnet *ifp) +{ + IF_ADDR_LOCK_DESTROY(ifp); + _kernel_free(ifp); +} + + +void +if_initname(struct ifnet *ifp, const char *name, int unit) +{ + ifp->if_dname = name; + ifp->if_dunit = unit; + + /* XXX use a more Haiku friendly name here? */ + snprintf(ifp->if_xname, IFNAMSIZ, "%s%d", name, unit); +} + + +void +if_attach(struct ifnet *ifp) +{ + TAILQ_INIT(&ifp->if_addrhead); + TAILQ_INIT(&ifp->if_prefixhead); + TAILQ_INIT(&ifp->if_multiaddrs); + + mtx_init(&ifp->if_snd.ifq_mtx, ifp->if_xname, NULL, MTX_DEF); +} + + +void +if_detach(struct ifnet *ifp) +{ + mtx_destroy(&ifp->if_snd.ifq_mtx); +} + + +void +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); +} + + +int +ether_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, + struct rtentry *rt0) +{ + int error; + IFQ_HANDOFF(ifp, m, error); + return error; +} + + +static void +ether_input(struct ifnet *ifp, struct mbuf *m) +{ + device_t dev = NULL; /* XXX */ + + IF_ENQUEUE(&dev->receive_queue, m); + release_sem_etc(dev->receive_sem, 1, B_DO_NOT_RESCHEDULE); +} + + +void +ether_ifattach(struct ifnet *ifp, const uint8_t *mac_address) +{ + ifp->if_addrlen = ETHER_ADDR_LEN; + ifp->if_hdrlen = ETHER_HDR_LEN; + if_attach(ifp); + ifp->if_mtu = ETHERMTU; + ifp->if_output = ether_output; + ifp->if_input = ether_input; + ifp->if_resolvemulti = NULL; /* done in the stack */ + + ifp->if_init(ifp->if_softc); +} + + +void +ether_ifdetach(struct ifnet *ifp) +{ + if_detach(ifp); +} + + +int +ether_ioctl(struct ifnet *ifp, int command, caddr_t data) +{ + struct ifreq *ifr = (struct ifreq *)data; + + switch (command) { + case SIOCSIFMTU: + if (ifr->ifr_mtu > ETHERMTU) + return EINVAL; + else + ; + /* need to fix our ifreq to work with C... */ + /* ifp->ifr_mtu = ifr->ifr_mtu; */ + break; + + default: + return EINVAL; + } + + return 0; +} +