Skip to content

Commit 45e23cf

Browse files
authored
Merge pull request FRRouting#20552 from donaldsharp/separate_sg_rpt_sg_ifchannels
Separate sg rpt sg ifchannels and add ability to set a override-interval and a test.
2 parents 5efac74 + e2906b0 commit 45e23cf

27 files changed

+1001
-225
lines changed

doc/user/pim.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,11 @@ keyword at the end.
422422
Modify the PIM assert override interval in milliseconds on this
423423
interface (defaults to 3000).
424424

425+
.. clicmd:: ip pim override-interval (0-65535)
426+
427+
Modify the PIM LAN prune delay override interval in milliseconds on this
428+
interface (defaults to 2500).
429+
425430
.. clicmd:: ip pim [sm | dm | sm-dm]
426431

427432
Enable PIM on this interface. PIM will use this interface to form PIM

doc/user/pimv6.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,11 @@ PIMv6 Router
169169
Modify the PIM assert override interval in milliseconds on this
170170
interface (defaults to 3000).
171171

172+
.. clicmd:: ipv6 pim override-interval (0-65535)
173+
174+
Modify the PIM LAN prune delay override interval in milliseconds on this
175+
interface (defaults to 2500).
176+
172177
.. clicmd:: keep-alive-timer (1-65535)
173178
:daemon: pimv6
174179

gdb/pim.txt

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,137 @@ Example usage:
228228
To also dump the JP aggregation details, use dump_neighbor_jp_agg.
229229
end
230230

