From a974702e274cbed52ae9ad9ecef8501e267b822d Mon Sep 17 00:00:00 2001 From: Kristof Provost Date: Fri, 7 Oct 2022 16:22:57 +0200 Subject: [PATCH] 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 --- sys/netinet/icmp6.h | 1 + sys/netinet6/icmp6.c | 3 +-- 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)