Lines 59-69
Link Here
|
59 |
#include <sys/systm.h> |
59 |
#include <sys/systm.h> |
60 |
#include <sys/errno.h> |
60 |
#include <sys/errno.h> |
61 |
#include <sys/kernel.h> |
61 |
#include <sys/kernel.h> |
|
|
62 |
#include <sys/lock.h> |
62 |
#include <sys/malloc.h> |
63 |
#include <sys/malloc.h> |
63 |
#include <sys/mbuf.h> |
64 |
#include <sys/mbuf.h> |
64 |
#include <sys/errno.h> |
65 |
#include <sys/errno.h> |
65 |
#include <sys/proc.h> |
66 |
#include <sys/proc.h> |
66 |
#include <sys/random.h> |
67 |
#include <sys/random.h> |
|
|
68 |
#include <sys/rmlock.h> |
67 |
#include <sys/sockio.h> |
69 |
#include <sys/sockio.h> |
68 |
#include <sys/socket.h> |
70 |
#include <sys/socket.h> |
69 |
#include <sys/syslog.h> |
71 |
#include <sys/syslog.h> |
Lines 112-120
struct ng_iface_private {
Link Here
|
112 |
int unit; /* Interface unit number */ |
114 |
int unit; /* Interface unit number */ |
113 |
node_p node; /* Our netgraph node */ |
115 |
node_p node; /* Our netgraph node */ |
114 |
hook_p hooks[NUM_FAMILIES]; /* Hook for each address family */ |
116 |
hook_p hooks[NUM_FAMILIES]; /* Hook for each address family */ |
|
|
117 |
struct rmlock lock; /* Protect private data changes */ |
115 |
}; |
118 |
}; |
116 |
typedef struct ng_iface_private *priv_p; |
119 |
typedef struct ng_iface_private *priv_p; |
117 |
|
120 |
|
|
|
121 |
#define PRIV_RLOCK(priv, t) rm_rlock(&priv->lock, t) |
122 |
#define PRIV_RUNLOCK(priv, t) rm_runlock(&priv->lock, t) |
123 |
#define PRIV_WLOCK(priv) rm_wlock(&priv->lock) |
124 |
#define PRIV_WUNLOCK(priv) rm_wunlock(&priv->lock) |
125 |
|
118 |
/* Interface methods */ |
126 |
/* Interface methods */ |
119 |
static void ng_iface_start(struct ifnet *ifp); |
127 |
static void ng_iface_start(struct ifnet *ifp); |
120 |
static int ng_iface_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data); |
128 |
static int ng_iface_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data); |
Lines 134-139
static ng_constructor_t ng_iface_constru
Link Here
|
134 |
static ng_rcvmsg_t ng_iface_rcvmsg; |
142 |
static ng_rcvmsg_t ng_iface_rcvmsg; |
135 |
static ng_shutdown_t ng_iface_shutdown; |
143 |
static ng_shutdown_t ng_iface_shutdown; |
136 |
static ng_newhook_t ng_iface_newhook; |
144 |
static ng_newhook_t ng_iface_newhook; |
|
|
145 |
static ng_findhook_t ng_iface_findhook; |
137 |
static ng_rcvdata_t ng_iface_rcvdata; |
146 |
static ng_rcvdata_t ng_iface_rcvdata; |
138 |
static ng_disconnect_t ng_iface_disconnect; |
147 |
static ng_disconnect_t ng_iface_disconnect; |
139 |
|
148 |
|
Lines 185-190
static struct ng_type typestruct = {
Link Here
|
185 |
.rcvmsg = ng_iface_rcvmsg, |
194 |
.rcvmsg = ng_iface_rcvmsg, |
186 |
.shutdown = ng_iface_shutdown, |
195 |
.shutdown = ng_iface_shutdown, |
187 |
.newhook = ng_iface_newhook, |
196 |
.newhook = ng_iface_newhook, |
|
|
197 |
.findhook = ng_iface_findhook, |
188 |
.rcvdata = ng_iface_rcvdata, |
198 |
.rcvdata = ng_iface_rcvdata, |
189 |
.disconnect = ng_iface_disconnect, |
199 |
.disconnect = ng_iface_disconnect, |
190 |
.cmdlist = ng_iface_cmds, |
200 |
.cmdlist = ng_iface_cmds, |
Lines 431-436
ng_iface_bpftap(struct ifnet *ifp, struc
Link Here
|
431 |
static int |
441 |
static int |
432 |
ng_iface_send(struct ifnet *ifp, struct mbuf *m, sa_family_t sa) |
442 |
ng_iface_send(struct ifnet *ifp, struct mbuf *m, sa_family_t sa) |
433 |
{ |
443 |
{ |
|
|
444 |
struct rm_priotracker priv_tracker; |
434 |
const priv_p priv = (priv_p) ifp->if_softc; |
445 |
const priv_p priv = (priv_p) ifp->if_softc; |
435 |
const iffam_p iffam = get_iffam_from_af(sa); |
446 |
const iffam_p iffam = get_iffam_from_af(sa); |
436 |
int error; |
447 |
int error; |
Lines 448-454
ng_iface_send(struct ifnet *ifp, struct
Link Here
|
448 |
|
459 |
|
449 |
/* Send packet. If hook is not connected, mbuf will get freed. */ |
460 |
/* Send packet. If hook is not connected, mbuf will get freed. */ |
450 |
NG_OUTBOUND_THREAD_REF(); |
461 |
NG_OUTBOUND_THREAD_REF(); |
|
|
462 |
PRIV_RLOCK(priv, &priv_tracker); |
451 |
NG_SEND_DATA_ONLY(error, *get_hook_from_iffam(priv, iffam), m); |
463 |
NG_SEND_DATA_ONLY(error, *get_hook_from_iffam(priv, iffam), m); |
|
|
464 |
PRIV_RUNLOCK(priv, &priv_tracker); |
452 |
NG_OUTBOUND_THREAD_UNREF(); |
465 |
NG_OUTBOUND_THREAD_UNREF(); |
453 |
|
466 |
|
454 |
/* Update stats. */ |
467 |
/* Update stats. */ |
Lines 516-521
ng_iface_constructor(node_p node)
Link Here
|
516 |
return (ENOMEM); |
529 |
return (ENOMEM); |
517 |
} |
530 |
} |
518 |
|
531 |
|
|
|
532 |
rm_init(&priv->lock, "ng_iface private rmlock"); |
533 |
|
519 |
/* Link them together */ |
534 |
/* Link them together */ |
520 |
ifp->if_softc = priv; |
535 |
ifp->if_softc = priv; |
521 |
priv->ifp = ifp; |
536 |
priv->ifp = ifp; |
Lines 562-580
static int
Link Here
|
562 |
ng_iface_newhook(node_p node, hook_p hook, const char *name) |
577 |
ng_iface_newhook(node_p node, hook_p hook, const char *name) |
563 |
{ |
578 |
{ |
564 |
const iffam_p iffam = get_iffam_from_name(name); |
579 |
const iffam_p iffam = get_iffam_from_name(name); |
|
|
580 |
const priv_p priv = NG_NODE_PRIVATE(node); |
565 |
hook_p *hookptr; |
581 |
hook_p *hookptr; |
566 |
|
582 |
|
567 |
if (iffam == NULL) |
583 |
if (iffam == NULL) |
568 |
return (EPFNOSUPPORT); |
584 |
return (EPFNOSUPPORT); |
569 |
hookptr = get_hook_from_iffam(NG_NODE_PRIVATE(node), iffam); |
585 |
PRIV_WLOCK(priv); |
570 |
if (*hookptr != NULL) |
586 |
hookptr = get_hook_from_iffam(priv, iffam); |
|
|
587 |
if (*hookptr != NULL) { |
588 |
PRIV_WUNLOCK(priv); |
571 |
return (EISCONN); |
589 |
return (EISCONN); |
|
|
590 |
} |
572 |
*hookptr = hook; |
591 |
*hookptr = hook; |
573 |
NG_HOOK_HI_STACK(hook); |
592 |
NG_HOOK_HI_STACK(hook); |
574 |
NG_HOOK_SET_TO_INBOUND(hook); |
593 |
NG_HOOK_SET_TO_INBOUND(hook); |
|
|
594 |
PRIV_WUNLOCK(priv); |
575 |
return (0); |
595 |
return (0); |
576 |
} |
596 |
} |
577 |
|
597 |
|
|
|
598 |
/* Look up hook by name */ |
599 |
static hook_p |
600 |
ng_iface_findhook(node_p node, const char *name) |
601 |
{ |
602 |
struct rm_priotracker priv_tracker; |
603 |
const iffam_p iffam = get_iffam_from_name(name); |
604 |
const priv_p priv = NG_NODE_PRIVATE(node); |
605 |
hook_p *hookptr; |
606 |
|
607 |
if (iffam == NULL) |
608 |
return (NULL); |
609 |
PRIV_RLOCK(priv, &priv_tracker); |
610 |
hookptr = get_hook_from_iffam(priv, iffam); |
611 |
if (*hookptr && NG_HOOK_IS_VALID(*hookptr)) { |
612 |
PRIV_RUNLOCK(priv, &priv_tracker); |
613 |
return (*hookptr); |
614 |
} |
615 |
PRIV_RUNLOCK(priv, &priv_tracker); |
616 |
return (NULL); |
617 |
} |
618 |
|
578 |
/* |
619 |
/* |
579 |
* Receive a control message |
620 |
* Receive a control message |
580 |
*/ |
621 |
*/ |
Lines 730-735
ng_iface_shutdown(node_p node)
Link Here
|
730 |
CURVNET_RESTORE(); |
771 |
CURVNET_RESTORE(); |
731 |
priv->ifp = NULL; |
772 |
priv->ifp = NULL; |
732 |
free_unr(V_ng_iface_unit, priv->unit); |
773 |
free_unr(V_ng_iface_unit, priv->unit); |
|
|
774 |
rm_destroy(&priv->lock); |
733 |
free(priv, M_NETGRAPH_IFACE); |
775 |
free(priv, M_NETGRAPH_IFACE); |
734 |
NG_NODE_SET_PRIVATE(node, NULL); |
776 |
NG_NODE_SET_PRIVATE(node, NULL); |
735 |
NG_NODE_UNREF(node); |
777 |
NG_NODE_UNREF(node); |
Lines 748-754
ng_iface_disconnect(hook_p hook)
Link Here
|
748 |
|
790 |
|
749 |
if (iffam == NULL) |
791 |
if (iffam == NULL) |
750 |
panic("%s", __func__); |
792 |
panic("%s", __func__); |
|
|
793 |
PRIV_WLOCK(priv); |
751 |
*get_hook_from_iffam(priv, iffam) = NULL; |
794 |
*get_hook_from_iffam(priv, iffam) = NULL; |
|
|
795 |
PRIV_WUNLOCK(priv); |
752 |
return (0); |
796 |
return (0); |
753 |
} |
797 |
} |
754 |
|
798 |
|