231+
define dump_pim_neighbor
232+
set $_neigh = (struct pim_neighbor *)$arg0
233+
234+
if $_neigh == 0
235+
printf "Neighbor pointer is NULL\n"
236+
else
237+
printf "========== PIM Neighbor %p ==========\n", $_neigh
238+
239+
# Source address
240+
printf "Source Address: "
241+
if sizeof($_neigh->source_addr) == 4
242+
# IPv4
243+
set $_na = (unsigned char *)&$_neigh->source_addr
244+
printf "%u.%u.%u.%u", $_na[0], $_na[1], $_na[2], $_na[3]
245+
else
246+
# IPv6
247+
dump_s6_addr &$_neigh->source_addr
248+
end
249+
printf "\n"
250+
251+
# Interface
252+
if $_neigh->interface != 0
253+
printf "Interface: %s\n", $_neigh->interface->name
254+
else
255+
printf "Interface: NULL\n"
256+
end
257+
258+
# Creation timestamp
259+
printf "Creation time: %ld\n", $_neigh->creation
260+
261+
# Hello options (bit flags)
262+
printf "Hello options: 0x%08x ", $_neigh->hello_options
263+
if $_neigh->hello_options & 0x1
264+
printf "HOLDTIME "
265+
end
266+
if $_neigh->hello_options & 0x2
267+
printf "LAN_PRUNE_DELAY "
268+
end
269+
if $_neigh->hello_options & 0x4
270+
printf "DR_PRIORITY "
271+
end
272+
if $_neigh->hello_options & 0x8
273+
printf "GENERATION_ID "
274+
end
275+
if $_neigh->hello_options & 0x10
276+
printf "ADDRESS_LIST "
277+
end
278+
printf "\n"
279+
280+
# Timers and parameters
281+
printf "Holdtime: %u sec\n", $_neigh->holdtime
282+
printf "Propagation delay: %u msec\n", $_neigh->propagation_delay_msec
283+
printf "Override interval: %u msec\n", $_neigh->override_interval_msec
284+
printf "DR priority: %u\n", $_neigh->dr_priority
285+
printf "Generation ID: 0x%08x\n", $_neigh->generation_id
286+
287+
# Prefix list (secondary addresses)
288+
if $_neigh->prefix_list != 0
289+
printf "Secondary addresses: count=%u\n", $_neigh->prefix_list->count
290+
if $_neigh->prefix_list->count > 0
291+
set $_pnode = $_neigh->prefix_list->head
292+
set $_pcount = 0
293+
while $_pnode != 0 && $_pcount < 10
294+
set $_prefix = (struct prefix *)$_pnode->data
295+
printf " [%u] family=%u prefixlen=%u\n", $_pcount, $_prefix->family, $_prefix->prefixlen
296+
set $_pnode = $_pnode->next
297+
set $_pcount = $_pcount + 1
298+
end
299+
if $_neigh->prefix_list->count > 10
300+
printf " ... (%u more)\n", $_neigh->prefix_list->count - 10
301+
end
302+
end
303+
else
304+
printf "Secondary addresses: NULL\n"
305+
end
306+
307+
# Timers
308+
printf "\nTimers:\n"
309+
if $_neigh->t_expire_timer != 0
310+
printf " Expire timer: RUNNING (expires at %ld.%06ld)\n", $_neigh->t_expire_timer->u.sands.tv_sec, $_neigh->t_expire_timer->u.sands.tv_usec
311+
else
312+
printf " Expire timer: stopped\n"
313+
end
314+
if $_neigh->jp_timer != 0
315+
printf " JP timer: RUNNING (expires at %ld.%06ld)\n", $_neigh->jp_timer->u.sands.tv_sec, $_neigh->jp_timer->u.sands.tv_usec
316+
else
317+
printf " JP timer: stopped\n"
318+
end
319+
320+
# JP Aggregation list
321+
if $_neigh->upstream_jp_agg != 0
322+
printf "\nJP Aggregation: count=%u\n", $_neigh->upstream_jp_agg->count
323+
else
324+
printf "\nJP Aggregation: NULL\n"
325+
end
326+
327+
# BFD session
328+
if $_neigh->bfd_session != 0
329+
printf "BFD session: %p (configured)\n", $_neigh->bfd_session
330+
else
331+
printf "BFD session: NULL\n"
332+
end
333+
334+
printf "========================================\n"
335+
end
336+
end
337+
document dump_pim_neighbor
338+
Dump detailed information about a PIM neighbor structure.
339+
340+
This displays comprehensive information including:
341+
- Source address and interface
342+
- Creation timestamp
343+
- Hello options (decoded bit flags)
344+
- Holdtime, propagation delay, override interval
345+
- DR priority and generation ID
346+
- Secondary address list
347+
- Timer states
348+
- JP aggregation list count
349+
- BFD session status
350+
351+
Arguments:
352+
(struct pim_neighbor *) pointer to the neighbor structure
353+
354+
Example usage:
355+
(gdb) dump_pim_neighbor neigh
356+
(gdb) p pim_ifp->pim_neighbor_list->head->data
357+
(gdb) dump_pim_neighbor $
358+
359+
To also dump the JP aggregation details, use dump_neighbor_jp_agg.
360+
end
361+
231362
define dump_neighbor_jp_agg
232363
set $_neigh = (struct pim_neighbor *)$arg0
233364

pimd/pim6_cmd.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,23 @@ DEFPY_YANG(if_ipv6_pim_assert_override_interval,
226226
return nb_cli_apply_changes(vty, FRR_PIM_INTERFACE_XPATH, FRR_PIM_AF_XPATH_VAL);
227227
}
228228

