diff options
Diffstat (limited to 'sys/netpfil/pf/pf_ioctl.c')
-rw-r--r-- | sys/netpfil/pf/pf_ioctl.c | 84 |
1 files changed, 79 insertions, 5 deletions
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index e90a8fa..b00952c 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -1004,6 +1004,8 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td case DIOCCLRRULECTRS: case DIOCGETLIMIT: case DIOCGETALTQS: + case DIOCGETNAMEDALTQ: + case DIOCGETNAMEDTAG: case DIOCGETALTQ: case DIOCGETQSTATS: case DIOCGETRULESETS: @@ -1050,6 +1052,8 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td case DIOCGETTIMEOUT: case DIOCGETLIMIT: case DIOCGETALTQS: + case DIOCGETNAMEDALTQ: + case DIOCGETNAMEDTAG: case DIOCGETALTQ: case DIOCGETQSTATS: case DIOCGETRULESETS: @@ -1164,7 +1168,9 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td rule->states_cur = counter_u64_alloc(M_WAITOK); rule->states_tot = counter_u64_alloc(M_WAITOK); rule->src_nodes = counter_u64_alloc(M_WAITOK); +#ifdef PF_USER_INFO rule->cuid = td->td_ucred->cr_ruid; +#endif rule->cpid = td->td_proc ? td->td_proc->p_pid : 0; TAILQ_INIT(&rule->rpool.list); @@ -1190,7 +1196,6 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td V_ticket_pabuf)); ERROUT(EBUSY); } - tail = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr, pf_rulequeue); if (tail) @@ -1269,8 +1274,29 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td } rule->rpool.cur = TAILQ_FIRST(&rule->rpool.list); +#ifndef PF_USER_INFO + if (rule->cuid) { + tail = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr); + while ((tail != NULL) && (tail->cuid != rule->cuid)) + tail = TAILQ_NEXT(tail, entries); + if (tail != NULL) { + rule->evaluations = tail->evaluations; + rule->packets[0] = tail->packets[0]; + rule->packets[1] = tail->packets[1]; + rule->bytes[0] = tail->bytes[0]; + rule->bytes[1] = tail->bytes[1]; + } else { + rule->evaluations = rule->packets[0] = rule->packets[1] = + rule->bytes[0] = rule->bytes[1] = 0; + } + } else { + rule->evaluations = rule->packets[0] = rule->packets[1] = + rule->bytes[0] = rule->bytes[1] = 0; + } +#else rule->evaluations = rule->packets[0] = rule->packets[1] = rule->bytes[0] = rule->bytes[1] = 0; +#endif TAILQ_INSERT_TAIL(ruleset->rules[rs_num].inactive.ptr, rule, entries); ruleset->rules[rs_num].inactive.rcount++; @@ -1420,7 +1446,9 @@ DIOCADDRULE_error: newrule->states_cur = counter_u64_alloc(M_WAITOK); newrule->states_tot = counter_u64_alloc(M_WAITOK); newrule->src_nodes = counter_u64_alloc(M_WAITOK); +#ifdef PF_USER_INFO newrule->cuid = td->td_ucred->cr_ruid; +#endif newrule->cpid = td->td_proc ? td->td_proc->p_pid : 0; TAILQ_INIT(&newrule->rpool.list); } @@ -1707,6 +1735,30 @@ relock_DIOCKILLSTATES: break; } + case DIOCKILLSCHEDULE: { + struct pf_state *state; + struct pfioc_schedule_kill *psk = (struct pfioc_schedule_kill *)addr; + int killed = 0; + u_int i; + + for (i = 0; i <= pf_hashmask; i++) { + struct pf_idhash *ih = &V_pf_idhash[i]; + +relock_DIOCKILLSCHEDULE: + PF_HASHROW_LOCK(ih); + LIST_FOREACH(state, &ih->states, entry) { + if (!strcmp(psk->schedule, state->rule.ptr->schedule)) { + pf_unlink_state(state, PF_ENTER_LOCKED); + killed++; + goto relock_DIOCKILLSCHEDULE; + } + } + PF_HASHROW_UNLOCK(ih); + } + psk->numberkilled = killed; + break; + } + case DIOCADDSTATE: { struct pfioc_state *ps = (struct pfioc_state *)addr; struct pfsync_state *sp = &ps->state; @@ -2097,6 +2149,16 @@ DIOCGETSTATES_full: break; } + case DIOCGETNAMEDALTQ: { + struct pfioc_ruleset *pa = (struct pfioc_ruleset *)addr; + + if (pa->name[0]) { + pa->nr = pf_qname2qid(pa->name); + pf_qid_unref(pa->nr); + } + break; + } + case DIOCGETALTQS: { struct pfioc_altq *pa = (struct pfioc_altq *)addr; struct pf_altq *altq; @@ -2182,6 +2244,16 @@ DIOCGETSTATES_full: } #endif /* ALTQ */ + case DIOCGETNAMEDTAG: { + /* Little abuse. */ + struct pfioc_ruleset *pa = (struct pfioc_ruleset *)addr; + + if (pa->name[0]) + pa->nr = pf_tagname2tag(pa->name); + + break; + } + case DIOCBEGINADDRS: { struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr; @@ -3629,8 +3701,8 @@ hook_pf(void) pfh_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET); if (pfh_inet == NULL) return (ESRCH); /* XXX */ - pfil_add_hook(pf_check_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet); - pfil_add_hook(pf_check_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet); + pfil_add_named_hook(pf_check_in, NULL, "pf", PFIL_IN | PFIL_WAITOK, pfh_inet); + pfil_add_named_hook(pf_check_out, NULL, "pf", PFIL_OUT | PFIL_WAITOK, pfh_inet); #endif #ifdef INET6 pfh_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6); @@ -3643,8 +3715,10 @@ hook_pf(void) #endif return (ESRCH); /* XXX */ } - pfil_add_hook(pf_check6_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet6); - pfil_add_hook(pf_check6_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet6); + pfil_add_named_hook(pf_check6_in, NULL, "pf", PFIL_IN | PFIL_WAITOK, + pfh_inet6); + pfil_add_named_hook(pf_check6_out, NULL, "pf", PFIL_OUT | PFIL_WAITOK, + pfh_inet6); #endif V_pf_pfil_hooked = 1; |