From: Alexander Bluhm Subject: convert IN_LOOKUP_MULTI to function To: tech@openbsd.org Date: Tue, 11 Nov 2025 20:07:06 +0100 Hi, I would like to convert macros IN_LOOKUP_MULTI() and IN6_LOOKUP_MULTI() into functions. Has less side effects and makes future locking easier. ok? bluhm Index: netinet/igmp.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/igmp.c,v diff -u -p -r1.89 igmp.c --- netinet/igmp.c 11 Nov 2025 13:05:35 -0000 1.89 +++ netinet/igmp.c 11 Nov 2025 18:48:07 -0000 @@ -396,7 +396,7 @@ igmp_input_if(struct ifnet *ifp, struct * If we belong to the group being reported, stop * our timer for that group. */ - IN_LOOKUP_MULTI(igmp->igmp_group, ifp, inm); + inm = in_lookupmulti(&igmp->igmp_group, ifp); if (inm != NULL) { inm->inm_timer = 0; igmpstat_inc(igps_rcv_ourreports); @@ -464,7 +464,7 @@ igmp_input_if(struct ifnet *ifp, struct * If we belong to the group being reported, stop * our timer for that group. */ - IN_LOOKUP_MULTI(igmp->igmp_group, ifp, inm); + inm = in_lookupmulti(&igmp->igmp_group, ifp); if (inm != NULL) { inm->inm_timer = 0; igmpstat_inc(igps_rcv_ourreports); Index: netinet/in.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/in.c,v diff -u -p -r1.187 in.c --- netinet/in.c 8 Jul 2025 00:47:41 -0000 1.187 +++ netinet/in.c 11 Nov 2025 18:48:07 -0000 @@ -820,10 +820,33 @@ in_broadcast(struct in_addr in, u_int rt } /* + * Function for looking up the in_multi record for a given IP multicast + * address on a given interface. If no matching record is found, "inm" + * returns NULL. + */ +struct in_multi * +in_lookupmulti(struct in_addr *addr, struct ifnet *ifp) +{ + struct in_multi *inm = NULL; + struct ifmaddr *ifma; + + NET_ASSERT_LOCKED(); + + TAILQ_FOREACH(ifma, &ifp->if_maddrlist, ifma_list) { + if (ifma->ifma_addr->sa_family == AF_INET && + ifmatoinm(ifma)->inm_addr.s_addr == addr->s_addr) { + inm = ifmatoinm(ifma); + break; + } + } + return (inm); +} + +/* * Add an address to the list of IP multicast addresses for a given interface. */ struct in_multi * -in_addmulti(struct in_addr *ap, struct ifnet *ifp) +in_addmulti(struct in_addr *addr, struct ifnet *ifp) { struct in_multi *inm; struct ifreq ifr; @@ -831,7 +854,7 @@ in_addmulti(struct in_addr *ap, struct i /* * See if address already in list. */ - IN_LOOKUP_MULTI(*ap, ifp, inm); + inm = in_lookupmulti(addr, ifp); if (inm != NULL) { /* * Found it; just increment the reference count. @@ -845,7 +868,7 @@ in_addmulti(struct in_addr *ap, struct i inm = malloc(sizeof(*inm), M_IPMADDR, M_WAITOK | M_ZERO); inm->inm_sin.sin_len = sizeof(struct sockaddr_in); inm->inm_sin.sin_family = AF_INET; - inm->inm_sin.sin_addr = *ap; + inm->inm_sin.sin_addr = *addr; refcnt_init_trace(&inm->inm_refcnt, DT_REFCNT_IDX_IFMADDR); inm->inm_ifidx = ifp->if_index; inm->inm_ifma.ifma_addr = sintosa(&inm->inm_sin); @@ -918,16 +941,16 @@ in_delmulti(struct in_multi *inm) } /* - * Return 1 if the multicast group represented by ``ap'' has been + * Return 1 if the multicast group represented by ``addr'' has been * joined by interface ``ifp'', 0 otherwise. */ int -in_hasmulti(struct in_addr *ap, struct ifnet *ifp) +in_hasmulti(struct in_addr *addr, struct ifnet *ifp) { struct in_multi *inm; int joined; - IN_LOOKUP_MULTI(*ap, ifp, inm); + inm = in_lookupmulti(addr, ifp); joined = (inm != NULL); return (joined); Index: netinet/in_var.h =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/in_var.h,v diff -u -p -r1.42 in_var.h --- netinet/in_var.h 11 Nov 2025 13:05:35 -0000 1.42 +++ netinet/in_var.h 11 Nov 2025 18:48:07 -0000 @@ -119,30 +119,9 @@ ifmatoinm(struct ifmaddr *ifma) return ((struct in_multi *)(ifma)); } -/* - * Macro for looking up the in_multi record for a given IP multicast - * address on a given interface. If no matching record is found, "inm" - * returns NULL. - */ -#define IN_LOOKUP_MULTI(addr, ifp, inm) \ - /* struct in_addr addr; */ \ - /* struct ifnet *ifp; */ \ - /* struct in_multi *inm; */ \ -do { \ - struct ifmaddr *ifma; \ - \ - (inm) = NULL; \ - NET_ASSERT_LOCKED(); \ - TAILQ_FOREACH(ifma, &(ifp)->if_maddrlist, ifma_list) \ - if (ifma->ifma_addr->sa_family == AF_INET && \ - ifmatoinm(ifma)->inm_addr.s_addr == (addr).s_addr) {\ - (inm) = ifmatoinm(ifma); \ - break; \ - } \ -} while (/* CONSTCOND */ 0) - int in_ifinit(struct ifnet *, struct in_ifaddr *, struct sockaddr_in *, int); +struct in_multi *in_lookupmulti(struct in_addr *, struct ifnet *); struct in_multi *in_addmulti(struct in_addr *, struct ifnet *); void in_delmulti(struct in_multi *); int in_hasmulti(struct in_addr *, struct ifnet *); Index: netinet6/in6.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/in6.c,v diff -u -p -r1.273 in6.c --- netinet6/in6.c 16 Sep 2025 09:18:29 -0000 1.273 +++ netinet6/in6.c 11 Nov 2025 19:03:52 -0000 @@ -998,11 +998,34 @@ in6_ifinit(struct ifnet *ifp, struct in6 } /* + * Function for looking up the in6_multi record for a given IP6 multicast + * address on a given interface. If no matching record is found, "in6m" + * returns NULL. + */ +struct in6_multi * +in6_lookupmulti(struct in6_addr *addr, struct ifnet *ifp) +{ + struct in6_multi *in6m = NULL; + struct ifmaddr *ifma; + + NET_ASSERT_LOCKED(); + + TAILQ_FOREACH(ifma, &ifp->if_maddrlist, ifma_list) { + if (ifma->ifma_addr->sa_family == AF_INET6 && + IN6_ARE_ADDR_EQUAL(&ifmatoin6m(ifma)->in6m_addr, addr)) { + in6m = ifmatoin6m(ifma); + break; + } + } + return (in6m); +} + +/* * Add an address to the list of IP6 multicast addresses for a * given interface. */ struct in6_multi * -in6_addmulti(struct in6_addr *maddr6, struct ifnet *ifp, int *errorp) +in6_addmulti(struct in6_addr *addr, struct ifnet *ifp, int *errorp) { struct in6_ifreq ifr; struct in6_multi *in6m; @@ -1013,7 +1036,7 @@ in6_addmulti(struct in6_addr *maddr6, st /* * See if address already in list. */ - IN6_LOOKUP_MULTI(*maddr6, ifp, in6m); + in6m = in6_lookupmulti(addr, ifp); if (in6m != NULL) { /* * Found it; just increment the reference count. @@ -1032,7 +1055,7 @@ in6_addmulti(struct in6_addr *maddr6, st in6m->in6m_sin.sin6_len = sizeof(struct sockaddr_in6); in6m->in6m_sin.sin6_family = AF_INET6; - in6m->in6m_sin.sin6_addr = *maddr6; + in6m->in6m_sin.sin6_addr = *addr; refcnt_init_trace(&in6m->in6m_refcnt, DT_REFCNT_IDX_IFMADDR); in6m->in6m_ifidx = ifp->if_index; in6m->in6m_ifma.ifma_addr = sin6tosa(&in6m->in6m_sin); @@ -1109,12 +1132,12 @@ in6_delmulti(struct in6_multi *in6m) * joined by interface ``ifp'', 0 otherwise. */ int -in6_hasmulti(struct in6_addr *maddr6, struct ifnet *ifp) +in6_hasmulti(struct in6_addr *addr, struct ifnet *ifp) { struct in6_multi *in6m; int joined; - IN6_LOOKUP_MULTI(*maddr6, ifp, in6m); + in6m = in6_lookupmulti(addr, ifp); joined = (in6m != NULL); return (joined); Index: netinet6/in6_var.h =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/in6_var.h,v diff -u -p -r1.81 in6_var.h --- netinet6/in6_var.h 20 May 2025 05:51:43 -0000 1.81 +++ netinet6/in6_var.h 11 Nov 2025 18:48:07 -0000 @@ -329,28 +329,7 @@ ifmatoin6m(struct ifmaddr *ifma) return ((struct in6_multi *)(ifma)); } -/* - * Macros for looking up the in6_multi record for a given IP6 multicast - * address on a given interface. If no matching record is found, "in6m" - * returns NULL. - */ -#define IN6_LOOKUP_MULTI(addr, ifp, in6m) \ - /* struct in6_addr addr; */ \ - /* struct ifnet *ifp; */ \ - /* struct in6_multi *in6m; */ \ -do { \ - struct ifmaddr *ifma; \ - \ - (in6m) = NULL; \ - TAILQ_FOREACH(ifma, &(ifp)->if_maddrlist, ifma_list) \ - if (ifma->ifma_addr->sa_family == AF_INET6 && \ - IN6_ARE_ADDR_EQUAL(&ifmatoin6m(ifma)->in6m_addr, \ - &(addr))) { \ - (in6m) = ifmatoin6m(ifma); \ - break; \ - } \ -} while (/* CONSTCOND */ 0) - +struct in6_multi *in6_lookupmulti(struct in6_addr *, struct ifnet *); 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 *); Index: netinet6/mld6.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/mld6.c,v diff -u -p -r1.68 mld6.c --- netinet6/mld6.c 8 Jul 2025 00:47:41 -0000 1.68 +++ netinet6/mld6.c 11 Nov 2025 18:48:07 -0000 @@ -308,7 +308,7 @@ mld6_input(struct mbuf *m, int off) * If we belong to the group being reported, stop * our timer for that group. */ - IN6_LOOKUP_MULTI(mldh->mld_addr, ifp, in6m); + in6m = in6_lookupmulti(&mldh->mld_addr, ifp); if (in6m) { in6m->in6m_timer = 0; /* transit to idle state */ in6m->in6m_state = MLD_OTHERLISTENER; /* clear flag */ Index: netinet6/nd6.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/nd6.c,v diff -u -p -r1.303 nd6.c --- netinet6/nd6.c 16 Sep 2025 09:19:43 -0000 1.303 +++ netinet6/nd6.c 11 Nov 2025 18:48:07 -0000 @@ -912,7 +912,7 @@ nd6_rtrequest(struct ifnet *ifp, int req llsol.s6_addr8[12] = 0xff; KERNEL_LOCK(); - IN6_LOOKUP_MULTI(llsol, ifp, in6m); + in6m = in6_lookupmulti(&llsol, ifp); if (in6m) in6_delmulti(in6m); KERNEL_UNLOCK();