69#include <sys/eventhandler.h>
70#include <sys/kernel.h>
72#include <sys/malloc.h>
76#include <sys/socket.h>
79#include <net/if_var.h>
86#include <netinet6/ip6_var.h>
90 "Export host address structure");
114static struct encaptab_head ipv4_encaptab = CK_LIST_HEAD_INITIALIZER();
115static struct srcaddrtab_head
ipv4_srcaddrtab = CK_LIST_HEAD_INITIALIZER();
118static struct encaptab_head ipv6_encaptab = CK_LIST_HEAD_INITIALIZER();
119static struct srcaddrtab_head ipv6_srcaddrtab = CK_LIST_HEAD_INITIALIZER();
125#define ENCAP_WLOCK() mtx_lock(&encapmtx)
126#define ENCAP_WUNLOCK() mtx_unlock(&encapmtx)
127#define ENCAP_RLOCK_TRACKER struct epoch_tracker encap_et
128#define ENCAP_RLOCK() NET_EPOCH_ENTER(encap_et)
129#define ENCAP_RUNLOCK() NET_EPOCH_EXIT(encap_et)
130#define ENCAP_WAIT() NET_EPOCH_WAIT()
132#define SRCADDR_WLOCK() mtx_lock(&srcaddrmtx)
133#define SRCADDR_WUNLOCK() mtx_unlock(&srcaddrmtx)
134#define SRCADDR_RLOCK_TRACKER struct epoch_tracker srcaddr_et
135#define SRCADDR_RLOCK() \
136 epoch_enter_preempt(net_epoch_preempt, &srcaddr_et)
137#define SRCADDR_RUNLOCK() \
138 epoch_exit_preempt(net_epoch_preempt, &srcaddr_et)
139#define SRCADDR_WAIT() epoch_wait_preempt(net_epoch_preempt)
152 struct ifaddr *ifa,
int event)
155 struct srcaddrtab_head *head;
159 EVENTHANDLER_INVOKE(ifaddr_event, ifp);
161 switch (ifa->ifa_addr->sa_family) {
169 head = &ipv6_srcaddrtab;
178 CK_LIST_FOREACH(p, head, chain) {
179 (*p->srcaddr)(p->arg, ifa->ifa_addr, event);
187 void *arg,
int mflags)
193 p = malloc(
sizeof(*p), M_NETADDR, mflags);
200 CK_LIST_FOREACH(tmp, head, chain) {
201 if (func == tmp->srcaddr && arg == tmp->arg)
205 CK_LIST_INSERT_HEAD(head, p, chain);
222 CK_LIST_FOREACH(p, head, chain) {
224 CK_LIST_REMOVE(p, chain);
237 void *arg,
int mflags)
241 if (cfg == NULL || cfg->
input == NULL ||
247 ep = malloc(
sizeof(*ep), M_NETADDR, mflags);
251 ep->proto = cfg->
proto;
257 ep->input = cfg->
input;
260 CK_LIST_FOREACH(tmp, head, chain) {
261 if (tmp->exact_match <= ep->exact_match)
265 CK_LIST_INSERT_HEAD(head, ep, chain);
267 CK_LIST_INSERT_BEFORE(tmp, ep, chain);
278 CK_LIST_FOREACH(ep, head, chain) {
280 CK_LIST_REMOVE(ep, chain);
292encap_input(
struct encaptab_head *head,
struct mbuf *m,
int off,
int proto)
303 CK_LIST_FOREACH(ep, head, chain) {
304 if (ep->proto >= 0 && ep->proto != proto)
306 if (ep->min_length > m->m_pkthdr.len)
309 ret = (*ep->lookup)(m, off, proto, &arg);
311 ret = (*ep->check)(m, off, proto, ep->arg);
314 if (ret > matchprio) {
322 if (ret >= ep->exact_match)
330 ret = (*match->input)(m, off, proto, arg);
332 MPASS(ret == IPPROTO_DONE);
333 return (IPPROTO_DONE);
358 return (
encap_attach(&ipv4_encaptab, cfg, arg, mflags));
372 if (
encap_input(&ipv4_encaptab, *mp, *offp, proto) != IPPROTO_DONE)
374 return (IPPROTO_DONE);
397 return (
encap_attach(&ipv6_encaptab, cfg, arg, mflags));
411 if (
encap_input(&ipv6_encaptab, *mp, *offp, proto) != IPPROTO_DONE)
412 return (rip6_input(mp, offp, proto));
413 return (IPPROTO_DONE);
const struct encaptab * cookie
static const struct srcaddrtab * ipv4_srcaddrtab
static MALLOC_DEFINE(M_NETADDR, "encap_export_host", "Export host address structure")
static int encap_unregister_srcaddr(struct srcaddrtab_head *head, const struct srcaddrtab *cookie)
EVENTHANDLER_DEFINE(ifaddr_event_ext, srcaddr_change_event, NULL, 0)
static struct srcaddrtab * encap_register_srcaddr(struct srcaddrtab_head *head, encap_srcaddr_t func, void *arg, int mflags)
static struct mtx encapmtx srcaddrmtx
#define ENCAP_RLOCK_TRACKER
static int encap_input(struct encaptab_head *head, struct mbuf *m, int off, int proto)
static void srcaddr_change_event(void *arg __unused, struct ifnet *ifp, struct ifaddr *ifa, int event)
MTX_SYSINIT(encapmtx, &encapmtx, "encapmtx", MTX_DEF)
static struct encaptab * encap_attach(struct encaptab_head *head, const struct encap_config *cfg, void *arg, int mflags)
CK_LIST_HEAD(encaptab_head, encaptab)
#define SRCADDR_WUNLOCK()
#define SRCADDR_RLOCK_TRACKER
static int encap_detach(struct encaptab_head *head, const struct encaptab *cookie)
#define SRCADDR_RUNLOCK()
const struct encaptab * ip6_encap_attach(const struct encap_config *, void *arg, int mflags)
int ip6_encap_detach(const struct encaptab *)
int encap4_input(struct mbuf **, int *, int)
int(* encap_input_t)(struct mbuf *, int, int, void *)
int ip_encap_detach(const struct encaptab *)
void(* encap_srcaddr_t)(void *, const struct sockaddr *, int)
int encap6_input(struct mbuf **, int *, int)
int ip_encap_unregister_srcaddr(const struct srcaddrtab *)
int(* encap_check_t)(const struct mbuf *, int, int, void *)
const struct encaptab * ip_encap_attach(const struct encap_config *, void *arg, int mflags)
const struct srcaddrtab * ip6_encap_register_srcaddr(encap_srcaddr_t, void *arg, int mflags)
int ip6_encap_unregister_srcaddr(const struct srcaddrtab *)
int(* encap_lookup_t)(const struct mbuf *, int, int, void **)
const struct srcaddrtab * ip_encap_register_srcaddr(encap_srcaddr_t, void *arg, int mflags)
int rip_input(struct mbuf **, int *, int)