From 834200830bd0a27c09465b6e23941364a149b9a3 Mon Sep 17 00:00:00 2001 From: Leonard Herve Date: Tue, 11 Aug 2009 15:51:52 -0300 Subject: [pim] igmpv3: specific query interval set to 1 second (RFC 3376 8.8.) [pim] pim messages: encoded source address format with Sparse bit=1 (RFC 4601 4.9.1.) [pim] and Mask Len MUST be equal to 32 [pim] dr election: new traces [pim] fix triggered_hello_delay_msec randomization --- pimd/pim_iface.c | 7 ++++--- pimd/pim_iface.h | 11 ++++++----- pimd/pim_igmp.h | 9 ++++++--- pimd/pim_igmpv3.c | 18 +++++++++--------- pimd/pim_join.c | 26 ++++++++++++++++++++++++++ pimd/pim_msg.c | 2 +- pimd/pim_neighbor.c | 34 +++++++++++++++++++++++++++------- pimd/pim_pim.c | 2 +- 8 files changed, 80 insertions(+), 29 deletions(-) (limited to 'pimd') diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index b3df0189..009f87c1 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -85,9 +85,10 @@ struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim) pim_ifp->options = 0; pim_ifp->mroute_vif_index = -1; - pim_ifp->igmp_default_robustness_variable = IGMP_DEFAULT_ROBUSTNESS_VARIABLE; - pim_ifp->igmp_default_query_interval = IGMP_GENERAL_QUERY_INTERVAL; - pim_ifp->igmp_query_max_response_time_dsec = IGMP_QUERY_MAX_RESPONSE_TIME_DSEC; + pim_ifp->igmp_default_robustness_variable = IGMP_DEFAULT_ROBUSTNESS_VARIABLE; + pim_ifp->igmp_default_query_interval = IGMP_GENERAL_QUERY_INTERVAL; + pim_ifp->igmp_query_max_response_time_dsec = IGMP_QUERY_MAX_RESPONSE_TIME_DSEC; + pim_ifp->igmp_specific_query_max_response_time_dsec = IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC; /* RFC 3376: 8.3. Query Response Interval diff --git a/pimd/pim_iface.h b/pimd/pim_iface.h index 6ce866ba..bc99aafb 100644 --- a/pimd/pim_iface.h +++ b/pimd/pim_iface.h @@ -57,11 +57,12 @@ struct pim_interface { int mroute_vif_index; struct in_addr primary_address; /* remember addr to detect change */ - int igmp_default_robustness_variable; /* IGMPv3 QRV */ - int igmp_default_query_interval; /* IGMPv3 secs between general queries */ - int igmp_query_max_response_time_dsec; /* IGMPv3 Max Response Time in dsecs */ - struct list *igmp_socket_list; /* list of struct igmp_sock */ - struct list *igmp_join_list; /* list of struct igmp_join */ + int igmp_default_robustness_variable; /* IGMPv3 QRV */ + int igmp_default_query_interval; /* IGMPv3 secs between general queries */ + int igmp_query_max_response_time_dsec; /* IGMPv3 Max Response Time in dsecs for general queries */ + int igmp_specific_query_max_response_time_dsec; /* IGMPv3 Max Response Time in dsecs for specific queries */ + struct list *igmp_socket_list; /* list of struct igmp_sock */ + struct list *igmp_join_list; /* list of struct igmp_join */ int pim_sock_fd; /* PIM socket file descriptor */ struct thread *t_pim_sock_read; /* thread for reading PIM socket */ diff --git a/pimd/pim_igmp.h b/pimd/pim_igmp.h index 656147f2..95e60bf2 100644 --- a/pimd/pim_igmp.h +++ b/pimd/pim_igmp.h @@ -55,13 +55,16 @@ #define IGMP_V3_GROUP_RECORD_SOURCE_OFFSET (8) /* RFC 3376: 8.1. Robustness Variable - Default: 2 */ -#define IGMP_DEFAULT_ROBUSTNESS_VARIABLE (2) +#define IGMP_DEFAULT_ROBUSTNESS_VARIABLE (2) /* RFC 3376: 8.2. Query Interval - Default: 125 seconds */ -#define IGMP_GENERAL_QUERY_INTERVAL (125) +#define IGMP_GENERAL_QUERY_INTERVAL (125) /* RFC 3376: 8.3. Query Response Interval - Default: 100 deciseconds */ -#define IGMP_QUERY_MAX_RESPONSE_TIME_DSEC (100) +#define IGMP_QUERY_MAX_RESPONSE_TIME_DSEC (100) + +/* RFC 3376: 8.8. Last Member Query Interval - Default: 10 deciseconds */ +#define IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC (10) struct igmp_join { struct in_addr group_addr; diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c index 3ff04c91..3d3ee7ac 100644 --- a/pimd/pim_igmpv3.c +++ b/pimd/pim_igmpv3.c @@ -1006,7 +1006,7 @@ static void group_retransmit_group(struct igmp_group *group) pim_ifp = igmp->interface->info; lmqc = igmp->querier_robustness_variable; - lmqi_msec = 100 * pim_ifp->igmp_query_max_response_time_dsec; + lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec; lmqt_msec = lmqc * lmqi_msec; /* @@ -1042,7 +1042,7 @@ static void group_retransmit_group(struct igmp_group *group) 0 /* num_sources_tosend */, group->group_addr /* dst_addr */, group->group_addr /* group_addr */, - pim_ifp->igmp_query_max_response_time_dsec, + pim_ifp->igmp_specific_query_max_response_time_dsec, s_flag, igmp->querier_robustness_variable, igmp->querier_query_interval); @@ -1090,7 +1090,7 @@ static int group_retransmit_sources(struct igmp_group *group, pim_ifp = igmp->interface->info; lmqc = igmp->querier_robustness_variable; - lmqi_msec = 100 * pim_ifp->igmp_query_max_response_time_dsec; + lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec; lmqt_msec = lmqc * lmqi_msec; /* Scan all group sources */ @@ -1163,7 +1163,7 @@ static int group_retransmit_sources(struct igmp_group *group, num_sources_tosend1, group->group_addr, group->group_addr, - pim_ifp->igmp_query_max_response_time_dsec, + pim_ifp->igmp_specific_query_max_response_time_dsec, 1 /* s_flag */, igmp->querier_robustness_variable, igmp->querier_query_interval); @@ -1205,7 +1205,7 @@ static int group_retransmit_sources(struct igmp_group *group, num_sources_tosend2, group->group_addr, group->group_addr, - pim_ifp->igmp_query_max_response_time_dsec, + pim_ifp->igmp_specific_query_max_response_time_dsec, 0 /* s_flag */, igmp->querier_robustness_variable, igmp->querier_query_interval); @@ -1290,7 +1290,7 @@ static void group_retransmit_timer_on(struct igmp_group *group) igmp = group->group_igmp_sock; pim_ifp = igmp->interface->info; - lmqi_msec = 100 * pim_ifp->igmp_query_max_response_time_dsec; + lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec; if (PIM_DEBUG_IGMP_TRACE) { char group_str[100]; @@ -1359,7 +1359,7 @@ static void source_query_send_by_flag(struct igmp_group *group, pim_ifp = igmp->interface->info; lmqc = igmp->querier_robustness_variable; - lmqi_msec = 100 * pim_ifp->igmp_query_max_response_time_dsec; + lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec; lmqt_msec = lmqc * lmqi_msec; /* @@ -1519,7 +1519,7 @@ void igmp_group_timer_lower_to_lmqt(struct igmp_group *group) pim_ifp = ifp->info; ifname = ifp->name; - lmqi_dsec = pim_ifp->igmp_query_max_response_time_dsec; + lmqi_dsec = pim_ifp->igmp_specific_query_max_response_time_dsec; lmqc = igmp->querier_robustness_variable; lmqt_msec = PIM_IGMP_LMQT_MSEC(lmqi_dsec, lmqc); /* lmqt_msec = (100 * lmqi_dsec) * lmqc */ @@ -1554,7 +1554,7 @@ void igmp_source_timer_lower_to_lmqt(struct igmp_source *source) pim_ifp = ifp->info; ifname = ifp->name; - lmqi_dsec = pim_ifp->igmp_query_max_response_time_dsec; + lmqi_dsec = pim_ifp->igmp_specific_query_max_response_time_dsec; lmqc = igmp->querier_robustness_variable; lmqt_msec = PIM_IGMP_LMQT_MSEC(lmqi_dsec, lmqc); /* lmqt_msec = (100 * lmqi_dsec) * lmqc */ diff --git a/pimd/pim_join.c b/pimd/pim_join.c index ce4ec4e6..6b46759a 100644 --- a/pimd/pim_join.c +++ b/pimd/pim_join.c @@ -239,6 +239,19 @@ int pim_joinprune_recv(struct interface *ifp, if (addr_offset < 1) { return -7; } + + /* + RFC 4601: 4.9.1 Encoded Source and Group Address Formats + + Encoded-Source Address + (...) + The mask length MUST be equal to the mask length in bits for the + given Address Family and Encoding Type (32 for IPv4 native and + 128 for IPv6 native). A router SHOULD ignore any messages + received with any other mask length. + */ + if (msg_source_addr.prefixlen!=32) return; + buf += addr_offset; recv_join(ifp, neigh, msg_holdtime, @@ -257,6 +270,19 @@ int pim_joinprune_recv(struct interface *ifp, if (addr_offset < 1) { return -8; } + + /* + RFC 4601: 4.9.1 Encoded Source and Group Address Formats + + Encoded-Source Address + (...) + The mask length MUST be equal to the mask length in bits for the + given Address Family and Encoding Type (32 for IPv4 native and + 128 for IPv6 native). A router SHOULD ignore any messages + received with any other mask length. + */ + if (msg_source_addr.prefixlen!=32) return; + buf += addr_offset; recv_prune(ifp, neigh, msg_holdtime, diff --git a/pimd/pim_msg.c b/pimd/pim_msg.c index 76f78f8a..1105eaca 100644 --- a/pimd/pim_msg.c +++ b/pimd/pim_msg.c @@ -98,7 +98,7 @@ char *pim_msg_addr_encode_ipv4_source(char *buf, buf[0] = PIM_MSG_ADDRESS_FAMILY_IPV4; /* addr family */ buf[1] = '\0'; /* native encoding */ - buf[2] = '\0'; /* reserved */ + buf[2] = 4; /* reserved = 0 | S bit = 1 | W bit = 0 | R bit = 0 */ buf[3] = 32; /* mask len */ *(struct in_addr *)(buf + 4) = addr; diff --git a/pimd/pim_neighbor.c b/pimd/pim_neighbor.c index 67aa9d08..b4112edf 100644 --- a/pimd/pim_neighbor.c +++ b/pimd/pim_neighbor.c @@ -46,6 +46,10 @@ static void dr_election_by_addr(struct interface *ifp) pim_ifp->pim_dr_addr = pim_ifp->primary_address; + zlog_info("%s on interface %s", + __PRETTY_FUNCTION__, + ifp->name); + for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, node, neigh)) { if (ntohl(neigh->source_addr.s_addr) > ntohl(pim_ifp->pim_dr_addr.s_addr)) { pim_ifp->pim_dr_addr = neigh->source_addr; @@ -66,7 +70,15 @@ static void dr_election_by_pri(struct interface *ifp) pim_ifp->pim_dr_addr = pim_ifp->primary_address; dr_pri = pim_ifp->pim_dr_priority; + zlog_info("%s: dr pri %u on interface %s", + __PRETTY_FUNCTION__, + dr_pri, ifp->name); + + for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, node, neigh)) { + zlog_info("%s: neigh pri %u addr %x if dr addr %x", + __PRETTY_FUNCTION__, + neigh->dr_priority, ntohl(neigh->source_addr.s_addr) , ntohl(pim_ifp->pim_dr_addr.s_addr) ); if ( (neigh->dr_priority > dr_pri) || ( @@ -91,6 +103,8 @@ void pim_if_dr_election(struct interface *ifp) { struct pim_interface *pim_ifp = ifp->info; struct in_addr old_dr_addr; + char dr_old_str[100]; + char dr_new_str[100]; pim_ifp->pim_dr_election_last = pim_time_monotonic_sec(); /* timestamp */ ++pim_ifp->pim_dr_election_count; @@ -104,16 +118,22 @@ void pim_if_dr_election(struct interface *ifp) dr_election_by_pri(ifp); } - /* DR changed ? */ - if (old_dr_addr.s_addr != pim_ifp->pim_dr_addr.s_addr) { - char dr_old_str[100]; - char dr_new_str[100]; - pim_inet4_dump("", old_dr_addr, dr_old_str, sizeof(dr_old_str)); - pim_inet4_dump("", pim_ifp->pim_dr_addr, dr_new_str, sizeof(dr_new_str)); - zlog_info("%s: DR was %s now is %s on interface %s", + pim_inet4_dump("", old_dr_addr, dr_old_str, sizeof(dr_old_str)); + pim_inet4_dump("", pim_ifp->pim_dr_addr, dr_new_str, sizeof(dr_new_str)); + zlog_info("%s: DR was %s now is %s on interface %s", __PRETTY_FUNCTION__, dr_old_str, dr_new_str, ifp->name); + /* DR changed ? */ + if (old_dr_addr.s_addr != pim_ifp->pim_dr_addr.s_addr) { + /* char dr_old_str[100]; */ + /* char dr_new_str[100]; */ + /* pim_inet4_dump("", old_dr_addr, dr_old_str, sizeof(dr_old_str)); */ + /* pim_inet4_dump("", pim_ifp->pim_dr_addr, dr_new_str, sizeof(dr_new_str)); */ + /* zlog_info("%s: DR was %s now is %s on interface %s", */ + /* __PRETTY_FUNCTION__, */ + /* dr_old_str, dr_new_str, ifp->name); */ + pim_if_update_join_desired(pim_ifp); pim_if_update_could_assert(ifp); pim_if_update_assert_tracking_desired(ifp); diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c index dd78b904..9b6dc359 100644 --- a/pimd/pim_pim.c +++ b/pimd/pim_pim.c @@ -674,7 +674,7 @@ void pim_hello_restart_triggered(struct interface *ifp) THREAD_TIMER_MSEC_ON(master, pim_ifp->t_pim_hello_timer, on_pim_hello_send, - ifp, triggered_hello_delay_msec); + ifp, random_msec); } int pim_sock_add(struct interface *ifp) -- cgit v1.2.3