229+
DEFPY_YANG(if_ipv6_pim_override_interval,
230+
if_ipv6_pim_override_interval_cmd,
231+
"[no] ipv6 pim override-interval ![(0-65535)$oi]",
232+
NO_STR
233+
IPV6_STR
234+
PIM_STR
235+
"LAN prune delay override interval\n"
236+
"Milliseconds, default 2500\n")
237+
{
238+
if (no)
239+
nb_cli_enqueue_change(vty, "./override-interval", NB_OP_DESTROY, NULL);
240+
else
241+
nb_cli_enqueue_change(vty, "./override-interval", NB_OP_MODIFY, oi_str);
242+
243+
return nb_cli_apply_changes(vty, FRR_PIM_INTERFACE_XPATH, FRR_PIM_AF_XPATH_VAL);
244+
}
245+
229246
DEFPY (pim6_spt_switchover_infinity,
230247
pim6_spt_switchover_infinity_cmd,
231248
"spt-switchover infinity-and-beyond",
@@ -3156,6 +3173,7 @@ void pim_cmd_init(void)
31563173
install_element(INTERFACE_NODE, &no_interface_ipv6_mld_limits_cmd);
31573174
install_element(INTERFACE_NODE, &if_ipv6_pim_assert_interval_cmd);
31583175
install_element(INTERFACE_NODE, &if_ipv6_pim_assert_override_interval_cmd);
3176+
install_element(INTERFACE_NODE, &if_ipv6_pim_override_interval_cmd);
31593177

31603178
install_element(INTERFACE_NODE, &interface_ipv6_pim_use_source_cmd);
31613179

pimd/pim_cmd.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6133,6 +6133,23 @@ DEFPY_YANG(interface_ip_pim_assert_override, interface_ip_pim_assert_override_cm
61336133
return nb_cli_apply_changes(vty, FRR_PIM_INTERFACE_XPATH, FRR_PIM_AF_XPATH_VAL);
61346134
}
61356135

6136+
DEFPY_YANG(interface_ip_pim_override_interval,
6137+
interface_ip_pim_override_interval_cmd,
6138+
"[no] ip pim override-interval ![(0-65535)$oi]",
6139+
NO_STR
6140+
IP_STR
6141+
"pim multicast routing\n"
6142+
"LAN prune delay override interval\n"
6143+
"Milliseconds, default 2500\n")
6144+
{
6145+
if (no)
6146+
nb_cli_enqueue_change(vty, "./override-interval", NB_OP_DESTROY, NULL);
6147+
else
6148+
nb_cli_enqueue_change(vty, "./override-interval", NB_OP_MODIFY, oi_str);
6149+
6150+
return nb_cli_apply_changes(vty, FRR_PIM_INTERFACE_XPATH, FRR_PIM_AF_XPATH_VAL);
6151+
}
6152+
61366153
DEFUN (debug_igmp,
61376154
debug_igmp_cmd,
61386155
"debug igmp",
@@ -9480,6 +9497,7 @@ void pim_cmd_init(void)
94809497
install_element(INTERFACE_NODE, &interface_no_ip_pim_neighbor_prefix_list_cmd);
94819498
install_element(INTERFACE_NODE, &interface_ip_pim_assert_interval_cmd);
94829499
install_element(INTERFACE_NODE, &interface_ip_pim_assert_override_cmd);
9500+
install_element(INTERFACE_NODE, &interface_ip_pim_override_interval_cmd);
94839501

94849502
// Static mroutes NEB
94859503
install_element(INTERFACE_NODE, &interface_ip_mroute_cmd);

pimd/pim_cmd_common.c

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1766,10 +1766,9 @@ static void pim_show_join_helper(struct pim_interface *pim_ifp,
17661766
json_object_string_add(json_row, "upTime", uptime);
17671767
json_object_string_add(json_row, "expire", expire);
17681768
json_object_string_add(json_row, "prune", prune);
1769-
json_object_string_add(
1770-
json_row, "channelJoinName",
1771-
pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags));
1772-
if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags))
1769+
json_object_string_add(json_row, "channelJoinName",
1770+
pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->sg_rpt));
1771+
if (pim_ifchannel_is_sg_rpt(ch))
17731772
json_object_int_add(json_row, "sgRpt", 1);
17741773
if (PIM_IF_FLAG_TEST_PROTO_PIM(ch->flags))
17751774
json_object_int_add(json_row, "protocolPim", 1);
@@ -1780,19 +1779,29 @@ static void pim_show_join_helper(struct pim_interface *pim_ifp,
17801779
json_object_object_get_ex(json_iface, ch_grp_str, &json_grp);
17811780
if (!json_grp) {
17821781
json_grp = json_object_new_object();
1783-
json_object_object_addf(json_grp, json_row, "%pPAs",
1784-
&ch->sg.src);
17851782
json_object_object_addf(json_iface, json_grp, "%pPAs",
17861783
&ch->sg.grp);
1787-
} else
1788-
json_object_object_addf(json_grp, json_row, "%pPAs",
1789-
&ch->sg.src);
1784+
}
1785+
1786+
/* Generate a unique key for this channel entry.
1787+
* If this is an (S,G,rpt) channel and a regular (S,G) already exists,
1788+
* append ",S,Grpt" suffix to distinguish them.
1789+
*/
1790+
char src_key[PIM_ADDRSTRLEN + 16];
1791+
1792+
if (pim_ifchannel_is_sg_rpt(ch)) {
1793+
/* For S,G,rpt entries, append ",S,Grpt" suffix */
1794+
snprintfrr(src_key, sizeof(src_key), "%pPAs,S,Grpt", &ch->sg.src);
1795+
} else {
1796+
snprintfrr(src_key, sizeof(src_key), "%pPAs", &ch->sg.src);
1797+
}
1798+
1799+
json_object_object_add(json_grp, src_key, json_row);
17901800
} else {
1791-
ttable_add_row(
1792-
tt, "%s|%pPAs|%pPAs|%pPAs|%s|%s|%s|%s",
1793-
ch->interface->name, &ifaddr, &ch->sg.src, &ch->sg.grp,
1794-
pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags),
1795-
uptime, expire, prune);
1801+
ttable_add_row(tt, "%s|%pPAs|%pPAs|%pPAs|%s|%s|%s|%s", ch->interface->name,
1802+
&ifaddr, &ch->sg.src, &ch->sg.grp,
1803+
pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->sg_rpt), uptime,
1804+
expire, prune);
17961805
}
17971806
}
17981807

