diff options
author | Kristof Provost <kp@FreeBSD.org> | 2022-10-07 14:22:57 +0000 |
---|---|---|
committer | Kristof Provost <kp@FreeBSD.org> | 2022-10-14 08:36:16 +0000 |
commit | a974702e274cbed52ae9ad9ecef8501e267b822d (patch) | |
tree | 41b3fe6977778863761b9690a8eca026e886ea75 | |
parent | 12b92f3ed82aa71c0eba246ce3053ef225724570 (diff) | |
download | src-a974702e274cbed52ae9ad9ecef8501e267b822d.tar.gz src-a974702e274cbed52ae9ad9ecef8501e267b822d.zip |
pf: apply the network stack's ICMP rate limiting to ICMP errors sent by pf
PR: 266477
Event: Aberdeen Hackathon 2022
Differential Revision: https://reviews.freebsd.org/D36903
-rw-r--r-- | sys/netinet/icmp6.h | 1 | ||||
-rw-r--r-- | sys/netinet6/icmp6.c | 3 | ||||
-rw-r--r-- | sys/netpfil/pf/pf.c | 26 |
3 files changed, 28 insertions, 2 deletions
diff --git a/sys/netinet/icmp6.h b/sys/netinet/icmp6.h index 7429b8173b6a..45a8b8ec0ce8 100644 --- a/sys/netinet/icmp6.h +++ b/sys/netinet/icmp6.h @@ -708,6 +708,7 @@ int icmp6_input(struct mbuf **, int *, int); void icmp6_prepare(struct mbuf *); void icmp6_redirect_input(struct mbuf *, int); void icmp6_redirect_output(struct mbuf *, struct nhop_object *); +int icmp6_ratelimit(const struct in6_addr *, const int, const int); struct ip6ctlparam; void icmp6_mtudisc_update(struct ip6ctlparam *, int); diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index 4497041f0330..2cd54abbb76e 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -137,7 +137,6 @@ VNET_DECLARE(int, icmp6_nodeinfo); static void icmp6_errcount(int, int); static int icmp6_rip6_input(struct mbuf **, int); static void icmp6_reflect(struct mbuf *, size_t); -static int icmp6_ratelimit(const struct in6_addr *, const int, const int); static const char *icmp6_redirect_diag(struct in6_addr *, struct in6_addr *, struct in6_addr *); static struct mbuf *ni6_input(struct mbuf *, int, struct prison *); @@ -2727,7 +2726,7 @@ icmp6_ctloutput(struct socket *so, struct sockopt *sopt) * type - not used at this moment * code - not used at this moment */ -static int +int icmp6_ratelimit(const struct in6_addr *dst, const int type, const int code) { diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 2a6efbfe6e7d..d0139dc6bd15 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -3048,6 +3048,22 @@ pf_match_ieee8021q_pcp(u_int8_t prio, struct mbuf *m) return (mpcp == prio); } +static int +pf_icmp_to_bandlim(uint8_t type) +{ + switch (type) { + case ICMP_ECHO: + case ICMP_ECHOREPLY: + return (BANDLIM_ICMP_ECHO); + case ICMP_TSTAMP: + case ICMP_TSTAMPREPLY: + return (BANDLIM_ICMP_TSTAMP); + case ICMP_UNREACH: + default: + return (BANDLIM_ICMP_UNREACH); + } +} + static void pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af, struct pf_krule *r) @@ -3056,6 +3072,16 @@ pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af, struct mbuf *m0; struct pf_mtag *pf_mtag; + /* ICMP packet rate limitation. */ + if (af == AF_INET6) { + if (icmp6_ratelimit(NULL, type, code)) + return; + } else { + MPASS(af == AF_INET); + if (badport_bandlim(pf_icmp_to_bandlim(type)) != 0) + return; + } + /* Allocate outgoing queue entry, mbuf and mbuf tag. */ pfse = malloc(sizeof(*pfse), M_PFTEMP, M_NOWAIT); if (pfse == NULL) |