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