ip_mroute: refactor epoch-basd locking

Remove duplicated epoch_enter and epoch_exit in IP inp/outp routines.
Remove unnecessary macros as well.

Obtained from:		Semihalf
Spponsored by:		Stormshield
Reviewed by:		glebius
Differential revision:	https://reviews.freebsd.org/D34030
This commit is contained in:
Wojciech Macek 2022-01-25 10:10:44 +01:00
parent 445ecc480c
commit 77223d98b6
5 changed files with 14 additions and 42 deletions

View File

@ -82,7 +82,6 @@ __FBSDID("$FreeBSD$");
#include <machine/in_cksum.h> #include <machine/in_cksum.h>
#include <netinet/ip_carp.h> #include <netinet/ip_carp.h>
#include <netinet/in_rss.h> #include <netinet/in_rss.h>
#include <netinet/ip_mroute.h>
#include <netipsec/ipsec_support.h> #include <netipsec/ipsec_support.h>
@ -448,7 +447,6 @@ ip_direct_input(struct mbuf *m)
void void
ip_input(struct mbuf *m) ip_input(struct mbuf *m)
{ {
MROUTER_RLOCK_TRACKER;
struct ip *ip = NULL; struct ip *ip = NULL;
struct in_ifaddr *ia = NULL; struct in_ifaddr *ia = NULL;
struct ifaddr *ifa; struct ifaddr *ifa;
@ -744,7 +742,6 @@ ip_input(struct mbuf *m)
ia = NULL; ia = NULL;
} }
if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) { if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
MROUTER_RLOCK();
/* /*
* RFC 3927 2.7: Do not forward multicast packets from * RFC 3927 2.7: Do not forward multicast packets from
* IN_LINKLOCAL. * IN_LINKLOCAL.
@ -759,7 +756,6 @@ ip_input(struct mbuf *m)
* must be discarded, else it may be accepted below. * must be discarded, else it may be accepted below.
*/ */
if (ip_mforward && ip_mforward(ip, ifp, m, 0) != 0) { if (ip_mforward && ip_mforward(ip, ifp, m, 0) != 0) {
MROUTER_RUNLOCK();
IPSTAT_INC(ips_cantforward); IPSTAT_INC(ips_cantforward);
m_freem(m); m_freem(m);
return; return;
@ -771,12 +767,10 @@ ip_input(struct mbuf *m)
* host belongs to their destination groups. * host belongs to their destination groups.
*/ */
if (ip->ip_p == IPPROTO_IGMP) { if (ip->ip_p == IPPROTO_IGMP) {
MROUTER_RUNLOCK();
goto ours; goto ours;
} }
IPSTAT_INC(ips_forward); IPSTAT_INC(ips_forward);
} }
MROUTER_RUNLOCK();
/* /*
* Assume the packet is for us, to avoid prematurely taking * Assume the packet is for us, to avoid prematurely taking
* a lock on the in_multi hash. Protocols must perform * a lock on the in_multi hash. Protocols must perform

View File

@ -300,7 +300,7 @@ VNET_DEFINE_STATIC(struct ifnet *, multicast_register_if);
static u_long X_ip_mcast_src(int); static u_long X_ip_mcast_src(int);
static int X_ip_mforward(struct ip *, struct ifnet *, struct mbuf *, static int X_ip_mforward(struct ip *, struct ifnet *, struct mbuf *,
struct ip_moptions *); struct ip_moptions *);
static int X_ip_mrouter_done(void *); static int X_ip_mrouter_done(void);
static int X_ip_mrouter_get(struct socket *, struct sockopt *); static int X_ip_mrouter_get(struct socket *, struct sockopt *);
static int X_ip_mrouter_set(struct socket *, struct sockopt *); static int X_ip_mrouter_set(struct socket *, struct sockopt *);
static int X_legal_vif_num(int); static int X_legal_vif_num(int);
@ -431,7 +431,7 @@ X_ip_mrouter_set(struct socket *so, struct sockopt *sopt)
break; break;
case MRT_DONE: case MRT_DONE:
error = ip_mrouter_done(NULL); error = ip_mrouter_done();
break; break;
case MRT_ADD_VIF: case MRT_ADD_VIF:
@ -734,20 +734,15 @@ ip_mrouter_init(struct socket *so, int version)
* Disable multicast forwarding. * Disable multicast forwarding.
*/ */
static int static int
X_ip_mrouter_done(void *locked) X_ip_mrouter_done(void)
{ {
struct ifnet *ifp; struct ifnet *ifp;
u_long i; u_long i;
vifi_t vifi; vifi_t vifi;
struct bw_upcall *bu; struct bw_upcall *bu;
if (V_ip_mrouter == NULL) { if (V_ip_mrouter == NULL)
if (locked) { return (EINVAL);
struct epoch_tracker *mrouter_et = locked;
MROUTER_RUNLOCK_PARAM(mrouter_et);
}
return EINVAL;
}
/* /*
* Detach/disable hooks to the reset of the system. * Detach/disable hooks to the reset of the system.
@ -756,12 +751,11 @@ X_ip_mrouter_done(void *locked)
atomic_subtract_int(&ip_mrouter_cnt, 1); atomic_subtract_int(&ip_mrouter_cnt, 1);
V_mrt_api_config = 0; V_mrt_api_config = 0;
if (locked) { /*
struct epoch_tracker *mrouter_et = locked; * Wait for all epoch sections to complete to ensure
MROUTER_RUNLOCK_PARAM(mrouter_et); * V_ip_mrouter = NULL is visible to others.
} */
epoch_wait_preempt(net_epoch_preempt);
MROUTER_WAIT();
/* Stop and drain task queue */ /* Stop and drain task queue */
taskqueue_block(V_task_queue); taskqueue_block(V_task_queue);

View File

@ -363,16 +363,9 @@ struct sockopt;
extern int (*ip_mrouter_set)(struct socket *, struct sockopt *); extern int (*ip_mrouter_set)(struct socket *, struct sockopt *);
extern int (*ip_mrouter_get)(struct socket *, struct sockopt *); extern int (*ip_mrouter_get)(struct socket *, struct sockopt *);
extern int (*ip_mrouter_done)(void *); extern int (*ip_mrouter_done)(void);
extern int (*mrt_ioctl)(u_long, caddr_t, int); extern int (*mrt_ioctl)(u_long, caddr_t, int);
#define MROUTER_RLOCK_TRACKER struct epoch_tracker mrouter_et
#define MROUTER_RLOCK_PARAM_PTR &mrouter_et
#define MROUTER_RLOCK() epoch_enter_preempt(net_epoch_preempt, &mrouter_et)
#define MROUTER_RUNLOCK() epoch_exit_preempt(net_epoch_preempt, &mrouter_et)
#define MROUTER_RUNLOCK_PARAM(param) epoch_exit_preempt(net_epoch_preempt, param)
#define MROUTER_WAIT() epoch_wait_preempt(net_epoch_preempt)
#endif /* _KERNEL */ #endif /* _KERNEL */
#endif /* _NETINET_IP_MROUTE_H_ */ #endif /* _NETINET_IP_MROUTE_H_ */

View File

@ -82,7 +82,6 @@ __FBSDID("$FreeBSD$");
#include <netinet/in_var.h> #include <netinet/in_var.h>
#include <netinet/ip_var.h> #include <netinet/ip_var.h>
#include <netinet/ip_options.h> #include <netinet/ip_options.h>
#include <netinet/ip_mroute.h>
#include <netinet/udp.h> #include <netinet/udp.h>
#include <netinet/udp_var.h> #include <netinet/udp_var.h>
@ -321,7 +320,6 @@ int
ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
struct ip_moptions *imo, struct inpcb *inp) struct ip_moptions *imo, struct inpcb *inp)
{ {
MROUTER_RLOCK_TRACKER;
struct ip *ip; struct ip *ip;
struct ifnet *ifp = NULL; /* keep compiler happy */ struct ifnet *ifp = NULL; /* keep compiler happy */
struct mbuf *m0; struct mbuf *m0;
@ -609,7 +607,6 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
* above, will be forwarded by the ip_input() routine, * above, will be forwarded by the ip_input() routine,
* if necessary. * if necessary.
*/ */
MROUTER_RLOCK();
if (V_ip_mrouter && (flags & IP_FORWARDING) == 0) { if (V_ip_mrouter && (flags & IP_FORWARDING) == 0) {
/* /*
* If rsvp daemon is not running, do not * If rsvp daemon is not running, do not
@ -621,12 +618,10 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
imo = NULL; imo = NULL;
if (ip_mforward && if (ip_mforward &&
ip_mforward(ip, ifp, m, imo) != 0) { ip_mforward(ip, ifp, m, imo) != 0) {
MROUTER_RUNLOCK();
m_freem(m); m_freem(m);
goto done; goto done;
} }
} }
MROUTER_RUNLOCK();
} }
/* /*

View File

@ -119,7 +119,7 @@ VNET_DEFINE(struct socket *, ip_mrouter);
*/ */
int (*ip_mrouter_set)(struct socket *, struct sockopt *); int (*ip_mrouter_set)(struct socket *, struct sockopt *);
int (*ip_mrouter_get)(struct socket *, struct sockopt *); int (*ip_mrouter_get)(struct socket *, struct sockopt *);
int (*ip_mrouter_done)(void *locked); int (*ip_mrouter_done)(void);
int (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *, int (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
struct ip_moptions *); struct ip_moptions *);
int (*mrt_ioctl)(u_long, caddr_t, int); int (*mrt_ioctl)(u_long, caddr_t, int);
@ -879,19 +879,15 @@ static void
rip_detach(struct socket *so) rip_detach(struct socket *so)
{ {
struct inpcb *inp; struct inpcb *inp;
MROUTER_RLOCK_TRACKER;
inp = sotoinpcb(so); inp = sotoinpcb(so);
KASSERT(inp != NULL, ("rip_detach: inp == NULL")); KASSERT(inp != NULL, ("rip_detach: inp == NULL"));
KASSERT(inp->inp_faddr.s_addr == INADDR_ANY, KASSERT(inp->inp_faddr.s_addr == INADDR_ANY,
("rip_detach: not closed")); ("rip_detach: not closed"));
/* Disable mrouter first, lock released inside ip_mrouter_done */ /* Disable mrouter first */
MROUTER_RLOCK();
if (so == V_ip_mrouter && ip_mrouter_done) if (so == V_ip_mrouter && ip_mrouter_done)
ip_mrouter_done(MROUTER_RLOCK_PARAM_PTR); ip_mrouter_done();
else
MROUTER_RUNLOCK();
INP_WLOCK(inp); INP_WLOCK(inp);
INP_HASH_WLOCK(&V_ripcbinfo); INP_HASH_WLOCK(&V_ripcbinfo);