Changeset View
Changeset View
Standalone View
Standalone View
sys/netpfil/pf/pf_ioctl.c
Show First 20 Lines • Show All 3,867 Lines • ▼ Show 20 Lines | case DIOCRDELTABLES: { | ||||
PF_RULES_WUNLOCK(); | PF_RULES_WUNLOCK(); | ||||
free(pfrts, M_TEMP); | free(pfrts, M_TEMP); | ||||
break; | break; | ||||
} | } | ||||
case DIOCRGETTABLES: { | case DIOCRGETTABLES: { | ||||
struct pfioc_table *io = (struct pfioc_table *)addr; | struct pfioc_table *io = (struct pfioc_table *)addr; | ||||
struct pfr_table *pfrts; | struct pfr_table *pfrts; | ||||
size_t totlen; | |||||
int n; | int n; | ||||
if (io->pfrio_esize != sizeof(struct pfr_table)) { | if (io->pfrio_esize != sizeof(struct pfr_table)) { | ||||
error = ENODEV; | error = ENODEV; | ||||
break; | break; | ||||
} | } | ||||
PF_RULES_RLOCK(); | PF_RULES_RLOCK(); | ||||
n = pfr_table_count(&io->pfrio_table, io->pfrio_flags); | n = pfr_table_count(&io->pfrio_table, io->pfrio_flags); | ||||
if (n < 0) { | if (n < 0) { | ||||
PF_RULES_RUNLOCK(); | PF_RULES_RUNLOCK(); | ||||
error = EINVAL; | error = EINVAL; | ||||
break; | break; | ||||
} | } | ||||
io->pfrio_size = min(io->pfrio_size, n); | io->pfrio_size = min(io->pfrio_size, n); | ||||
totlen = io->pfrio_size * sizeof(struct pfr_table); | |||||
pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table), | pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table), | ||||
M_TEMP, M_NOWAIT); | M_TEMP, M_NOWAIT); | ||||
if (pfrts == NULL) { | if (pfrts == NULL) { | ||||
error = ENOMEM; | error = ENOMEM; | ||||
PF_RULES_RUNLOCK(); | PF_RULES_RUNLOCK(); | ||||
break; | break; | ||||
} | } | ||||
error = pfr_get_tables(&io->pfrio_table, pfrts, | error = pfr_get_tables(&io->pfrio_table, pfrts, | ||||
&io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); | &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); | ||||
PF_RULES_RUNLOCK(); | PF_RULES_RUNLOCK(); | ||||
if (error == 0) | if (error == 0) { | ||||
error = copyout(pfrts, io->pfrio_buffer, totlen); | error = copyout(pfrts, io->pfrio_buffer, | ||||
io->pfrio_size * sizeof(struct pfr_table)); | |||||
} | |||||
free(pfrts, M_TEMP); | free(pfrts, M_TEMP); | ||||
break; | break; | ||||
} | } | ||||
case DIOCRGETTSTATS: { | case DIOCRGETTSTATS: { | ||||
struct pfioc_table *io = (struct pfioc_table *)addr; | struct pfioc_table *io = (struct pfioc_table *)addr; | ||||
struct pfr_tstats *pfrtstats; | struct pfr_tstats *pfrtstats; | ||||
size_t totlen; | |||||
int n; | int n; | ||||
if (io->pfrio_esize != sizeof(struct pfr_tstats)) { | if (io->pfrio_esize != sizeof(struct pfr_tstats)) { | ||||
error = ENODEV; | error = ENODEV; | ||||
break; | break; | ||||
} | } | ||||
PF_TABLE_STATS_LOCK(); | PF_TABLE_STATS_LOCK(); | ||||
PF_RULES_RLOCK(); | PF_RULES_RLOCK(); | ||||
n = pfr_table_count(&io->pfrio_table, io->pfrio_flags); | n = pfr_table_count(&io->pfrio_table, io->pfrio_flags); | ||||
if (n < 0) { | if (n < 0) { | ||||
PF_RULES_RUNLOCK(); | PF_RULES_RUNLOCK(); | ||||
PF_TABLE_STATS_UNLOCK(); | PF_TABLE_STATS_UNLOCK(); | ||||
error = EINVAL; | error = EINVAL; | ||||
break; | break; | ||||
} | } | ||||
io->pfrio_size = min(io->pfrio_size, n); | io->pfrio_size = min(io->pfrio_size, n); | ||||
totlen = io->pfrio_size * sizeof(struct pfr_tstats); | |||||
pfrtstats = mallocarray(io->pfrio_size, | pfrtstats = mallocarray(io->pfrio_size, | ||||
sizeof(struct pfr_tstats), M_TEMP, M_NOWAIT); | sizeof(struct pfr_tstats), M_TEMP, M_NOWAIT); | ||||
if (pfrtstats == NULL) { | if (pfrtstats == NULL) { | ||||
error = ENOMEM; | error = ENOMEM; | ||||
PF_RULES_RUNLOCK(); | PF_RULES_RUNLOCK(); | ||||
PF_TABLE_STATS_UNLOCK(); | PF_TABLE_STATS_UNLOCK(); | ||||
break; | break; | ||||
} | } | ||||
error = pfr_get_tstats(&io->pfrio_table, pfrtstats, | error = pfr_get_tstats(&io->pfrio_table, pfrtstats, | ||||
&io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); | &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); | ||||
PF_RULES_RUNLOCK(); | PF_RULES_RUNLOCK(); | ||||
PF_TABLE_STATS_UNLOCK(); | PF_TABLE_STATS_UNLOCK(); | ||||
if (error == 0) | if (error == 0) { | ||||
error = copyout(pfrtstats, io->pfrio_buffer, totlen); | error = copyout(pfrtstats, io->pfrio_buffer, | ||||
io->pfrio_size * sizeof(struct pfr_tstats)); | |||||
} | |||||
free(pfrtstats, M_TEMP); | free(pfrtstats, M_TEMP); | ||||
break; | break; | ||||
} | } | ||||
case DIOCRCLRTSTATS: { | case DIOCRCLRTSTATS: { | ||||
struct pfioc_table *io = (struct pfioc_table *)addr; | struct pfioc_table *io = (struct pfioc_table *)addr; | ||||
struct pfr_table *pfrts; | struct pfr_table *pfrts; | ||||
size_t totlen; | size_t totlen; | ||||
▲ Show 20 Lines • Show All 189 Lines • ▼ Show 20 Lines | if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK) | ||||
error = copyout(pfras, io->pfrio_buffer, totlen); | error = copyout(pfras, io->pfrio_buffer, totlen); | ||||
free(pfras, M_TEMP); | free(pfras, M_TEMP); | ||||
break; | break; | ||||
} | } | ||||
case DIOCRGETADDRS: { | case DIOCRGETADDRS: { | ||||
struct pfioc_table *io = (struct pfioc_table *)addr; | struct pfioc_table *io = (struct pfioc_table *)addr; | ||||
struct pfr_addr *pfras; | struct pfr_addr *pfras; | ||||
size_t totlen; | |||||
if (io->pfrio_esize != sizeof(struct pfr_addr)) { | if (io->pfrio_esize != sizeof(struct pfr_addr)) { | ||||
error = ENODEV; | error = ENODEV; | ||||
break; | break; | ||||
} | } | ||||
if (io->pfrio_size < 0 || | if (io->pfrio_size < 0 || | ||||
io->pfrio_size > pf_ioctl_maxcount || | io->pfrio_size > pf_ioctl_maxcount || | ||||
WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) { | WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) { | ||||
error = EINVAL; | error = EINVAL; | ||||
break; | break; | ||||
} | } | ||||
totlen = io->pfrio_size * sizeof(struct pfr_addr); | |||||
pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr), | pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr), | ||||
M_TEMP, M_WAITOK); | M_TEMP, M_WAITOK); | ||||
PF_RULES_RLOCK(); | PF_RULES_RLOCK(); | ||||
error = pfr_get_addrs(&io->pfrio_table, pfras, | error = pfr_get_addrs(&io->pfrio_table, pfras, | ||||
&io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); | &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); | ||||
PF_RULES_RUNLOCK(); | PF_RULES_RUNLOCK(); | ||||
if (error == 0) | if (error == 0) { | ||||
error = copyout(pfras, io->pfrio_buffer, totlen); | error = copyout(pfras, io->pfrio_buffer, | ||||
io->pfrio_size * sizeof(struct pfr_addr)); | |||||
} | |||||
free(pfras, M_TEMP); | free(pfras, M_TEMP); | ||||
break; | break; | ||||
} | } | ||||
case DIOCRGETASTATS: { | case DIOCRGETASTATS: { | ||||
struct pfioc_table *io = (struct pfioc_table *)addr; | struct pfioc_table *io = (struct pfioc_table *)addr; | ||||
struct pfr_astats *pfrastats; | struct pfr_astats *pfrastats; | ||||
size_t totlen; | |||||
if (io->pfrio_esize != sizeof(struct pfr_astats)) { | if (io->pfrio_esize != sizeof(struct pfr_astats)) { | ||||
error = ENODEV; | error = ENODEV; | ||||
break; | break; | ||||
} | } | ||||
if (io->pfrio_size < 0 || | if (io->pfrio_size < 0 || | ||||
io->pfrio_size > pf_ioctl_maxcount || | io->pfrio_size > pf_ioctl_maxcount || | ||||
WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_astats))) { | WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_astats))) { | ||||
error = EINVAL; | error = EINVAL; | ||||
break; | break; | ||||
} | } | ||||
totlen = io->pfrio_size * sizeof(struct pfr_astats); | |||||
pfrastats = mallocarray(io->pfrio_size, | pfrastats = mallocarray(io->pfrio_size, | ||||
sizeof(struct pfr_astats), M_TEMP, M_WAITOK); | sizeof(struct pfr_astats), M_TEMP, M_WAITOK); | ||||
PF_RULES_RLOCK(); | PF_RULES_RLOCK(); | ||||
error = pfr_get_astats(&io->pfrio_table, pfrastats, | error = pfr_get_astats(&io->pfrio_table, pfrastats, | ||||
&io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); | &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL); | ||||
PF_RULES_RUNLOCK(); | PF_RULES_RUNLOCK(); | ||||
if (error == 0) | if (error == 0) { | ||||
error = copyout(pfrastats, io->pfrio_buffer, totlen); | error = copyout(pfrastats, io->pfrio_buffer, | ||||
io->pfrio_size * sizeof(struct pfr_astats)); | |||||
} | |||||
free(pfrastats, M_TEMP); | free(pfrastats, M_TEMP); | ||||
break; | break; | ||||
} | } | ||||
case DIOCRCLRASTATS: { | case DIOCRCLRASTATS: { | ||||
struct pfioc_table *io = (struct pfioc_table *)addr; | struct pfioc_table *io = (struct pfioc_table *)addr; | ||||
struct pfr_addr *pfras; | struct pfr_addr *pfras; | ||||
size_t totlen; | size_t totlen; | ||||
▲ Show 20 Lines • Show All 468 Lines • ▼ Show 20 Lines | case DIOCOSFPFLUSH: | ||||
PF_RULES_WLOCK(); | PF_RULES_WLOCK(); | ||||
pf_osfp_flush(); | pf_osfp_flush(); | ||||
PF_RULES_WUNLOCK(); | PF_RULES_WUNLOCK(); | ||||
break; | break; | ||||
case DIOCIGETIFACES: { | case DIOCIGETIFACES: { | ||||
struct pfioc_iface *io = (struct pfioc_iface *)addr; | struct pfioc_iface *io = (struct pfioc_iface *)addr; | ||||
struct pfi_kif *ifstore; | struct pfi_kif *ifstore; | ||||
size_t bufsiz; | |||||
if (io->pfiio_esize != sizeof(struct pfi_kif)) { | if (io->pfiio_esize != sizeof(struct pfi_kif)) { | ||||
error = ENODEV; | error = ENODEV; | ||||
break; | break; | ||||
} | } | ||||
if (io->pfiio_size < 0 || | if (io->pfiio_size < 0 || | ||||
io->pfiio_size > pf_ioctl_maxcount || | io->pfiio_size > pf_ioctl_maxcount || | ||||
WOULD_OVERFLOW(io->pfiio_size, sizeof(struct pfi_kif))) { | WOULD_OVERFLOW(io->pfiio_size, sizeof(struct pfi_kif))) { | ||||
error = EINVAL; | error = EINVAL; | ||||
break; | break; | ||||
} | } | ||||
bufsiz = io->pfiio_size * sizeof(struct pfi_kif); | |||||
ifstore = mallocarray(io->pfiio_size, sizeof(struct pfi_kif), | ifstore = mallocarray(io->pfiio_size, sizeof(struct pfi_kif), | ||||
M_TEMP, M_WAITOK); | M_TEMP, M_WAITOK); | ||||
PF_RULES_RLOCK(); | PF_RULES_RLOCK(); | ||||
pfi_get_ifaces(io->pfiio_name, ifstore, &io->pfiio_size); | pfi_get_ifaces(io->pfiio_name, ifstore, &io->pfiio_size); | ||||
PF_RULES_RUNLOCK(); | PF_RULES_RUNLOCK(); | ||||
error = copyout(ifstore, io->pfiio_buffer, bufsiz); | error = copyout(ifstore, io->pfiio_buffer, | ||||
io->pfiio_size * sizeof(struct pfi_kif)); | |||||
free(ifstore, M_TEMP); | free(ifstore, M_TEMP); | ||||
break; | break; | ||||
} | } | ||||
case DIOCSETIFFLAG: { | case DIOCSETIFFLAG: { | ||||
struct pfioc_iface *io = (struct pfioc_iface *)addr; | struct pfioc_iface *io = (struct pfioc_iface *)addr; | ||||
PF_RULES_WLOCK(); | PF_RULES_WLOCK(); | ||||
▲ Show 20 Lines • Show All 1,108 Lines • Show Last 20 Lines |