summaryrefslogtreecommitdiffstats
path: root/pimd
diff options
context:
space:
mode:
authorLeonard Herve <leonard.herve@yahoo.fr>2009-08-11 15:51:52 -0300
committerEverton Marques <everton.marques@gmail.com>2009-10-02 10:44:31 -0300
commit834200830bd0a27c09465b6e23941364a149b9a3 (patch)
treeb2e849b56035fee771c7e0f841c184093658a4e4 /pimd
parent077339fc42d51afb3e936171d112b1da8519220a (diff)
downloadquagga-834200830bd0a27c09465b6e23941364a149b9a3.tar.bz2
quagga-834200830bd0a27c09465b6e23941364a149b9a3.tar.xz
[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
Diffstat (limited to 'pimd')
-rw-r--r--pimd/pim_iface.c7
-rw-r--r--pimd/pim_iface.h11
-rw-r--r--pimd/pim_igmp.h9
-rw-r--r--pimd/pim_igmpv3.c18
-rw-r--r--pimd/pim_join.c26
-rw-r--r--pimd/pim_msg.c2
-rw-r--r--pimd/pim_neighbor.c34
-rw-r--r--pimd/pim_pim.c2
8 files changed, 80 insertions, 29 deletions
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?>", old_dr_addr, dr_old_str, sizeof(dr_old_str));
- pim_inet4_dump("<new_dr?>", 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?>", old_dr_addr, dr_old_str, sizeof(dr_old_str));
+ pim_inet4_dump("<new_dr?>", 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?>", old_dr_addr, dr_old_str, sizeof(dr_old_str)); */
+ /* pim_inet4_dump("<new_dr?>", 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)