On Tue, Oct 1, 2013 at 3:33 PM, Martin Pieuchot <mpieuc...@nolizard.org> wrote: > On 19/09/13(Thu) 13:59, Martin Pieuchot wrote: >> Diff below change the macros used to iterate over the multicast >> records linked to an interface without using the global lists of >> addresses. >> >> These records are currently link to the first address descriptor, >> respectively v4 and v6, even if they are per-interface. So I >> changed the code to loop over the global interface list instead >> of iterating over all existing addresses. >> >> Tested here with a carp setup. Comments, ok?
What kind of test coverage are you looking for specifically ? > > I got one ok for this diff but no other feedback. > > Did somebody tried it on a different setup? I would really help me to > get this in to move forward, so I appreciate any tests, reviews or ok. > >> Index: netinet/igmp.c >> =================================================================== >> RCS file: /home/ncvs/src/sys/netinet/igmp.c,v >> retrieving revision 1.33 >> diff -u -p -r1.33 igmp.c >> --- netinet/igmp.c 2 May 2013 11:54:10 -0000 1.33 >> +++ netinet/igmp.c 13 Sep 2013 09:07:42 -0000 >> @@ -104,6 +104,7 @@ int igmp_timers_are_running; >> static struct router_info *rti_head; >> struct igmpstat igmpstat; >> >> +void igmp_checktimer(struct ifnet *); >> void igmp_sendpkt(struct in_multi *, int, in_addr_t); >> int rti_fill(struct in_multi *); >> struct router_info * rti_find(struct ifnet *); >> @@ -193,7 +194,6 @@ igmp_input(struct mbuf *m, ...) >> int igmplen; >> int minlen; >> struct in_multi *inm; >> - struct in_multistep step; >> struct router_info *rti; >> struct in_ifaddr *ia; >> int timer; >> @@ -266,17 +266,14 @@ igmp_input(struct mbuf *m, ...) >> * except those that are already running and those >> * that belong to a "local" group (224.0.0.X). >> */ >> - IN_FIRST_MULTI(step, inm); >> - while (inm != NULL) { >> - if (inm->inm_ia->ia_ifp == ifp && >> - inm->inm_timer == 0 && >> + IN_FOREACH_MULTI(ia, ifp, inm) { >> + if (inm->inm_timer == 0 && >> !IN_LOCAL_GROUP(inm->inm_addr.s_addr)) { >> inm->inm_state = IGMP_DELAYING_MEMBER; >> inm->inm_timer = IGMP_RANDOM_DELAY( >> IGMP_MAX_HOST_REPORT_DELAY * >> PR_FASTHZ); >> igmp_timers_are_running = 1; >> } >> - IN_NEXT_MULTI(step, inm); >> } >> } else { >> if (!IN_MULTICAST(ip->ip_dst.s_addr)) { >> @@ -297,10 +294,8 @@ igmp_input(struct mbuf *m, ...) >> * timers already running, check if they need to be >> * reset. >> */ >> - IN_FIRST_MULTI(step, inm); >> - while (inm != NULL) { >> - if (inm->inm_ia->ia_ifp == ifp && >> - !IN_LOCAL_GROUP(inm->inm_addr.s_addr) && >> + IN_FOREACH_MULTI(ia, ifp, inm) { >> + if (!IN_LOCAL_GROUP(inm->inm_addr.s_addr) && >> (ip->ip_dst.s_addr == >> INADDR_ALLHOSTS_GROUP || >> ip->ip_dst.s_addr == >> inm->inm_addr.s_addr)) { >> switch (inm->inm_state) { >> @@ -323,7 +318,6 @@ igmp_input(struct mbuf *m, ...) >> break; >> } >> } >> - IN_NEXT_MULTI(step, inm); >> } >> } >> >> @@ -505,8 +499,7 @@ igmp_leavegroup(struct in_multi *inm) >> void >> igmp_fasttimo(void) >> { >> - struct in_multi *inm; >> - struct in_multistep step; >> + struct ifnet *ifp; >> int s; >> >> /* >> @@ -518,8 +511,21 @@ igmp_fasttimo(void) >> >> s = splsoftnet(); >> igmp_timers_are_running = 0; >> - IN_FIRST_MULTI(step, inm); >> - while (inm != NULL) { >> + TAILQ_FOREACH(ifp, &ifnet, if_list) >> + igmp_checktimer(ifp); >> + splx(s); >> +} >> + >> + >> +void >> +igmp_checktimer(struct ifnet *ifp) >> +{ >> + struct in_multi *inm; >> + struct in_ifaddr *ia; >> + >> + splsoftassert(IPL_SOFTNET); >> + >> + IN_FOREACH_MULTI(ia, ifp, inm) { >> if (inm->inm_timer == 0) { >> /* do nothing */ >> } else if (--inm->inm_timer == 0) { >> @@ -535,9 +541,7 @@ igmp_fasttimo(void) >> } else { >> igmp_timers_are_running = 1; >> } >> - IN_NEXT_MULTI(step, inm); >> } >> - splx(s); >> } >> >> void >> Index: netinet/in_var.h >> =================================================================== >> RCS file: /home/ncvs/src/sys/netinet/in_var.h,v >> retrieving revision 1.21 >> diff -u -p -r1.21 in_var.h >> --- netinet/in_var.h 28 Aug 2013 21:19:16 -0000 1.21 >> +++ netinet/in_var.h 13 Sep 2013 09:07:42 -0000 >> @@ -147,17 +147,21 @@ struct in_multi { >> >> #ifdef _KERNEL >> /* >> - * Structure used by macros below to remember position when stepping through >> - * all of the in_multi records. >> + * Macro for iterating over all the in_multi records linked to a given >> + * interface. >> */ >> -struct in_multistep { >> - struct in_ifaddr *i_ia; >> - struct in_multi *i_inm; >> -}; >> +#define IN_FOREACH_MULTI(ia, ifp, inm) >> \ >> + /* struct in_ifaddr *ia; */ \ >> + /* struct ifnet *ifp; */ \ >> + /* struct in_multi *inm; */ \ >> + IFP_TO_IA((ifp), ia); \ >> + if (ia != NULL) \ >> + LIST_FOREACH((inm), &ia->ia_multiaddrs, inm_list) \ >> >> /* >> - * 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. >> + * 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; */ \ >> @@ -166,48 +170,10 @@ struct in_multistep { >> do { \ >> struct in_ifaddr *ia; \ >> \ >> - IFP_TO_IA((ifp), ia); \ >> - if (ia == NULL) \ >> - (inm) = NULL; \ >> - else \ >> - for ((inm) = LIST_FIRST(&ia->ia_multiaddrs); \ >> - (inm) != NULL && \ >> - (inm)->inm_addr.s_addr != (addr).s_addr; \ >> - (inm) = LIST_NEXT(inm, inm_list)) \ >> - continue; \ >> -} while (/* CONSTCOND */ 0) >> - >> -/* >> - * Macro to step through all of the in_multi records, one at a time. >> - * The current position is remembered in "step", which the caller must >> - * provide. IN_FIRST_MULTI(), below, must be called to initialize "step" >> - * and get the first record. Both macros return a NULL "inm" when there >> - * are no remaining records. >> - */ >> -#define IN_NEXT_MULTI(step, inm) \ >> - /* struct in_multistep step; */ \ >> - /* struct in_multi *inm; */ \ >> -do { \ >> - if (((inm) = (step).i_inm) != NULL) \ >> - (step).i_inm = LIST_NEXT((inm), inm_list); \ >> - else \ >> - while ((step).i_ia != NULL) { \ >> - (inm) = LIST_FIRST(&(step).i_ia->ia_multiaddrs); \ >> - (step).i_ia = TAILQ_NEXT((step).i_ia, ia_list); \ >> - if ((inm) != NULL) { \ >> - (step).i_inm = LIST_NEXT((inm), inm_list); \ >> - break; \ >> - } \ >> - } \ >> -} while (/* CONSTCOND */ 0) >> - >> -#define IN_FIRST_MULTI(step, inm) \ >> - /* struct in_multistep step; */ \ >> - /* struct in_multi *inm; */ \ >> -do { \ >> - (step).i_ia = TAILQ_FIRST(&in_ifaddr); \ >> - (step).i_inm = NULL; \ >> - IN_NEXT_MULTI((step), (inm)); \ >> + (inm) = NULL; \ >> + IN_FOREACH_MULTI(ia, ifp, inm) \ >> + if ((inm)->inm_addr.s_addr == (addr).s_addr) \ >> + break; \ >> } while (/* CONSTCOND */ 0) >> >> int in_ifinit(struct ifnet *, >> Index: netinet6/in6_var.h >> =================================================================== >> RCS file: /home/ncvs/src/sys/netinet6/in6_var.h,v >> retrieving revision 1.41 >> diff -u -p -r1.41 in6_var.h >> --- netinet6/in6_var.h 26 Aug 2013 07:15:58 -0000 1.41 >> +++ netinet6/in6_var.h 13 Sep 2013 09:07:42 -0000 >> @@ -502,70 +502,34 @@ struct in6_multi { >> >> #ifdef _KERNEL >> /* >> - * Structure used by macros below to remember position when stepping through >> - * all of the in6_multi records. >> + * Macro for iterating over all the in6_multi records linked to a given >> + * interface. >> */ >> -struct in6_multistep { >> - struct in6_ifaddr *i_ia; >> - struct in6_multi *i_in6m; >> -}; >> +#define IN6_FOREACH_MULTI(ia, ifp, in6m) \ >> + /* struct in6_ifaddr *ia; */ \ >> + /* struct ifnet *ifp; */ \ >> + /* struct in6_multi *in6m; */ \ >> + IFP_TO_IA6((ifp), ia); \ >> + if (ia != NULL) \ >> + LIST_FOREACH((in6m), &ia->ia6_multiaddrs, in6m_entry) \ >> >> /* >> * 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 NLL. >> + * returns NULL. >> */ >> - >> -#define IN6_LOOKUP_MULTI(addr, ifp, in6m) \ >> -/* struct in6_addr addr; */ \ >> -/* struct ifnet *ifp; */ \ >> -/* struct in6_multi *in6m; */ \ >> -do { \ >> - struct in6_ifaddr *ia; \ >> - \ >> - IFP_TO_IA6((ifp), ia); \ >> - if (ia == NULL) \ >> - (in6m) = NULL; \ >> - else \ >> - for ((in6m) = LIST_FIRST(&ia->ia6_multiaddrs); \ >> - (in6m) != NULL && \ >> - !IN6_ARE_ADDR_EQUAL(&(in6m)->in6m_addr, &(addr)); \ >> - (in6m) = LIST_NEXT((in6m), in6m_entry)) \ >> - continue; \ >> -} while (0) >> - >> -/* >> - * Macro to step through all of the in6_multi records, one at a time. >> - * The current position is remembered in "step", which the caller must >> - * provide. IN6_FIRST_MULTI(), below, must be called to initialize "step" >> - * and get the first record. Both macros return a NULL "in6m" when there >> - * are no remaining records. >> - */ >> -#define IN6_NEXT_MULTI(step, in6m) \ >> -/* struct in6_multistep step; */ \ >> -/* struct in6_multi *in6m; */ >> \ >> +#define IN6_LOOKUP_MULTI(addr, ifp, in6m) \ >> + /* struct in6_addr addr; */ \ >> + /* struct ifnet *ifp; */ \ >> + /* struct in6_multi *in6m; */ \ >> do { \ >> - if (((in6m) = (step).i_in6m) != NULL) \ >> - (step).i_in6m = LIST_NEXT((in6m), in6m_entry); \ >> - else \ >> - while ((step).i_ia != NULL) { \ >> - (in6m) = LIST_FIRST(&(step).i_ia->ia6_multiaddrs); \ >> - (step).i_ia = TAILQ_NEXT((step).i_ia, ia_list); \ >> - if ((in6m) != NULL) { \ >> - (step).i_in6m = LIST_NEXT((in6m), in6m_entry); >> \ >> - break; \ >> - } \ >> - } \ >> -} while (0) >> - >> -#define IN6_FIRST_MULTI(step, in6m) \ >> -/* struct in6_multistep step; */ \ >> -/* struct in6_multi *in6m */ \ >> -do { \ >> - (step).i_ia = TAILQ_FIRST(&in6_ifaddr); \ >> - (step).i_in6m = NULL; \ >> - IN6_NEXT_MULTI((step), (in6m)); \ >> -} while (0) >> + struct in6_ifaddr *ia; \ >> + \ >> + (in6m) = NULL; \ >> + IN6_FOREACH_MULTI(ia, ifp, in6m) \ >> + if (IN6_ARE_ADDR_EQUAL(&(in6m)->in6m_addr, &(addr))) \ >> + break; \ >> +} while (/* CONSTCOND */ 0) >> >> struct in6_multi *in6_addmulti(struct in6_addr *, struct ifnet *, int >> *); >> void in6_delmulti(struct in6_multi *); >> Index: netinet6/mld6.c >> =================================================================== >> RCS file: /home/ncvs/src/sys/netinet6/mld6.c,v >> retrieving revision 1.28 >> diff -u -p -r1.28 mld6.c >> --- netinet6/mld6.c 24 Nov 2011 17:39:55 -0000 1.28 >> +++ netinet6/mld6.c 13 Sep 2013 09:07:42 -0000 >> @@ -89,6 +89,7 @@ static int mld_timers_are_running; >> static struct in6_addr mld_all_nodes_linklocal = >> IN6ADDR_LINKLOCAL_ALLNODES_INIT; >> static struct in6_addr mld_all_routers_linklocal = >> IN6ADDR_LINKLOCAL_ALLROUTERS_INIT; >> >> +void mld6_checktimer(struct ifnet *); >> static void mld6_sendpkt(struct in6_multi *, int, const struct in6_addr *); >> >> void >> @@ -317,10 +318,9 @@ mld6_input(struct mbuf *m, int off) >> } >> >> void >> -mld6_fasttimeo() >> +mld6_fasttimeo(void) >> { >> - struct in6_multi *in6m; >> - struct in6_multistep step; >> + struct ifnet *ifp; >> int s; >> >> /* >> @@ -332,8 +332,20 @@ mld6_fasttimeo() >> >> s = splsoftnet(); >> mld_timers_are_running = 0; >> - IN6_FIRST_MULTI(step, in6m); >> - while (in6m != NULL) { >> + TAILQ_FOREACH(ifp, &ifnet, if_list) >> + mld6_checktimer(ifp); >> + splx(s); >> +} >> + >> +void >> +mld6_checktimer(struct ifnet *ifp) >> +{ >> + struct in6_multi *in6m; >> + struct in6_ifaddr *ia; \ >> + >> + splsoftassert(IPL_SOFTNET); >> + >> + IN6_FOREACH_MULTI(ia, ifp, in6m) { >> if (in6m->in6m_timer == 0) { >> /* do nothing */ >> } else if (--in6m->in6m_timer == 0) { >> @@ -342,9 +354,7 @@ mld6_fasttimeo() >> } else { >> mld_timers_are_running = 1; >> } >> - IN6_NEXT_MULTI(step, in6m); >> } >> - splx(s); >> } >> >> static void >> > -- This message is strictly personal and the opinions expressed do not represent those of my employers, either past or present.