pimd/pim_dm.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ void pim_dm_recv_graft(struct interface *ifp, pim_sgaddr *sg)
236236
struct pim_upstream *up;
237237
struct pim_interface *pim_ifp = ifp->info;
238238
pim_addr group_addr = sg->grp;
239-
struct pim_ifchannel *ch;
239+
struct pim_ifchannel *ch, *throwaway;
240240

241241
if (!pim_ifp || !pim_ifp->pim_enable)
242242
return;
@@ -256,7 +256,7 @@ void pim_dm_recv_graft(struct interface *ifp, pim_sgaddr *sg)
256256
oil_if_set(up->channel_oil, pim_ifp->mroute_vif_index, 1);
257257
pim_upstream_mroute_update(up->channel_oil, __func__);
258258

259-
ch = pim_ifchannel_find(ifp, sg);
259+
pim_ifchannel_find(ifp, sg, &ch, &throwaway);
260260

261261
if (ch) {
262262
PIM_UPSTREAM_DM_UNSET_PRUNE(ch->flags);
@@ -283,7 +283,7 @@ void pim_dm_recv_prune(struct interface *ifp, struct pim_neighbor *neigh, uint16
283283
struct pim_upstream *up;
284284
struct pim_interface *pim_ifp;
285285
pim_addr group_addr = sg->grp;
286-
struct pim_ifchannel *ch;
286+
struct pim_ifchannel *ch, *throwaway;
287287

288288
struct interface *ifp2 = NULL;
289289
struct pim_interface *pim_ifp2;
@@ -332,7 +332,7 @@ void pim_dm_recv_prune(struct interface *ifp, struct pim_neighbor *neigh, uint16
332332
prune_timer_start(up);
333333
}
334334

335-
ch = pim_ifchannel_find(ifp, sg);
335+
pim_ifchannel_find(ifp, sg, &ch, &throwaway);
336336
if (!ch)
337337
ch = pim_ifchannel_add(ifp, sg, source_flags,
338338
PIM_UPSTREAM_DM_FLAG_MASK_PRUNE);

0 commit comments

Comments
 (0)