summaryrefslogtreecommitdiffstats
path: root/pimd/pim_neighbor.c
diff options
context:
space:
mode:
authorwhitespace / reindent <invalid@invalid.invalid>2017-07-17 14:03:14 +0200
committerwhitespace / reindent <invalid@invalid.invalid>2017-07-17 14:04:07 +0200
commitd62a17aedeb0eebdba98238874bb13d62c48dbf9 (patch)
tree3b319b1d61c8b85b4d1f06adf8b844bb8a9b5107 /pimd/pim_neighbor.c
parent*: add indent control files (diff)
downloadfrr-d62a17aedeb0eebdba98238874bb13d62c48dbf9.tar.xz
frr-d62a17aedeb0eebdba98238874bb13d62c48dbf9.zip
indent.py `git ls-files | pcregrep '\.[ch]$' | pcregrep -v '^(ldpd|babeld|nhrpd)/'` Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'pimd/pim_neighbor.c')
-rw-r--r--pimd/pim_neighbor.c1297
1 files changed, 645 insertions, 652 deletions
diff --git a/pimd/pim_neighbor.c b/pimd/pim_neighbor.c
index 8b8946daf..70341a375 100644
--- a/pimd/pim_neighbor.c
+++ b/pimd/pim_neighbor.c
@@ -42,66 +42,61 @@
static void dr_election_by_addr(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
- struct listnode *node;
- struct pim_neighbor *neigh;
-
- pim_ifp = ifp->info;
- zassert(pim_ifp);
-
- pim_ifp->pim_dr_addr = pim_ifp->primary_address;
-
- if (PIM_DEBUG_PIM_TRACE) {
- zlog_debug("%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;
- }
- }
+ struct pim_interface *pim_ifp;
+ struct listnode *node;
+ struct pim_neighbor *neigh;
+
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+
+ pim_ifp->pim_dr_addr = pim_ifp->primary_address;
+
+ if (PIM_DEBUG_PIM_TRACE) {
+ zlog_debug("%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;
+ }
+ }
}
static void dr_election_by_pri(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
- struct listnode *node;
- struct pim_neighbor *neigh;
- uint32_t dr_pri;
-
- pim_ifp = ifp->info;
- zassert(pim_ifp);
-
- pim_ifp->pim_dr_addr = pim_ifp->primary_address;
- dr_pri = pim_ifp->pim_dr_priority;
-
- if (PIM_DEBUG_PIM_TRACE) {
- zlog_debug("%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)) {
- if (PIM_DEBUG_PIM_TRACE) {
- 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) ||
- (
- (neigh->dr_priority == dr_pri) &&
- (ntohl(neigh->source_addr.s_addr) > ntohl(pim_ifp->pim_dr_addr.s_addr))
- )
- ) {
- pim_ifp->pim_dr_addr = neigh->source_addr;
- dr_pri = neigh->dr_priority;
- }
- }
+ struct pim_interface *pim_ifp;
+ struct listnode *node;
+ struct pim_neighbor *neigh;
+ uint32_t dr_pri;
+
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+
+ pim_ifp->pim_dr_addr = pim_ifp->primary_address;
+ dr_pri = pim_ifp->pim_dr_priority;
+
+ if (PIM_DEBUG_PIM_TRACE) {
+ zlog_debug("%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)) {
+ if (PIM_DEBUG_PIM_TRACE) {
+ 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)
+ || ((neigh->dr_priority == dr_pri)
+ && (ntohl(neigh->source_addr.s_addr)
+ > ntohl(pim_ifp->pim_dr_addr.s_addr)))) {
+ pim_ifp->pim_dr_addr = neigh->source_addr;
+ dr_pri = neigh->dr_priority;
+ }
+ }
}
/*
@@ -113,359 +108,359 @@ static void dr_election_by_pri(struct interface *ifp)
*/
int pim_if_dr_election(struct interface *ifp)
{
- struct pim_interface *pim_ifp = ifp->info;
- struct in_addr old_dr_addr;
-
- ++pim_ifp->pim_dr_election_count;
-
- old_dr_addr = pim_ifp->pim_dr_addr;
-
- if (pim_ifp->pim_dr_num_nondrpri_neighbors) {
- dr_election_by_addr(ifp);
- }
- else {
- dr_election_by_pri(ifp);
- }
-
- /* DR changed ? */
- if (old_dr_addr.s_addr != pim_ifp->pim_dr_addr.s_addr) {
-
- if (PIM_DEBUG_PIM_EVENTS) {
- char dr_old_str[INET_ADDRSTRLEN];
- char dr_new_str[INET_ADDRSTRLEN];
- 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_debug("%s: DR was %s now is %s on interface %s",
- __PRETTY_FUNCTION__,
- dr_old_str, dr_new_str, ifp->name);
- }
-
- pim_ifp->pim_dr_election_last = pim_time_monotonic_sec(); /* timestamp */
- ++pim_ifp->pim_dr_election_changes;
- pim_if_update_join_desired(pim_ifp);
- pim_if_update_could_assert(ifp);
- pim_if_update_assert_tracking_desired(ifp);
- return 1;
- }
-
- return 0;
+ struct pim_interface *pim_ifp = ifp->info;
+ struct in_addr old_dr_addr;
+
+ ++pim_ifp->pim_dr_election_count;
+
+ old_dr_addr = pim_ifp->pim_dr_addr;
+
+ if (pim_ifp->pim_dr_num_nondrpri_neighbors) {
+ dr_election_by_addr(ifp);
+ } else {
+ dr_election_by_pri(ifp);
+ }
+
+ /* DR changed ? */
+ if (old_dr_addr.s_addr != pim_ifp->pim_dr_addr.s_addr) {
+
+ if (PIM_DEBUG_PIM_EVENTS) {
+ char dr_old_str[INET_ADDRSTRLEN];
+ char dr_new_str[INET_ADDRSTRLEN];
+ 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_debug("%s: DR was %s now is %s on interface %s",
+ __PRETTY_FUNCTION__, dr_old_str, dr_new_str,
+ ifp->name);
+ }
+
+ pim_ifp->pim_dr_election_last =
+ pim_time_monotonic_sec(); /* timestamp */
+ ++pim_ifp->pim_dr_election_changes;
+ pim_if_update_join_desired(pim_ifp);
+ pim_if_update_could_assert(ifp);
+ pim_if_update_assert_tracking_desired(ifp);
+ return 1;
+ }
+
+ return 0;
}
static void update_dr_priority(struct pim_neighbor *neigh,
pim_hello_options hello_options,
uint32_t dr_priority)
{
- pim_hello_options will_set_pri; /* boolean */
- pim_hello_options bit_flip; /* boolean */
- pim_hello_options pri_change; /* boolean */
-
- will_set_pri = PIM_OPTION_IS_SET(hello_options,
- PIM_OPTION_MASK_DR_PRIORITY);
-
- bit_flip =
- (
- will_set_pri !=
- PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_DR_PRIORITY)
- );
-
- if (bit_flip) {
- struct pim_interface *pim_ifp = neigh->interface->info;
-
- /* update num. of neighbors without dr_pri */
-
- if (will_set_pri) {
- --pim_ifp->pim_dr_num_nondrpri_neighbors;
- }
- else {
- ++pim_ifp->pim_dr_num_nondrpri_neighbors;
- }
- }
-
- pri_change =
- (
- bit_flip
- ||
- (neigh->dr_priority != dr_priority)
- );
-
- if (will_set_pri) {
- neigh->dr_priority = dr_priority;
- }
- else {
- neigh->dr_priority = 0; /* cosmetic unset */
- }
-
- if (pri_change) {
- /*
- RFC 4601: 4.3.2. DR Election
-
- A router's idea of the current DR on an interface can change when a
- PIM Hello message is received, when a neighbor times out, or when a
- router's own DR Priority changes.
- */
- pim_if_dr_election(neigh->interface); // router's own DR Priority changes
- }
+ pim_hello_options will_set_pri; /* boolean */
+ pim_hello_options bit_flip; /* boolean */
+ pim_hello_options pri_change; /* boolean */
+
+ will_set_pri =
+ PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_DR_PRIORITY);
+
+ bit_flip = (will_set_pri
+ != PIM_OPTION_IS_SET(neigh->hello_options,
+ PIM_OPTION_MASK_DR_PRIORITY));
+
+ if (bit_flip) {
+ struct pim_interface *pim_ifp = neigh->interface->info;
+
+ /* update num. of neighbors without dr_pri */
+
+ if (will_set_pri) {
+ --pim_ifp->pim_dr_num_nondrpri_neighbors;
+ } else {
+ ++pim_ifp->pim_dr_num_nondrpri_neighbors;
+ }
+ }
+
+ pri_change = (bit_flip || (neigh->dr_priority != dr_priority));
+
+ if (will_set_pri) {
+ neigh->dr_priority = dr_priority;
+ } else {
+ neigh->dr_priority = 0; /* cosmetic unset */
+ }
+
+ if (pri_change) {
+ /*
+ RFC 4601: 4.3.2. DR Election
+
+ A router's idea of the current DR on an interface can change
+ when a
+ PIM Hello message is received, when a neighbor times out, or
+ when a
+ router's own DR Priority changes.
+ */
+ pim_if_dr_election(
+ neigh->interface); // router's own DR Priority changes
+ }
}
static int on_neighbor_timer(struct thread *t)
{
- struct pim_neighbor *neigh;
- struct interface *ifp;
- char msg[100];
-
- neigh = THREAD_ARG(t);
-
- ifp = neigh->interface;
-
- if (PIM_DEBUG_PIM_TRACE) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", neigh->source_addr, src_str, sizeof(src_str));
- zlog_debug("Expired %d sec holdtime for neighbor %s on interface %s",
- neigh->holdtime, src_str, ifp->name);
- }
-
- snprintf(msg, sizeof(msg), "%d-sec holdtime expired", neigh->holdtime);
- pim_neighbor_delete(ifp, neigh, msg);
-
- /*
- RFC 4601: 4.3.2. DR Election
-
- A router's idea of the current DR on an interface can change when a
- PIM Hello message is received, when a neighbor times out, or when a
- router's own DR Priority changes.
- */
- pim_if_dr_election(ifp); // neighbor times out
-
- return 0;
+ struct pim_neighbor *neigh;
+ struct interface *ifp;
+ char msg[100];
+
+ neigh = THREAD_ARG(t);
+
+ ifp = neigh->interface;
+
+ if (PIM_DEBUG_PIM_TRACE) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", neigh->source_addr, src_str,
+ sizeof(src_str));
+ zlog_debug(
+ "Expired %d sec holdtime for neighbor %s on interface %s",
+ neigh->holdtime, src_str, ifp->name);
+ }
+
+ snprintf(msg, sizeof(msg), "%d-sec holdtime expired", neigh->holdtime);
+ pim_neighbor_delete(ifp, neigh, msg);
+
+ /*
+ RFC 4601: 4.3.2. DR Election
+
+ A router's idea of the current DR on an interface can change when a
+ PIM Hello message is received, when a neighbor times out, or when a
+ router's own DR Priority changes.
+ */
+ pim_if_dr_election(ifp); // neighbor times out
+
+ return 0;
}
void pim_neighbor_timer_reset(struct pim_neighbor *neigh, uint16_t holdtime)
{
- neigh->holdtime = holdtime;
-
- THREAD_OFF(neigh->t_expire_timer);
-
- /*
- 0xFFFF is request for no holdtime
- */
- if (neigh->holdtime == 0xFFFF) {
- return;
- }
-
- if (PIM_DEBUG_PIM_TRACE_DETAIL) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", neigh->source_addr, src_str, sizeof(src_str));
- zlog_debug("%s: starting %u sec timer for neighbor %s on %s",
- __PRETTY_FUNCTION__,
- neigh->holdtime, src_str, neigh->interface->name);
- }
-
- thread_add_timer(master, on_neighbor_timer, neigh, neigh->holdtime,
- &neigh->t_expire_timer);
+ neigh->holdtime = holdtime;
+
+ THREAD_OFF(neigh->t_expire_timer);
+
+ /*
+ 0xFFFF is request for no holdtime
+ */
+ if (neigh->holdtime == 0xFFFF) {
+ return;
+ }
+
+ if (PIM_DEBUG_PIM_TRACE_DETAIL) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", neigh->source_addr, src_str,
+ sizeof(src_str));
+ zlog_debug("%s: starting %u sec timer for neighbor %s on %s",
+ __PRETTY_FUNCTION__, neigh->holdtime, src_str,
+ neigh->interface->name);
+ }
+
+ thread_add_timer(master, on_neighbor_timer, neigh, neigh->holdtime,
+ &neigh->t_expire_timer);
}
-static int
-on_neighbor_jp_timer (struct thread *t)
+static int on_neighbor_jp_timer(struct thread *t)
{
- struct pim_neighbor *neigh = THREAD_ARG(t);
- struct pim_rpf rpf;
-
- if (PIM_DEBUG_PIM_TRACE)
- {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", neigh->source_addr, src_str, sizeof(src_str));
- zlog_debug("%s:Sending JP Agg to %s on %s with %d groups", __PRETTY_FUNCTION__,
- src_str, neigh->interface->name, neigh->upstream_jp_agg->count);
- }
+ struct pim_neighbor *neigh = THREAD_ARG(t);
+ struct pim_rpf rpf;
+
+ if (PIM_DEBUG_PIM_TRACE) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", neigh->source_addr, src_str,
+ sizeof(src_str));
+ zlog_debug("%s:Sending JP Agg to %s on %s with %d groups",
+ __PRETTY_FUNCTION__, src_str, neigh->interface->name,
+ neigh->upstream_jp_agg->count);
+ }
- rpf.source_nexthop.interface = neigh->interface;
- rpf.rpf_addr.u.prefix4 = neigh->source_addr;
- pim_joinprune_send(&rpf, neigh->upstream_jp_agg);
+ rpf.source_nexthop.interface = neigh->interface;
+ rpf.rpf_addr.u.prefix4 = neigh->source_addr;
+ pim_joinprune_send(&rpf, neigh->upstream_jp_agg);
- thread_add_timer(master, on_neighbor_jp_timer, neigh, qpim_t_periodic,
- &neigh->jp_timer);
+ thread_add_timer(master, on_neighbor_jp_timer, neigh, qpim_t_periodic,
+ &neigh->jp_timer);
- return 0;
+ return 0;
}
-static void
-pim_neighbor_start_jp_timer (struct pim_neighbor *neigh)
+static void pim_neighbor_start_jp_timer(struct pim_neighbor *neigh)
{
- THREAD_TIMER_OFF(neigh->jp_timer);
- thread_add_timer(master, on_neighbor_jp_timer, neigh, qpim_t_periodic,
- &neigh->jp_timer);
+ THREAD_TIMER_OFF(neigh->jp_timer);
+ thread_add_timer(master, on_neighbor_jp_timer, neigh, qpim_t_periodic,
+ &neigh->jp_timer);
}
-static struct pim_neighbor *pim_neighbor_new(struct interface *ifp,
- struct in_addr source_addr,
- pim_hello_options hello_options,
- uint16_t holdtime,
- uint16_t propagation_delay,
- uint16_t override_interval,
- uint32_t dr_priority,
- uint32_t generation_id,
- struct list *addr_list)
+static struct pim_neighbor *
+pim_neighbor_new(struct interface *ifp, struct in_addr source_addr,
+ pim_hello_options hello_options, uint16_t holdtime,
+ uint16_t propagation_delay, uint16_t override_interval,
+ uint32_t dr_priority, uint32_t generation_id,
+ struct list *addr_list)
{
- struct pim_interface *pim_ifp;
- struct pim_neighbor *neigh;
- char src_str[INET_ADDRSTRLEN];
-
- zassert(ifp);
- pim_ifp = ifp->info;
- zassert(pim_ifp);
-
- neigh = XCALLOC(MTYPE_PIM_NEIGHBOR, sizeof(*neigh));
- if (!neigh) {
- zlog_err("%s: PIM XCALLOC(%zu) failure",
- __PRETTY_FUNCTION__, sizeof(*neigh));
- return 0;
- }
-
- neigh->creation = pim_time_monotonic_sec();
- neigh->source_addr = source_addr;
- neigh->hello_options = hello_options;
- neigh->propagation_delay_msec = propagation_delay;
- neigh->override_interval_msec = override_interval;
- neigh->dr_priority = dr_priority;
- neigh->generation_id = generation_id;
- neigh->prefix_list = addr_list;
- neigh->t_expire_timer = NULL;
- neigh->interface = ifp;
-
- neigh->upstream_jp_agg = list_new();
- neigh->upstream_jp_agg->cmp = pim_jp_agg_group_list_cmp;
- neigh->upstream_jp_agg->del = (void (*)(void *))pim_jp_agg_group_list_free;
- pim_neighbor_start_jp_timer(neigh);
-
- pim_neighbor_timer_reset(neigh, holdtime);
- /*
- * The pim_ifstat_hello_sent variable is used to decide if
- * we should expedite a hello out the interface. If we
- * establish a new neighbor, we unfortunately need to
- * reset the value so that we can know to hurry up and
- * hello
- */
- pim_ifp->pim_ifstat_hello_sent = 0;
-
- pim_inet4_dump("<src?>", source_addr, src_str, sizeof(src_str));
-
- if (PIM_DEBUG_PIM_EVENTS) {
- zlog_debug("%s: creating PIM neighbor %s on interface %s",
- __PRETTY_FUNCTION__,
- src_str, ifp->name);
- }
-
- zlog_info("PIM NEIGHBOR UP: neighbor %s on interface %s",
- src_str, ifp->name);
-
- if (neigh->propagation_delay_msec > pim_ifp->pim_neighbors_highest_propagation_delay_msec) {
- pim_ifp->pim_neighbors_highest_propagation_delay_msec = neigh->propagation_delay_msec;
- }
- if (neigh->override_interval_msec > pim_ifp->pim_neighbors_highest_override_interval_msec) {
- pim_ifp->pim_neighbors_highest_override_interval_msec = neigh->override_interval_msec;
- }
-
- if (!PIM_OPTION_IS_SET(neigh->hello_options,
- PIM_OPTION_MASK_LAN_PRUNE_DELAY)) {
- /* update num. of neighbors without hello option lan_delay */
- ++pim_ifp->pim_number_of_nonlandelay_neighbors;
- }
-
- if (!PIM_OPTION_IS_SET(neigh->hello_options,
- PIM_OPTION_MASK_DR_PRIORITY)) {
- /* update num. of neighbors without hello option dr_pri */
- ++pim_ifp->pim_dr_num_nondrpri_neighbors;
- }
-
- //Register PIM Neighbor with BFD
- pim_bfd_trigger_event (pim_ifp, neigh, 1);
-
- return neigh;
+ struct pim_interface *pim_ifp;
+ struct pim_neighbor *neigh;
+ char src_str[INET_ADDRSTRLEN];
+
+ zassert(ifp);
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+
+ neigh = XCALLOC(MTYPE_PIM_NEIGHBOR, sizeof(*neigh));
+ if (!neigh) {
+ zlog_err("%s: PIM XCALLOC(%zu) failure", __PRETTY_FUNCTION__,
+ sizeof(*neigh));
+ return 0;
+ }
+
+ neigh->creation = pim_time_monotonic_sec();
+ neigh->source_addr = source_addr;
+ neigh->hello_options = hello_options;
+ neigh->propagation_delay_msec = propagation_delay;
+ neigh->override_interval_msec = override_interval;
+ neigh->dr_priority = dr_priority;
+ neigh->generation_id = generation_id;
+ neigh->prefix_list = addr_list;
+ neigh->t_expire_timer = NULL;
+ neigh->interface = ifp;
+
+ neigh->upstream_jp_agg = list_new();
+ neigh->upstream_jp_agg->cmp = pim_jp_agg_group_list_cmp;
+ neigh->upstream_jp_agg->del =
+ (void (*)(void *))pim_jp_agg_group_list_free;
+ pim_neighbor_start_jp_timer(neigh);
+
+ pim_neighbor_timer_reset(neigh, holdtime);
+ /*
+ * The pim_ifstat_hello_sent variable is used to decide if
+ * we should expedite a hello out the interface. If we
+ * establish a new neighbor, we unfortunately need to
+ * reset the value so that we can know to hurry up and
+ * hello
+ */
+ pim_ifp->pim_ifstat_hello_sent = 0;
+
+ pim_inet4_dump("<src?>", source_addr, src_str, sizeof(src_str));
+
+ if (PIM_DEBUG_PIM_EVENTS) {
+ zlog_debug("%s: creating PIM neighbor %s on interface %s",
+ __PRETTY_FUNCTION__, src_str, ifp->name);
+ }
+
+ zlog_info("PIM NEIGHBOR UP: neighbor %s on interface %s", src_str,
+ ifp->name);
+
+ if (neigh->propagation_delay_msec
+ > pim_ifp->pim_neighbors_highest_propagation_delay_msec) {
+ pim_ifp->pim_neighbors_highest_propagation_delay_msec =
+ neigh->propagation_delay_msec;
+ }
+ if (neigh->override_interval_msec
+ > pim_ifp->pim_neighbors_highest_override_interval_msec) {
+ pim_ifp->pim_neighbors_highest_override_interval_msec =
+ neigh->override_interval_msec;
+ }
+
+ if (!PIM_OPTION_IS_SET(neigh->hello_options,
+ PIM_OPTION_MASK_LAN_PRUNE_DELAY)) {
+ /* update num. of neighbors without hello option lan_delay */
+ ++pim_ifp->pim_number_of_nonlandelay_neighbors;
+ }
+
+ if (!PIM_OPTION_IS_SET(neigh->hello_options,
+ PIM_OPTION_MASK_DR_PRIORITY)) {
+ /* update num. of neighbors without hello option dr_pri */
+ ++pim_ifp->pim_dr_num_nondrpri_neighbors;
+ }
+
+ // Register PIM Neighbor with BFD
+ pim_bfd_trigger_event(pim_ifp, neigh, 1);
+
+ return neigh;
}
static void delete_prefix_list(struct pim_neighbor *neigh)
{
- if (neigh->prefix_list) {
+ if (neigh->prefix_list) {
#ifdef DUMP_PREFIX_LIST
- struct listnode *p_node;
- struct prefix *p;
- char addr_str[10];
- int list_size = neigh->prefix_list ? (int) listcount(neigh->prefix_list) : -1;
- int i = 0;
- for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list, p_node, p)) {
- pim_inet4_dump("<addr?>", p->u.prefix4, addr_str, sizeof(addr_str));
- zlog_debug("%s: DUMP_PREFIX_LIST neigh=%x prefix_list=%x prefix=%x addr=%s [%d/%d]",
- __PRETTY_FUNCTION__,
- (unsigned) neigh, (unsigned) neigh->prefix_list, (unsigned) p,
- addr_str, i, list_size);
- ++i;
- }
+ struct listnode *p_node;
+ struct prefix *p;
+ char addr_str[10];
+ int list_size = neigh->prefix_list
+ ? (int)listcount(neigh->prefix_list)
+ : -1;
+ int i = 0;
+ for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list, p_node, p)) {
+ pim_inet4_dump("<addr?>", p->u.prefix4, addr_str,
+ sizeof(addr_str));
+ zlog_debug(
+ "%s: DUMP_PREFIX_LIST neigh=%x prefix_list=%x prefix=%x addr=%s [%d/%d]",
+ __PRETTY_FUNCTION__, (unsigned)neigh,
+ (unsigned)neigh->prefix_list, (unsigned)p,
+ addr_str, i, list_size);
+ ++i;
+ }
#endif
- list_delete(neigh->prefix_list);
- neigh->prefix_list = 0;
- }
+ list_delete(neigh->prefix_list);
+ neigh->prefix_list = 0;
+ }
}
void pim_neighbor_free(struct pim_neighbor *neigh)
{
- zassert(!neigh->t_expire_timer);
+ zassert(!neigh->t_expire_timer);
- delete_prefix_list(neigh);
+ delete_prefix_list(neigh);
- list_delete(neigh->upstream_jp_agg);
- THREAD_OFF(neigh->jp_timer);
+ list_delete(neigh->upstream_jp_agg);
+ THREAD_OFF(neigh->jp_timer);
- XFREE(MTYPE_PIM_NEIGHBOR, neigh);
+ XFREE(MTYPE_PIM_NEIGHBOR, neigh);
}
-struct pim_neighbor *
-pim_neighbor_find_by_secondary (struct interface *ifp,
- struct prefix *src)
+struct pim_neighbor *pim_neighbor_find_by_secondary(struct interface *ifp,
+ struct prefix *src)
{
- struct pim_interface *pim_ifp;
- struct listnode *node, *pnode;
- struct pim_neighbor *neigh;
- struct prefix *p;
-
- pim_ifp = ifp->info;
- if (!pim_ifp)
- return NULL;
-
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, node, neigh))
- {
- for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list, pnode, p))
- {
- if (prefix_same (p, src))
- return neigh;
- }
- }
-
- return NULL;
+ struct pim_interface *pim_ifp;
+ struct listnode *node, *pnode;
+ struct pim_neighbor *neigh;
+ struct prefix *p;
+
+ pim_ifp = ifp->info;
+ if (!pim_ifp)
+ return NULL;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, node, neigh)) {
+ for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list, pnode, p)) {
+ if (prefix_same(p, src))
+ return neigh;
+ }
+ }
+
+ return NULL;
}
struct pim_neighbor *pim_neighbor_find(struct interface *ifp,
struct in_addr source_addr)
{
- struct pim_interface *pim_ifp;
- struct listnode *node;
- struct pim_neighbor *neigh;
+ struct pim_interface *pim_ifp;
+ struct listnode *node;
+ struct pim_neighbor *neigh;
- if (!ifp)
- return NULL;
+ if (!ifp)
+ return NULL;
- pim_ifp = ifp->info;
- if (!pim_ifp)
- return NULL;
+ pim_ifp = ifp->info;
+ if (!pim_ifp)
+ return NULL;
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, node, neigh)) {
- if (source_addr.s_addr == neigh->source_addr.s_addr) {
- return neigh;
- }
- }
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, node, neigh)) {
+ if (source_addr.s_addr == neigh->source_addr.s_addr) {
+ return neigh;
+ }
+ }
- return NULL;
+ return NULL;
}
/*
@@ -473,263 +468,256 @@ struct pim_neighbor *pim_neighbor_find(struct interface *ifp,
* this interface. If more than
* one return NULL
*/
-struct pim_neighbor *
-pim_neighbor_find_if (struct interface *ifp)
+struct pim_neighbor *pim_neighbor_find_if(struct interface *ifp)
{
- struct pim_interface *pim_ifp = ifp->info;
+ struct pim_interface *pim_ifp = ifp->info;
- if (!pim_ifp || pim_ifp->pim_neighbor_list->count != 1)
- return NULL;
+ if (!pim_ifp || pim_ifp->pim_neighbor_list->count != 1)
+ return NULL;
- return listnode_head (pim_ifp->pim_neighbor_list);
+ return listnode_head(pim_ifp->pim_neighbor_list);
}
/* rpf info associated with an upstream entry needs to be re-evaluated
* when an RPF neighbor comes or goes */
-static void
-pim_neighbor_rpf_update(void)
-{
- /* XXX: for the time being piggyback on the timer used on rib changes
- * to scan and update the rpf nexthop. This is expensive processing
- * and we should be able to optimize neighbor changes differently than
- * nexthop changes. */
- sched_rpf_cache_refresh();
-}
-
-struct pim_neighbor *pim_neighbor_add(struct interface *ifp,
- struct in_addr source_addr,
- pim_hello_options hello_options,
- uint16_t holdtime,
- uint16_t propagation_delay,
- uint16_t override_interval,
- uint32_t dr_priority,
- uint32_t generation_id,
- struct list *addr_list,
- int send_hello_now)
+static void pim_neighbor_rpf_update(void)
{
- struct pim_interface *pim_ifp;
- struct pim_neighbor *neigh;
-
- neigh = pim_neighbor_new(ifp, source_addr,
- hello_options,
- holdtime,
- propagation_delay,
- override_interval,
- dr_priority,
- generation_id,
- addr_list);
- if (!neigh) {
- return 0;
- }
-
- pim_ifp = ifp->info;
- zassert(pim_ifp);
-
- listnode_add(pim_ifp->pim_neighbor_list, neigh);
-
- if (PIM_DEBUG_PIM_TRACE_DETAIL)
- {
- char str[INET_ADDRSTRLEN];
- pim_inet4_dump("<nht_nbr?>", source_addr, str, sizeof (str));
- zlog_debug ("%s: neighbor %s added ", __PRETTY_FUNCTION__, str);
- }
- /*
- RFC 4601: 4.3.2. DR Election
-
- A router's idea of the current DR on an interface can change when a
- PIM Hello message is received, when a neighbor times out, or when a
- router's own DR Priority changes.
- */
- pim_if_dr_election(neigh->interface); // new neighbor -- should not trigger dr election...
-
- /*
- RFC 4601: 4.3.1. Sending Hello Messages
-
- To allow new or rebooting routers to learn of PIM neighbors quickly,
- when a Hello message is received from a new neighbor, or a Hello
- message with a new GenID is received from an existing neighbor, a
- new Hello message should be sent on this interface after a
- randomized delay between 0 and Triggered_Hello_Delay.
-
- This is a bit silly to do it that way. If I get a new
- genid we need to send the hello *now* because we've
- lined up a bunch of join/prune messages to go out the
- interface.
- */
- if (send_hello_now)
- pim_hello_restart_now (ifp);
- else
- pim_hello_restart_triggered(neigh->interface);
-
- pim_upstream_find_new_rpf();
-
- /* RNH can send nexthop update prior to PIM neibhor UP
- in that case nexthop cache would not consider this neighbor
- as RPF.
- Upon PIM neighbor UP, iterate all RPs and update
- nexthop cache with this neighbor.
- */
- pim_resolve_rp_nh ();
-
- pim_rp_setup ();
-
- pim_neighbor_rpf_update();
- return neigh;
+ /* XXX: for the time being piggyback on the timer used on rib changes
+ * to scan and update the rpf nexthop. This is expensive processing
+ * and we should be able to optimize neighbor changes differently than
+ * nexthop changes. */
+ sched_rpf_cache_refresh();
}
-static uint16_t
-find_neighbors_next_highest_propagation_delay_msec(struct interface *ifp,
- struct pim_neighbor *highest_neigh)
+struct pim_neighbor *
+pim_neighbor_add(struct interface *ifp, struct in_addr source_addr,
+ pim_hello_options hello_options, uint16_t holdtime,
+ uint16_t propagation_delay, uint16_t override_interval,
+ uint32_t dr_priority, uint32_t generation_id,
+ struct list *addr_list, int send_hello_now)
{
- struct pim_interface *pim_ifp;
- struct listnode *neigh_node;
- struct pim_neighbor *neigh;
- uint16_t next_highest_delay_msec;
-
- pim_ifp = ifp->info;
- zassert(pim_ifp);
+ struct pim_interface *pim_ifp;
+ struct pim_neighbor *neigh;
+
+ neigh = pim_neighbor_new(ifp, source_addr, hello_options, holdtime,
+ propagation_delay, override_interval,
+ dr_priority, generation_id, addr_list);
+ if (!neigh) {
+ return 0;
+ }
- next_highest_delay_msec = pim_ifp->pim_propagation_delay_msec;
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neigh_node, neigh)) {
- if (neigh == highest_neigh)
- continue;
- if (neigh->propagation_delay_msec > next_highest_delay_msec)
- next_highest_delay_msec = neigh->propagation_delay_msec;
- }
+ listnode_add(pim_ifp->pim_neighbor_list, neigh);
- return next_highest_delay_msec;
+ if (PIM_DEBUG_PIM_TRACE_DETAIL) {
+ char str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<nht_nbr?>", source_addr, str, sizeof(str));
+ zlog_debug("%s: neighbor %s added ", __PRETTY_FUNCTION__, str);
+ }
+ /*
+ RFC 4601: 4.3.2. DR Election
+
+ A router's idea of the current DR on an interface can change when a
+ PIM Hello message is received, when a neighbor times out, or when a
+ router's own DR Priority changes.
+ */
+ pim_if_dr_election(neigh->interface); // new neighbor -- should not
+ // trigger dr election...
+
+ /*
+ RFC 4601: 4.3.1. Sending Hello Messages
+
+ To allow new or rebooting routers to learn of PIM neighbors quickly,
+ when a Hello message is received from a new neighbor, or a Hello
+ message with a new GenID is received from an existing neighbor, a
+ new Hello message should be sent on this interface after a
+ randomized delay between 0 and Triggered_Hello_Delay.
+
+ This is a bit silly to do it that way. If I get a new
+ genid we need to send the hello *now* because we've
+ lined up a bunch of join/prune messages to go out the
+ interface.
+ */
+ if (send_hello_now)
+ pim_hello_restart_now(ifp);
+ else
+ pim_hello_restart_triggered(neigh->interface);
+
+ pim_upstream_find_new_rpf();
+
+ /* RNH can send nexthop update prior to PIM neibhor UP
+ in that case nexthop cache would not consider this neighbor
+ as RPF.
+ Upon PIM neighbor UP, iterate all RPs and update
+ nexthop cache with this neighbor.
+ */
+ pim_resolve_rp_nh();
+
+ pim_rp_setup();
+
+ pim_neighbor_rpf_update();
+ return neigh;
}
-static uint16_t
-find_neighbors_next_highest_override_interval_msec(struct interface *ifp,
- struct pim_neighbor *highest_neigh)
+static uint16_t find_neighbors_next_highest_propagation_delay_msec(
+ struct interface *ifp, struct pim_neighbor *highest_neigh)
{
- struct pim_interface *pim_ifp;
- struct listnode *neigh_node;
- struct pim_neighbor *neigh;
- uint16_t next_highest_interval_msec;
-
- pim_ifp = ifp->info;
- zassert(pim_ifp);
+ struct pim_interface *pim_ifp;
+ struct listnode *neigh_node;
+ struct pim_neighbor *neigh;
+ uint16_t next_highest_delay_msec;
+
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+
+ next_highest_delay_msec = pim_ifp->pim_propagation_delay_msec;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neigh_node,
+ neigh)) {
+ if (neigh == highest_neigh)
+ continue;
+ if (neigh->propagation_delay_msec > next_highest_delay_msec)
+ next_highest_delay_msec = neigh->propagation_delay_msec;
+ }
- next_highest_interval_msec = pim_ifp->pim_override_interval_msec;
+ return next_highest_delay_msec;
+}
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neigh_node, neigh)) {
- if (neigh == highest_neigh)
- continue;
- if (neigh->override_interval_msec > next_highest_interval_msec)
- next_highest_interval_msec = neigh->override_interval_msec;
- }
+static uint16_t find_neighbors_next_highest_override_interval_msec(
+ struct interface *ifp, struct pim_neighbor *highest_neigh)
+{
+ struct pim_interface *pim_ifp;
+ struct listnode *neigh_node;
+ struct pim_neighbor *neigh;
+ uint16_t next_highest_interval_msec;
+
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+
+ next_highest_interval_msec = pim_ifp->pim_override_interval_msec;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neigh_node,
+ neigh)) {
+ if (neigh == highest_neigh)
+ continue;
+ if (neigh->override_interval_msec > next_highest_interval_msec)
+ next_highest_interval_msec =
+ neigh->override_interval_msec;
+ }
- return next_highest_interval_msec;
+ return next_highest_interval_msec;
}
-void pim_neighbor_delete(struct interface *ifp,
- struct pim_neighbor *neigh,
+void pim_neighbor_delete(struct interface *ifp, struct pim_neighbor *neigh,
const char *delete_message)
{
- struct pim_interface *pim_ifp;
- char src_str[INET_ADDRSTRLEN];
-
- pim_ifp = ifp->info;
- zassert(pim_ifp);
-
- pim_inet4_dump("<src?>", neigh->source_addr, src_str, sizeof(src_str));
- zlog_info("PIM NEIGHBOR DOWN: neighbor %s on interface %s: %s",
- src_str, ifp->name, delete_message);
+ struct pim_interface *pim_ifp;
+ char src_str[INET_ADDRSTRLEN];
- THREAD_OFF(neigh->t_expire_timer);
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
- pim_if_assert_on_neighbor_down(ifp, neigh->source_addr);
+ pim_inet4_dump("<src?>", neigh->source_addr, src_str, sizeof(src_str));
+ zlog_info("PIM NEIGHBOR DOWN: neighbor %s on interface %s: %s", src_str,
+ ifp->name, delete_message);
- if (!PIM_OPTION_IS_SET(neigh->hello_options,
- PIM_OPTION_MASK_LAN_PRUNE_DELAY)) {
- /* update num. of neighbors without hello option lan_delay */
+ THREAD_OFF(neigh->t_expire_timer);
- --pim_ifp->pim_number_of_nonlandelay_neighbors;
- }
+ pim_if_assert_on_neighbor_down(ifp, neigh->source_addr);
- if (!PIM_OPTION_IS_SET(neigh->hello_options,
- PIM_OPTION_MASK_DR_PRIORITY)) {
- /* update num. of neighbors without dr_pri */
+ if (!PIM_OPTION_IS_SET(neigh->hello_options,
+ PIM_OPTION_MASK_LAN_PRUNE_DELAY)) {
+ /* update num. of neighbors without hello option lan_delay */
- --pim_ifp->pim_dr_num_nondrpri_neighbors;
- }
-
- zassert(neigh->propagation_delay_msec <= pim_ifp->pim_neighbors_highest_propagation_delay_msec);
- zassert(neigh->override_interval_msec <= pim_ifp->pim_neighbors_highest_override_interval_msec);
+ --pim_ifp->pim_number_of_nonlandelay_neighbors;
+ }
- if (pim_if_lan_delay_enabled(ifp)) {
+ if (!PIM_OPTION_IS_SET(neigh->hello_options,
+ PIM_OPTION_MASK_DR_PRIORITY)) {
+ /* update num. of neighbors without dr_pri */
- /* will delete a neighbor with highest propagation delay? */
- if (neigh->propagation_delay_msec == pim_ifp->pim_neighbors_highest_propagation_delay_msec) {
- /* then find the next highest propagation delay */
- pim_ifp->pim_neighbors_highest_propagation_delay_msec =
- find_neighbors_next_highest_propagation_delay_msec(ifp, neigh);
- }
+ --pim_ifp->pim_dr_num_nondrpri_neighbors;
+ }
- /* will delete a neighbor with highest override interval? */
- if (neigh->override_interval_msec == pim_ifp->pim_neighbors_highest_override_interval_msec) {
- /* then find the next highest propagation delay */
- pim_ifp->pim_neighbors_highest_override_interval_msec =
- find_neighbors_next_highest_override_interval_msec(ifp, neigh);
- }
- }
+ zassert(neigh->propagation_delay_msec
+ <= pim_ifp->pim_neighbors_highest_propagation_delay_msec);
+ zassert(neigh->override_interval_msec
+ <= pim_ifp->pim_neighbors_highest_override_interval_msec);
+
+ if (pim_if_lan_delay_enabled(ifp)) {
+
+ /* will delete a neighbor with highest propagation delay? */
+ if (neigh->propagation_delay_msec
+ == pim_ifp->pim_neighbors_highest_propagation_delay_msec) {
+ /* then find the next highest propagation delay */
+ pim_ifp->pim_neighbors_highest_propagation_delay_msec =
+ find_neighbors_next_highest_propagation_delay_msec(
+ ifp, neigh);
+ }
+
+ /* will delete a neighbor with highest override interval? */
+ if (neigh->override_interval_msec
+ == pim_ifp->pim_neighbors_highest_override_interval_msec) {
+ /* then find the next highest propagation delay */
+ pim_ifp->pim_neighbors_highest_override_interval_msec =
+ find_neighbors_next_highest_override_interval_msec(
+ ifp, neigh);
+ }
+ }
- if (PIM_DEBUG_PIM_TRACE) {
- zlog_debug("%s: deleting PIM neighbor %s on interface %s",
- __PRETTY_FUNCTION__,
- src_str, ifp->name);
- }
+ if (PIM_DEBUG_PIM_TRACE) {
+ zlog_debug("%s: deleting PIM neighbor %s on interface %s",
+ __PRETTY_FUNCTION__, src_str, ifp->name);
+ }
- //De-Register PIM Neighbor with BFD
- pim_bfd_trigger_event (pim_ifp, neigh, 0);
+ // De-Register PIM Neighbor with BFD
+ pim_bfd_trigger_event(pim_ifp, neigh, 0);
- listnode_delete(pim_ifp->pim_neighbor_list, neigh);
+ listnode_delete(pim_ifp->pim_neighbor_list, neigh);
- pim_neighbor_free(neigh);
+ pim_neighbor_free(neigh);
- pim_neighbor_rpf_update();
+ pim_neighbor_rpf_update();
}
-void pim_neighbor_delete_all(struct interface *ifp,
- const char *delete_message)
+void pim_neighbor_delete_all(struct interface *ifp, const char *delete_message)
{
- struct pim_interface *pim_ifp;
- struct listnode *neigh_node;
- struct listnode *neigh_nextnode;
- struct pim_neighbor *neigh;
-
- pim_ifp = ifp->info;
- zassert(pim_ifp);
-
- for (ALL_LIST_ELEMENTS(pim_ifp->pim_neighbor_list, neigh_node,
- neigh_nextnode, neigh)) {
- pim_neighbor_delete(ifp, neigh, delete_message);
- }
+ struct pim_interface *pim_ifp;
+ struct listnode *neigh_node;
+ struct listnode *neigh_nextnode;
+ struct pim_neighbor *neigh;
+
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+
+ for (ALL_LIST_ELEMENTS(pim_ifp->pim_neighbor_list, neigh_node,
+ neigh_nextnode, neigh)) {
+ pim_neighbor_delete(ifp, neigh, delete_message);
+ }
}
struct prefix *pim_neighbor_find_secondary(struct pim_neighbor *neigh,
struct prefix *addr)
{
- struct listnode *node;
- struct prefix *p;
+ struct listnode *node;
+ struct prefix *p;
- if (!neigh->prefix_list)
- return 0;
+ if (!neigh->prefix_list)
+ return 0;
- for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list, node, p)) {
- if (prefix_same (p, addr))
- return p;
- }
+ for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list, node, p)) {
+ if (prefix_same(p, addr))
+ return p;
+ }
- return NULL;
+ return NULL;
}
/*
RFC 4601: 4.3.4. Maintaining Secondary Address Lists
-
+
All the advertised secondary addresses in received Hello messages
must be checked against those previously advertised by all other
PIM neighbors on that interface. If there is a conflict and the
@@ -742,104 +730,109 @@ static void delete_from_neigh_addr(struct interface *ifp,
struct list *addr_list,
struct in_addr neigh_addr)
{
- struct listnode *addr_node;
- struct prefix *addr;
- struct pim_interface *pim_ifp;
-
- pim_ifp = ifp->info;
- zassert(pim_ifp);
-
- zassert(addr_list);
-
- /*
- Scan secondary address list
- */
- for (ALL_LIST_ELEMENTS_RO(addr_list, addr_node,
- addr)) {
- struct listnode *neigh_node;
- struct pim_neighbor *neigh;
-
- if (addr->family != AF_INET)
- continue;
-
- /*
- Scan neighbors
- */
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neigh_node,
- neigh)) {
- {
- struct prefix *p = pim_neighbor_find_secondary(neigh, addr);
- if (p) {
- char addr_str[INET_ADDRSTRLEN];
- char this_neigh_str[INET_ADDRSTRLEN];
- char other_neigh_str[INET_ADDRSTRLEN];
-
- pim_inet4_dump("<addr?>", addr->u.prefix4, addr_str, sizeof(addr_str));
- pim_inet4_dump("<neigh1?>", neigh_addr, this_neigh_str, sizeof(this_neigh_str));
- pim_inet4_dump("<neigh2?>", neigh->source_addr, other_neigh_str, sizeof(other_neigh_str));
-
- zlog_info("secondary addr %s recvd from neigh %s deleted from neigh %s on %s",
- addr_str, this_neigh_str, other_neigh_str, ifp->name);
-
- listnode_delete(neigh->prefix_list, p);
- prefix_free(p);
- }
- }
-
- } /* scan neighbors */
-
- } /* scan addr list */
-
+ struct listnode *addr_node;
+ struct prefix *addr;
+ struct pim_interface *pim_ifp;
+
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+
+ zassert(addr_list);
+
+ /*
+ Scan secondary address list
+ */
+ for (ALL_LIST_ELEMENTS_RO(addr_list, addr_node, addr)) {
+ struct listnode *neigh_node;
+ struct pim_neighbor *neigh;
+
+ if (addr->family != AF_INET)
+ continue;
+
+ /*
+ Scan neighbors
+ */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list,
+ neigh_node, neigh)) {
+ {
+ struct prefix *p = pim_neighbor_find_secondary(
+ neigh, addr);
+ if (p) {
+ char addr_str[INET_ADDRSTRLEN];
+ char this_neigh_str[INET_ADDRSTRLEN];
+ char other_neigh_str[INET_ADDRSTRLEN];
+
+ pim_inet4_dump(
+ "<addr?>", addr->u.prefix4,
+ addr_str, sizeof(addr_str));
+ pim_inet4_dump("<neigh1?>", neigh_addr,
+ this_neigh_str,
+ sizeof(this_neigh_str));
+ pim_inet4_dump("<neigh2?>",
+ neigh->source_addr,
+ other_neigh_str,
+ sizeof(other_neigh_str));
+
+ zlog_info(
+ "secondary addr %s recvd from neigh %s deleted from neigh %s on %s",
+ addr_str, this_neigh_str,
+ other_neigh_str, ifp->name);
+
+ listnode_delete(neigh->prefix_list, p);
+ prefix_free(p);
+ }
+ }
+
+ } /* scan neighbors */
+
+ } /* scan addr list */
}
void pim_neighbor_update(struct pim_neighbor *neigh,
- pim_hello_options hello_options,
- uint16_t holdtime,
- uint32_t dr_priority,
- struct list *addr_list)
+ pim_hello_options hello_options, uint16_t holdtime,
+ uint32_t dr_priority, struct list *addr_list)
{
- struct pim_interface *pim_ifp = neigh->interface->info;
-
- /* Received holdtime ? */
- if (PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_HOLDTIME)) {
- pim_neighbor_timer_reset(neigh, holdtime);
- }
- else {
- pim_neighbor_timer_reset(neigh, PIM_IF_DEFAULT_HOLDTIME(pim_ifp));
- }
+ struct pim_interface *pim_ifp = neigh->interface->info;
+
+ /* Received holdtime ? */
+ if (PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_HOLDTIME)) {
+ pim_neighbor_timer_reset(neigh, holdtime);
+ } else {
+ pim_neighbor_timer_reset(neigh,
+ PIM_IF_DEFAULT_HOLDTIME(pim_ifp));
+ }
#ifdef DUMP_PREFIX_LIST
- zlog_debug("%s: DUMP_PREFIX_LIST old_prefix_list=%x old_size=%d new_prefix_list=%x new_size=%d",
- __PRETTY_FUNCTION__,
- (unsigned) neigh->prefix_list,
- neigh->prefix_list ? (int) listcount(neigh->prefix_list) : -1,
- (unsigned) addr_list,
- addr_list ? (int) listcount(addr_list) : -1);
+ zlog_debug(
+ "%s: DUMP_PREFIX_LIST old_prefix_list=%x old_size=%d new_prefix_list=%x new_size=%d",
+ __PRETTY_FUNCTION__, (unsigned)neigh->prefix_list,
+ neigh->prefix_list ? (int)listcount(neigh->prefix_list) : -1,
+ (unsigned)addr_list,
+ addr_list ? (int)listcount(addr_list) : -1);
#endif
- if (neigh->prefix_list == addr_list) {
- if (addr_list) {
- zlog_err("%s: internal error: trying to replace same prefix list=%p",
- __PRETTY_FUNCTION__, (void *) addr_list);
- }
- }
- else {
- /* Delete existing secondary address list */
- delete_prefix_list(neigh);
- }
-
- if (addr_list) {
- delete_from_neigh_addr(neigh->interface, addr_list, neigh->source_addr);
- }
-
- /* Replace secondary address list */
- neigh->prefix_list = addr_list;
-
- update_dr_priority(neigh,
- hello_options,
- dr_priority);
- /*
- Copy flags
- */
- neigh->hello_options = hello_options;
+ if (neigh->prefix_list == addr_list) {
+ if (addr_list) {
+ zlog_err(
+ "%s: internal error: trying to replace same prefix list=%p",
+ __PRETTY_FUNCTION__, (void *)addr_list);
+ }
+ } else {
+ /* Delete existing secondary address list */
+ delete_prefix_list(neigh);
+ }
+
+ if (addr_list) {
+ delete_from_neigh_addr(neigh->interface, addr_list,
+ neigh->source_addr);
+ }
+
+ /* Replace secondary address list */
+ neigh->prefix_list = addr_list;
+
+ update_dr_priority(neigh, hello_options, dr_priority);
+ /*
+ Copy flags
+ */
+ neigh->hello_options = hello_options;
}