diff options
| author | Gleb Smirnoff <glebius@FreeBSD.org> | 2019-01-31 23:01:03 +0000 |
|---|---|---|
| committer | Gleb Smirnoff <glebius@FreeBSD.org> | 2019-01-31 23:01:03 +0000 |
| commit | b252313f0b3a4659c02e61d3a0bba471c89bcfa9 (patch) | |
| tree | 129539f21574fd57abdc128138912eeee023fc89 /sys/netinet | |
| parent | 90f2d5012a44f34fc23a7d1743336266960510b7 (diff) | |
Notes
Diffstat (limited to 'sys/netinet')
| -rw-r--r-- | sys/netinet/ip_fastfwd.c | 16 | ||||
| -rw-r--r-- | sys/netinet/ip_input.c | 25 | ||||
| -rw-r--r-- | sys/netinet/ip_output.c | 15 | ||||
| -rw-r--r-- | sys/netinet/ip_var.h | 5 | ||||
| -rw-r--r-- | sys/netinet/siftr.c | 70 |
5 files changed, 76 insertions, 55 deletions
diff --git a/sys/netinet/ip_fastfwd.c b/sys/netinet/ip_fastfwd.c index 643a75e2294b..77a08b1a8af1 100644 --- a/sys/netinet/ip_fastfwd.c +++ b/sys/netinet/ip_fastfwd.c @@ -90,11 +90,11 @@ __FBSDID("$FreeBSD$"); #include <sys/socket.h> #include <sys/sysctl.h> -#include <net/pfil.h> #include <net/if.h> #include <net/if_types.h> #include <net/if_var.h> #include <net/if_dl.h> +#include <net/pfil.h> #include <net/route.h> #include <net/vnet.h> @@ -228,12 +228,11 @@ ip_tryforward(struct mbuf *m) /* * Run through list of ipfilter hooks for input packets */ - if (!PFIL_HOOKED(&V_inet_pfil_hook)) + if (!PFIL_HOOKED_IN(V_inet_pfil_head)) goto passin; - if (pfil_run_hooks( - &V_inet_pfil_hook, &m, m->m_pkthdr.rcvif, PFIL_IN, 0, NULL) || - m == NULL) + if (pfil_run_hooks(V_inet_pfil_head, &m, m->m_pkthdr.rcvif, PFIL_IN, + NULL) != PFIL_PASS) goto drop; M_ASSERTVALID(m); @@ -321,13 +320,12 @@ passin: /* * Step 5: outgoing firewall packet processing */ - if (!PFIL_HOOKED(&V_inet_pfil_hook)) + if (!PFIL_HOOKED_OUT(V_inet_pfil_head)) goto passout; - if (pfil_run_hooks(&V_inet_pfil_hook, &m, nh.nh_ifp, PFIL_OUT, PFIL_FWD, - NULL) || m == NULL) { + if (pfil_run_hooks(V_inet_pfil_head, &m, nh.nh_ifp, + PFIL_OUT | PFIL_FWD, NULL) != PFIL_PASS) goto drop; - } M_ASSERTVALID(m); M_ASSERTPKTHDR(m); diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index dd00d13a4d71..a1ec5935a826 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -57,11 +57,11 @@ __FBSDID("$FreeBSD$"); #include <sys/syslog.h> #include <sys/sysctl.h> -#include <net/pfil.h> #include <net/if.h> #include <net/if_types.h> #include <net/if_var.h> #include <net/if_dl.h> +#include <net/pfil.h> #include <net/route.h> #include <net/netisr.h> #include <net/rss_config.h> @@ -134,7 +134,7 @@ SYSCTL_INT(_net_inet_ip, OID_AUTO, check_interface, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip_checkinterface), 0, "Verify packet arrives on correct interface"); -VNET_DEFINE(struct pfil_head, inet_pfil_hook); /* Packet filter hooks */ +VNET_DEFINE(pfil_head_t, inet_pfil_head); /* Packet filter hooks */ static struct netisr_handler ip_nh = { .nh_name = "ip", @@ -301,6 +301,7 @@ SYSCTL_PROC(_net_inet_ip, IPCTL_INTRDQDROPS, intr_direct_queue_drops, void ip_init(void) { + struct pfil_head_args args; struct protosw *pr; int i; @@ -311,11 +312,11 @@ ip_init(void) ipreass_init(); /* Initialize packet filter hooks. */ - V_inet_pfil_hook.ph_type = PFIL_TYPE_AF; - V_inet_pfil_hook.ph_af = AF_INET; - if ((i = pfil_head_register(&V_inet_pfil_hook)) != 0) - printf("%s: WARNING: unable to register pfil hook, " - "error %d\n", __func__, i); + args.pa_version = PFIL_VERSION; + args.pa_flags = PFIL_IN | PFIL_OUT; + args.pa_type = PFIL_TYPE_IP4; + args.pa_headname = PFIL_INET_NAME; + V_inet_pfil_head = pfil_head_register(&args); if (hhook_head_register(HHOOK_TYPE_IPSEC_IN, AF_INET, &V_ipsec_hhh_in[HHOOK_IPSEC_INET], @@ -377,10 +378,7 @@ ip_destroy(void *unused __unused) #endif netisr_unregister_vnet(&ip_nh); - if ((error = pfil_head_unregister(&V_inet_pfil_hook)) != 0) - printf("%s: WARNING: unable to unregister pfil hook, " - "error %d\n", __func__, error); - + pfil_head_unregister(V_inet_pfil_head); error = hhook_head_deregister(V_ipsec_hhh_in[HHOOK_IPSEC_INET]); if (error != 0) { printf("%s: WARNING: unable to deregister input helper hook " @@ -599,11 +597,12 @@ tooshort: */ /* Jump over all PFIL processing if hooks are not active. */ - if (!PFIL_HOOKED(&V_inet_pfil_hook)) + if (!PFIL_HOOKED_IN(V_inet_pfil_head)) goto passin; odst = ip->ip_dst; - if (pfil_run_hooks(&V_inet_pfil_hook, &m, ifp, PFIL_IN, 0, NULL) != 0) + if (pfil_run_hooks(V_inet_pfil_head, &m, ifp, PFIL_IN, NULL) != + PFIL_PASS) return; if (m == NULL) /* consumed by filter */ return; diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 7595c3f90535..0c7a26503d07 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -121,11 +121,16 @@ ip_output_pfil(struct mbuf **mp, struct ifnet *ifp, struct inpcb *inp, /* Run through list of hooks for output packets. */ odst.s_addr = ip->ip_dst.s_addr; - *error = pfil_run_hooks(&V_inet_pfil_hook, mp, ifp, PFIL_OUT, 0, inp); - m = *mp; - if ((*error) != 0 || m == NULL) + switch (pfil_run_hooks(V_inet_pfil_head, mp, ifp, PFIL_OUT, inp)) { + case PFIL_DROPPED: + *error = EPERM; + /* FALLTHROUGH */ + case PFIL_CONSUMED: return 1; /* Finished */ - + case PFIL_PASS: + *error = 0; + } + m = *mp; ip = mtod(m, struct ip *); /* See if destination IP address was changed by packet filter. */ @@ -568,7 +573,7 @@ sendit: #endif /* IPSEC */ /* Jump over all PFIL processing if hooks are not active. */ - if (PFIL_HOOKED(&V_inet_pfil_hook)) { + if (PFIL_HOOKED_OUT(V_inet_pfil_head)) { switch (ip_output_pfil(&m, ifp, inp, dst, &fibnum, &error)) { case 1: /* Finished */ goto done; diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h index 86615a15ad26..d55a18bba91d 100644 --- a/sys/netinet/ip_var.h +++ b/sys/netinet/ip_var.h @@ -241,8 +241,9 @@ extern int (*ip_rsvp_vif)(struct socket *, struct sockopt *); extern void (*ip_rsvp_force_done)(struct socket *); extern int (*rsvp_input_p)(struct mbuf **, int *, int); -VNET_DECLARE(struct pfil_head, inet_pfil_hook); /* packet filter hooks */ -#define V_inet_pfil_hook VNET(inet_pfil_hook) +VNET_DECLARE(struct pfil_head *, inet_pfil_head); +#define V_inet_pfil_head VNET(inet_pfil_head) +#define PFIL_INET_NAME "inet" void in_delayed_cksum(struct mbuf *m); diff --git a/sys/netinet/siftr.c b/sys/netinet/siftr.c index 4d063c360386..68d8f8e16fa1 100644 --- a/sys/netinet/siftr.c +++ b/sys/netinet/siftr.c @@ -94,10 +94,12 @@ __FBSDID("$FreeBSD$"); #include <netinet/in_systm.h> #include <netinet/in_var.h> #include <netinet/ip.h> +#include <netinet/ip_var.h> #include <netinet/tcp_var.h> #ifdef SIFTR_IPV6 #include <netinet/ip6.h> +#include <netinet/ip6_var.h> #include <netinet6/in6_pcb.h> #endif /* SIFTR_IPV6 */ @@ -831,9 +833,9 @@ siftr_siftdata(struct pkt_node *pn, struct inpcb *inp, struct tcpcb *tp, * It's very important to use the M_NOWAIT flag with all function calls * that support it so that they won't sleep, otherwise you get a panic. */ -static int -siftr_chkpkt(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, - struct inpcb *inp) +static pfil_return_t +siftr_chkpkt(struct mbuf **m, struct ifnet *ifp, int flags, + void *ruleset __unused, struct inpcb *inp) { struct pkt_node *pn; struct ip *ip; @@ -841,9 +843,10 @@ siftr_chkpkt(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, struct tcpcb *tp; struct siftr_stats *ss; unsigned int ip_hl; - int inp_locally_locked; + int inp_locally_locked, dir; inp_locally_locked = 0; + dir = PFIL_DIR(flags); ss = DPCPU_PTR(ss); /* @@ -1007,15 +1010,13 @@ inp_unlock: INP_RUNLOCK(inp); ret: - /* Returning 0 ensures pfil will not discard the pkt */ - return (0); + return (PFIL_PASS); } #ifdef SIFTR_IPV6 static int -siftr_chkpkt6(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, - struct inpcb *inp) +siftr_chkpkt6(struct mbuf **m, struct ifnet *ifp, int flags, struct inpcb *inp) { struct pkt_node *pn; struct ip6_hdr *ip6; @@ -1023,9 +1024,10 @@ siftr_chkpkt6(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, struct tcpcb *tp; struct siftr_stats *ss; unsigned int ip6_hl; - int inp_locally_locked; + int inp_locally_locked, dir; inp_locally_locked = 0; + dir = PFIL_DIR(flags); ss = DPCPU_PTR(ss); /* @@ -1138,37 +1140,53 @@ ret6: } #endif /* #ifdef SIFTR_IPV6 */ - +VNET_DEFINE_STATIC(pfil_hook_t, siftr_inet_hook); +#define V_siftr_inet_hook VNET(siftr_inet_hook) +#ifdef INET6 +VNET_DEFINE_STATIC(pfil_hook_t, siftr_inet6_hook); +#define V_siftr_inet6_hook VNET(siftr_inet6_hook) +#endif static int siftr_pfil(int action) { - struct pfil_head *pfh_inet; -#ifdef SIFTR_IPV6 - struct pfil_head *pfh_inet6; -#endif + struct pfil_hook_args pha; + struct pfil_link_args pla; + + pha.pa_version = PFIL_VERSION; + pha.pa_flags = PFIL_IN | PFIL_OUT; + pha.pa_modname = "siftr"; + pha.pa_ruleset = NULL; + pha.pa_rulname = "default"; + + pla.pa_version = PFIL_VERSION; + pla.pa_flags = PFIL_IN | PFIL_OUT | + PFIL_HEADPTR | PFIL_HOOKPTR; + VNET_ITERATOR_DECL(vnet_iter); VNET_LIST_RLOCK(); VNET_FOREACH(vnet_iter) { CURVNET_SET(vnet_iter); - pfh_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET); -#ifdef SIFTR_IPV6 - pfh_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6); -#endif if (action == HOOK) { - pfil_add_hook(siftr_chkpkt, NULL, - PFIL_IN | PFIL_OUT | PFIL_WAITOK, pfh_inet); + pha.pa_func = siftr_chkpkt; + pha.pa_type = PFIL_TYPE_IP4; + V_siftr_inet_hook = pfil_add_hook(&pha); + pla.pa_hook = V_siftr_inet_hook; + pla.pa_head = V_inet_pfil_head; + (void)pfil_link(&pla); #ifdef SIFTR_IPV6 - pfil_add_hook(siftr_chkpkt6, NULL, - PFIL_IN | PFIL_OUT | PFIL_WAITOK, pfh_inet6); + pha.pa_func = siftr_chkpkt6; + pha.pa_type = PFIL_TYPE_IP6; + V_siftr_inet6_hook = pfil_add_hook(&pha); + pla.pa_hook = V_siftr_inet6_hook; + pla.pa_head = V_inet6_pfil_head; + (void)pfil_link(&pla); #endif } else if (action == UNHOOK) { - pfil_remove_hook(siftr_chkpkt, NULL, - PFIL_IN | PFIL_OUT | PFIL_WAITOK, pfh_inet); + pfil_remove_hook(V_siftr_inet_hook); #ifdef SIFTR_IPV6 - pfil_remove_hook(siftr_chkpkt6, NULL, - PFIL_IN | PFIL_OUT | PFIL_WAITOK, pfh_inet6); + pfil_remove_hook(V_siftr_inet6_hook); #endif } CURVNET_RESTORE(); |
