50#include <sys/eventhandler.h>
52#include <sys/kernel.h>
53#include <sys/malloc.h>
57#include <sys/syslog.h>
58#include <sys/socket.h>
59#include <sys/taskqueue.h>
63#include <net/if_types.h>
64#include <net/if_arp.h>
65#include <net/if_var.h>
66#include <net/ethernet.h>
67#include <net/if_bridgevar.h>
77#define IFP2NG(ifp) ((ifp)->if_l2com)
227 for (i = 0; i < IFNAMSIZ; i++) {
228 if (ifname[i] ==
'.' || ifname[i] ==
':')
270 if (
priv->orphan == NULL) {
324 KASSERT(!
IFP2NG(ifp), (
"%s: node already exists?", __func__));
326 log(LOG_ERR,
"%s: can't %s for %s\n",
327 __func__,
"create node", ifp->if_xname);
332 priv = malloc(
sizeof(*
priv), M_NETGRAPH, M_NOWAIT | M_ZERO);
334 log(LOG_ERR,
"%s: can't %s for %s\n",
335 __func__,
"allocate memory", ifp->if_xname);
342 priv->hwassist = ifp->if_hwassist;
346 log(LOG_WARNING,
"%s: can't name node %s\n", __func__,
name);
359 taskqueue_drain(taskqueue_swi, &ifp->if_linktask);
381 int cmd, dummy_error = 0;
383 if (
state == LINK_STATE_UP)
385 else if (
state == LINK_STATE_DOWN)
395 if (
priv->orphan != NULL) {
417 if (ifp->if_type != IFT_ETHER &&
418 ifp->if_type != IFT_L2VLAN &&
419 ifp->if_type != IFT_BRIDGE)
432 log(LOG_WARNING,
"%s: can't re-name node %s\n", __func__,
name);
472 hookptr = &
priv->orphan;
478 if (*hookptr != NULL)
483 priv->ifp->if_hwassist = 0;
511 strlcpy(resp->
data,
priv->ifp->if_xname, IFNAMSIZ);
519 *((u_int32_t *)resp->
data) =
priv->ifp->if_index;
527 bcopy(IF_LLADDR(
priv->ifp),
528 resp->
data, ETHER_ADDR_LEN);
536 error = if_setlladdr(
priv->ifp,
537 (u_char *)msg->
data, ETHER_ADDR_LEN);
546 *((u_int32_t *)resp->
data) =
priv->promisc;
556 want = !!*((u_int32_t *)msg->
data);
557 if (want ^
priv->promisc) {
558 if ((error = ifpromisc(
priv->ifp, want)) != 0)
560 priv->promisc = want;
570 *((u_int32_t *)resp->
data) =
priv->autoSrcAddr;
577 priv->autoSrcAddr = !!*((u_int32_t *)msg->
data);
581 struct sockaddr_dl sa_dl;
582 struct epoch_tracker et;
583 struct ifmultiaddr *ifma;
589 bzero(&sa_dl,
sizeof(
struct sockaddr_dl));
590 sa_dl.sdl_len =
sizeof(
struct sockaddr_dl);
591 sa_dl.sdl_family = AF_LINK;
592 sa_dl.sdl_alen = ETHER_ADDR_LEN;
593 bcopy((
void *)msg->
data, LLADDR(&sa_dl),
603 ifma = if_findmulti(
priv->ifp,
604 (
struct sockaddr *)&sa_dl);
609 error = if_addmulti(
priv->ifp,
610 (
struct sockaddr *)&sa_dl, &ifma);
616 struct sockaddr_dl sa_dl;
622 bzero(&sa_dl,
sizeof(
struct sockaddr_dl));
623 sa_dl.sdl_len =
sizeof(
struct sockaddr_dl);
624 sa_dl.sdl_family = AF_LINK;
625 sa_dl.sdl_alen = ETHER_ADDR_LEN;
626 bcopy((
void *)msg->
data, LLADDR(&sa_dl),
628 error = if_delmulti(
priv->ifp,
629 (
struct sockaddr *)&sa_dl);
658 panic(
"%s: weird hook", __func__);
670 struct ifnet *
const ifp =
priv->ifp;
677 if (!((ifp->if_flags & IFF_UP) &&
678 (ifp->if_drv_flags & IFF_DRV_RUNNING))) {
684 if (m->m_pkthdr.len <
sizeof(
struct ether_header)) {
688 if (m->m_len <
sizeof(
struct ether_header)
689 && (m = m_pullup(m,
sizeof(
struct ether_header))) == NULL)
693 if (
priv->autoSrcAddr) {
696 && (m = m_pullup(m,
sizeof(
struct ether_header))) == NULL)
700 bcopy(IF_LLADDR(ifp),
701 mtod(m,
struct ether_header *)->ether_shost,
706 return ether_output_frame(ifp, m);
718 struct ifnet *ifp =
priv->ifp;
724 if (m->m_pkthdr.len <
sizeof(
struct ether_header)) {
728 if (m->m_len <
sizeof(
struct ether_header) &&
729 (m = m_pullup(m,
sizeof(
struct ether_header))) == NULL)
732 m->m_pkthdr.rcvif = ifp;
735 if (ifp->if_bridge) {
736 BRIDGE_INPUT(ifp, m);
761 if (
priv->ifp != NULL)
763 free(
priv, M_NETGRAPH);
768 (void)ifpromisc(
priv->ifp, 0);
786 if (
priv->ifp != NULL)
787 priv->ifp->if_hwassist =
priv->hwassist;
790 else if (hook ==
priv->orphan)
793 panic(
"%s: weird hook", __func__);
828 EVENTHANDLER_REGISTER(ifnet_arrival_event,
842 EVENTHANDLER_DEREGISTER(ifnet_arrival_event,
872 CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
873 if (ifp->if_type == IFT_ETHER ||
874 ifp->if_type == IFT_L2VLAN ||
875 ifp->if_type == IFT_BRIDGE)
#define NG_OUTBOUND_THREAD_UNREF()
#define NG_HOOK_NODE(hook)
#define NG_HOOK_SET_TO_INBOUND(hook)
#define NG_HOOK_HI_STACK(hook)
int ng_rcvmsg_t(node_p node, item_p item, hook_p lasthook)
int ng_disconnect_t(hook_p hook)
#define NG_NODE_SET_PRIVATE(node, val)
#define NG_RESPOND_MSG(error, here, item, resp)
#define NG_NODE_IS_VALID(node)
#define NG_NODE_UNREF(node)
int ng_rmnode_self(node_p here)
#define NG_OUTBOUND_THREAD_REF()
#define NG_SEND_DATA_ONLY(error, hook, m)
#define NG_NODE_REVIVE(node)
int ng_rcvdata_t(hook_p hook, item_p item)
#define NG_NODE_REALLY_DIE(node)
int ng_shutdown_t(node_p node)
#define NG_FREE_ITEM(item)
#define NG_HOOK_SET_RCVDATA(hook, val)
int ng_make_node_common(struct ng_type *typep, node_p *nodep)
int ng_name_node(node_p node, const char *name)
int ng_constructor_t(node_p node)
node_p ng_name2noderef(node_p node, const char *name)
#define NG_NODE_NUMHOOKS(node)
#define NGI_GET_MSG(i, m)
#define NG_NODE_PRIVATE(node)
#define NG_SEND_MSG_HOOK(error, here, msg, hook, retaddr)
int ng_newhook_t(node_p node, hook_p hook, const char *name)
static void ng_ether_input_orphan(struct ifnet *ifp, struct mbuf *m)
static void ng_ether_attach(struct ifnet *ifp)
static ng_rcvmsg_t ng_ether_rcvmsg
static int ng_ether_rcv_upper(hook_p node, item_p item)
static void vnet_ng_ether_init(const void *unused)
static struct ng_type ng_ether_typestruct
static int ng_ether_mod_event(module_t mod, int event, void *data)
VNET_SYSINIT(vnet_ng_ether_init, SI_SUB_PSEUDO, SI_ORDER_ANY, vnet_ng_ether_init, NULL)
static void ng_ether_input(struct ifnet *ifp, struct mbuf **mp)
static void ng_ether_detach(struct ifnet *ifp)
void(* ng_ether_attach_p)(struct ifnet *ifp)
NETGRAPH_INIT(ether, &ng_ether_typestruct)
static ng_newhook_t ng_ether_newhook
static void ng_ether_link_state(struct ifnet *ifp, int state)
static const struct ng_cmdlist ng_ether_cmdlist[]
void(* ng_ether_link_state_p)(struct ifnet *ifp, int state)
static ng_constructor_t ng_ether_constructor
static ng_shutdown_t ng_ether_shutdown
static void ng_ether_ifnet_arrival_event(void *arg __unused, struct ifnet *ifp)
static void ng_ether_sanitize_ifname(const char *ifname, char *name)
void(* ng_ether_input_p)(struct ifnet *ifp, struct mbuf **mp)
void(* ng_ether_input_orphan_p)(struct ifnet *ifp, struct mbuf *m)
MODULE_VERSION(ng_ether, 1)
static eventhandler_tag ng_ether_ifnet_arrival_cookie
static ng_rcvdata_t ng_ether_rcvdata
void(* ng_ether_detach_p)(struct ifnet *ifp)
static int ng_ether_output(struct ifnet *ifp, struct mbuf **mp)
static ng_disconnect_t ng_ether_disconnect
int(* ng_ether_output_p)(struct ifnet *ifp, struct mbuf **mp)
static int ng_ether_rcv_lower(hook_p node, item_p item)
#define NG_ETHER_HOOK_DIVERT
#define NG_ETHER_HOOK_ORPHAN
#define NG_ETHER_NODE_TYPE
#define NG_ETHER_HOOK_UPPER
#define NG_ETHER_HOOK_LOWER
#define NG_MKRESPONSE(rsp, msg, len, how)
#define NG_MKMESSAGE(msg, cookie, cmdid, len, how)
const struct ng_parse_type ng_parse_int32_type
const struct ng_parse_type ng_parse_enaddr_type
const struct ng_parse_type ng_parse_string_type
struct ng_mesg::ng_msghdr header