From 77e6310e00ab597c99ff48c7b868dfb82c4e9dc2 Mon Sep 17 00:00:00 2001 From: Martin Pieuchot Date: Thu, 21 Jan 2016 11:23:49 +0000 Subject: Introduce in{,6}_hasmulti(), two functions to check in the hot path if an interface joined a specific multicast group. ok phessler@, visa@, dlg@ --- sys/netinet/in.c | 17 ++++++++++++++++- sys/netinet/in_var.h | 3 ++- sys/netinet/ip_carp.c | 8 ++------ sys/netinet/ip_input.c | 7 ++----- sys/netinet/ip_output.c | 8 +++----- sys/netinet6/in6.c | 18 +++++++++++++++++- sys/netinet6/in6_var.h | 3 ++- sys/netinet6/ip6_input.c | 6 ++---- sys/netinet6/ip6_mroute.c | 4 +--- sys/netinet6/ip6_output.c | 8 +++----- 10 files changed, 50 insertions(+), 32 deletions(-) diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 4450832b380..40f21d279e4 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in.c,v 1.125 2015/12/03 21:57:59 mpi Exp $ */ +/* $OpenBSD: in.c,v 1.126 2016/01/21 11:23:48 mpi Exp $ */ /* $NetBSD: in.c,v 1.26 1996/02/13 23:41:39 christos Exp $ */ /* @@ -880,6 +880,21 @@ in_delmulti(struct in_multi *inm) } } +/* + * Return 1 if the multicast group represented by ``ap'' has been + * joined by interface ``ifp'', 0 otherwise. + */ +int +in_hasmulti(struct in_addr *ap, struct ifnet *ifp) +{ + struct in_multi *inm; + int joined; + + IN_LOOKUP_MULTI(*ap, ifp, inm); + joined = (inm != NULL); + + return (joined); +} void in_ifdetach(struct ifnet *ifp) diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h index 2bee960430c..14a3a5938a8 100644 --- a/sys/netinet/in_var.h +++ b/sys/netinet/in_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in_var.h,v 1.37 2015/12/03 21:57:59 mpi Exp $ */ +/* $OpenBSD: in_var.h,v 1.38 2016/01/21 11:23:48 mpi Exp $ */ /* $NetBSD: in_var.h,v 1.16 1996/02/13 23:42:15 christos Exp $ */ /* @@ -154,6 +154,7 @@ int in_ifinit(struct ifnet *, struct in_ifaddr *, struct sockaddr_in *, int); struct in_multi *in_addmulti(struct in_addr *, struct ifnet *); void in_delmulti(struct in_multi *); +int in_hasmulti(struct in_addr *, struct ifnet *); void in_ifscrub(struct ifnet *, struct in_ifaddr *); int in_control(struct socket *, u_long, caddr_t, struct ifnet *); void in_prefixlen2mask(struct in_addr *, int); diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index b4abb0185cf..e0220d74ca3 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_carp.c,v 1.285 2016/01/12 09:22:01 mpi Exp $ */ +/* $OpenBSD: ip_carp.c,v 1.286 2016/01/21 11:23:48 mpi Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff. All rights reserved. @@ -1809,17 +1809,13 @@ carp_addr_updated(void *v) /* We received address changes from if_addrhooks callback */ if (new_naddrs != sc->sc_naddrs || new_naddrs6 != sc->sc_naddrs6) { - struct in_addr mc_addr; - struct in_multi *inm; sc->sc_naddrs = new_naddrs; sc->sc_naddrs6 = new_naddrs6; /* Re-establish multicast membership removed by in_control */ if (IN_MULTICAST(sc->sc_peer.s_addr)) { - mc_addr.s_addr = sc->sc_peer.s_addr; - IN_LOOKUP_MULTI(mc_addr, &sc->sc_if, inm); - if (inm == NULL) { + if (!in_hasmulti(&sc->sc_peer, &sc->sc_if)) { struct in_multi **imm = sc->sc_imo.imo_membership; u_int16_t maxmem = diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 885e6fc4ed8..4ceb3de01cd 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_input.c,v 1.265 2015/12/03 21:11:53 sashan Exp $ */ +/* $OpenBSD: ip_input.c,v 1.266 2016/01/21 11:23:48 mpi Exp $ */ /* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */ /* @@ -346,8 +346,6 @@ ipv4_input(struct mbuf *m) } if (IN_MULTICAST(ip->ip_dst.s_addr)) { - struct in_multi *inm; - /* * Make sure M_MCAST is set. It should theoretically * already be there, but let's play safe because upper @@ -402,8 +400,7 @@ ipv4_input(struct mbuf *m) * See if we belong to the destination multicast group on the * arrival interface. */ - IN_LOOKUP_MULTI(ip->ip_dst, ifp, inm); - if (inm == NULL) { + if (!in_hasmulti(&ip->ip_dst, ifp)) { ipstat.ips_notmember++; if (!IN_LOCAL_GROUP(ip->ip_dst.s_addr)) ipstat.ips_cantforward++; diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 070a56b6bd1..385f908aa9b 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_output.c,v 1.316 2016/01/13 09:38:36 mpi Exp $ */ +/* $OpenBSD: ip_output.c,v 1.317 2016/01/21 11:23:48 mpi Exp $ */ /* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */ /* @@ -241,7 +241,6 @@ reroute: if (IN_MULTICAST(ip->ip_dst.s_addr) || (ip->ip_dst.s_addr == INADDR_BROADCAST)) { - struct in_multi *inm; m->m_flags |= (ip->ip_dst.s_addr == INADDR_BROADCAST) ? M_BCAST : M_MCAST; @@ -295,9 +294,8 @@ reroute: ip->ip_src = ia->ia_addr.sin_addr; } - IN_LOOKUP_MULTI(ip->ip_dst, ifp, inm); - if (inm != NULL && - (imo == NULL || imo->imo_loop)) { + if ((imo == NULL || imo->imo_loop) && + in_hasmulti(&ip->ip_dst, ifp)) { /* * If we belong to the destination multicast group * on the outgoing interface, and the caller did not diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index a2c6b67b223..e1256cfa18a 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6.c,v 1.182 2015/12/22 10:01:01 mpi Exp $ */ +/* $OpenBSD: in6.c,v 1.183 2016/01/21 11:23:48 mpi Exp $ */ /* $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $ */ /* @@ -1378,6 +1378,22 @@ in6_delmulti(struct in6_multi *in6m) } } +/* + * Return 1 if the multicast group represented by ``maddr6'' has been + * joined by interface ``ifp'', 0 otherwise. + */ +int +in6_hasmulti(struct in6_addr *maddr6, struct ifnet *ifp) +{ + struct in6_multi *in6m; + int joined; + + IN6_LOOKUP_MULTI(*maddr6, ifp, in6m); + joined = (in6m != NULL); + + return (joined); +} + struct in6_multi_mship * in6_joingroup(struct ifnet *ifp, struct in6_addr *addr, int *errorp) { diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h index 700b8f4a366..fc91a9b1224 100644 --- a/sys/netinet6/in6_var.h +++ b/sys/netinet6/in6_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_var.h,v 1.58 2015/11/18 13:58:02 mpi Exp $ */ +/* $OpenBSD: in6_var.h,v 1.59 2016/01/21 11:23:48 mpi Exp $ */ /* $KAME: in6_var.h,v 1.55 2001/02/16 12:49:45 itojun Exp $ */ /* @@ -495,6 +495,7 @@ do { \ struct in6_multi *in6_addmulti(struct in6_addr *, struct ifnet *, int *); void in6_delmulti(struct in6_multi *); +int in6_hasmulti(struct in6_addr *, struct ifnet *); struct in6_multi_mship *in6_joingroup(struct ifnet *, struct in6_addr *, int *); int in6_leavegroup(struct in6_multi_mship *); int in6_control(struct socket *, u_long, caddr_t, struct ifnet *); diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 7656b09f8af..b9375930b01 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_input.c,v 1.153 2016/01/06 10:02:42 sthen Exp $ */ +/* $OpenBSD: ip6_input.c,v 1.154 2016/01/21 11:23:48 mpi Exp $ */ /* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */ /* @@ -388,7 +388,6 @@ ip6_input(struct mbuf *m) * Multicast check */ if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { - struct in6_multi *in6m = NULL; /* * Make sure M_MCAST is set. It should theoretically @@ -401,8 +400,7 @@ ip6_input(struct mbuf *m) * See if we belong to the destination multicast group on the * arrival interface. */ - IN6_LOOKUP_MULTI(ip6->ip6_dst, ifp, in6m); - if (in6m) + if (in6_hasmulti(&ip6->ip6_dst, ifp)) ours = 1; #ifdef MROUTING else if (!ip6_mforwarding || !ip6_mrouter) diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c index 0d8370165aa..51d504c15d7 100644 --- a/sys/netinet6/ip6_mroute.c +++ b/sys/netinet6/ip6_mroute.c @@ -1372,7 +1372,6 @@ phyint_send6(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m) int error = 0; int s = splsoftnet(); static struct route_in6 ro; - struct in6_multi *in6m; struct sockaddr_in6 *dst6; /* @@ -1416,8 +1415,7 @@ phyint_send6(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m) * on the outgoing interface, loop back a copy. */ dst6 = &ro.ro_dst; - IN6_LOOKUP_MULTI(ip6->ip6_dst, ifp, in6m); - if (in6m != NULL) { + if (in6_hasmulti(&ip6->ip6_dst, ifp)) { dst6->sin6_len = sizeof(struct sockaddr_in6); dst6->sin6_family = AF_INET6; dst6->sin6_addr = ip6->ip6_dst; diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 61e0fa2b7ab..17510b7bb68 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_output.c,v 1.203 2016/01/13 09:38:37 mpi Exp $ */ +/* $OpenBSD: ip6_output.c,v 1.204 2016/01/21 11:23:48 mpi Exp $ */ /* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */ /* @@ -566,7 +566,6 @@ reroute: m->m_flags &= ~(M_BCAST | M_MCAST); /* just in case */ } else { /* Multicast */ - struct in6_multi *in6m; m->m_flags = (m->m_flags & ~M_BCAST) | M_MCAST; @@ -579,9 +578,8 @@ reroute: goto bad; } - IN6_LOOKUP_MULTI(ip6->ip6_dst, ifp, in6m); - if (in6m != NULL && - (im6o == NULL || im6o->im6o_loop)) { + if ((im6o == NULL || im6o->im6o_loop) && + in6_hasmulti(&ip6->ip6_dst, ifp)) { /* * If we belong to the destination multicast group * on the outgoing interface, and the caller did not -- cgit v1.2.3