summaryrefslogtreecommitdiffstats
path: root/pimd
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
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')
-rw-r--r--pimd/pim_assert.c1095
-rw-r--r--pimd/pim_assert.h23
-rw-r--r--pimd/pim_bfd.c474
-rw-r--r--pimd/pim_bfd.h24
-rw-r--r--pimd/pim_br.c99
-rw-r--r--pimd/pim_br.h8
-rw-r--r--pimd/pim_cmd.c10300
-rw-r--r--pimd/pim_hello.c878
-rw-r--r--pimd/pim_hello.h14
-rw-r--r--pimd/pim_iface.c2417
-rw-r--r--pimd/pim_iface.h160
-rw-r--r--pimd/pim_ifchannel.c2254
-rw-r--r--pimd/pim_ifchannel.h119
-rw-r--r--pimd/pim_igmp.c1807
-rw-r--r--pimd/pim_igmp.h164
-rw-r--r--pimd/pim_igmp_join.h45
-rw-r--r--pimd/pim_igmpv2.c294
-rw-r--r--pimd/pim_igmpv2.h21
-rw-r--r--pimd/pim_igmpv3.c3451
-rw-r--r--pimd/pim_igmpv3.h59
-rw-r--r--pimd/pim_int.c20
-rw-r--r--pimd/pim_join.c918
-rw-r--r--pimd/pim_join.h10
-rw-r--r--pimd/pim_jp_agg.c495
-rw-r--r--pimd/pim_jp_agg.h40
-rw-r--r--pimd/pim_macro.c352
-rw-r--r--pimd/pim_macro.h3
-rw-r--r--pimd/pim_main.c162
-rw-r--r--pimd/pim_memory.c50
-rw-r--r--pimd/pim_mroute.c1568
-rw-r--r--pimd/pim_mroute.h68
-rw-r--r--pimd/pim_msdp.c2337
-rw-r--r--pimd/pim_msdp.h270
-rw-r--r--pimd/pim_msdp_packet.c1128
-rw-r--r--pimd/pim_msdp_packet.h4
-rw-r--r--pimd/pim_msdp_socket.c366
-rw-r--r--pimd/pim_msg.c341
-rw-r--r--pimd/pim_msg.h86
-rw-r--r--pimd/pim_neighbor.c1297
-rw-r--r--pimd/pim_neighbor.h62
-rw-r--r--pimd/pim_nht.c1949
-rw-r--r--pimd/pim_nht.h68
-rw-r--r--pimd/pim_oil.c784
-rw-r--r--pimd/pim_oil.h59
-rw-r--r--pimd/pim_pim.c1407
-rw-r--r--pimd/pim_pim.h26
-rw-r--r--pimd/pim_register.c617
-rw-r--r--pimd/pim_register.h22
-rw-r--r--pimd/pim_routemap.c56
-rw-r--r--pimd/pim_rp.c1640
-rw-r--r--pimd/pim_rp.h41
-rw-r--r--pimd/pim_rpf.c620
-rw-r--r--pimd/pim_rpf.h38
-rw-r--r--pimd/pim_signals.c51
-rw-r--r--pimd/pim_sock.c653
-rw-r--r--pimd/pim_sock.h17
-rw-r--r--pimd/pim_ssm.c190
-rw-r--r--pimd/pim_ssm.h26
-rw-r--r--pimd/pim_ssmpingd.c685
-rw-r--r--pimd/pim_ssmpingd.h10
-rw-r--r--pimd/pim_static.c598
-rw-r--r--pimd/pim_static.h20
-rw-r--r--pimd/pim_str.c84
-rw-r--r--pimd/pim_str.h10
-rw-r--r--pimd/pim_time.c158
-rw-r--r--pimd/pim_tlv.c1227
-rw-r--r--pimd/pim_tlv.h59
-rw-r--r--pimd/pim_upstream.c2515
-rw-r--r--pimd/pim_upstream.h162
-rw-r--r--pimd/pim_util.c130
-rw-r--r--pimd/pim_util.h4
-rw-r--r--pimd/pim_version.c2
-rw-r--r--pimd/pim_version.h2
-rw-r--r--pimd/pim_vty.c537
-rw-r--r--pimd/pim_zebra.c1994
-rw-r--r--pimd/pim_zebra.h6
-rw-r--r--pimd/pim_zlookup.c883
-rw-r--r--pimd/pim_zlookup.h19
-rw-r--r--pimd/pimd.c393
-rw-r--r--pimd/pimd.h97
-rw-r--r--pimd/test_igmpv3_join.c198
81 files changed, 25935 insertions, 25405 deletions
diff --git a/pimd/pim_assert.c b/pimd/pim_assert.c
index 37515cee5..f68c252a3 100644
--- a/pimd/pim_assert.c
+++ b/pimd/pim_assert.c
@@ -42,283 +42,280 @@ static void assert_action_a2(struct pim_ifchannel *ch,
static void assert_action_a6(struct pim_ifchannel *ch,
struct pim_assert_metric winner_metric);
-void pim_ifassert_winner_set(struct pim_ifchannel *ch,
- enum pim_ifassert_state new_state,
- struct in_addr winner,
- struct pim_assert_metric winner_metric)
+void pim_ifassert_winner_set(struct pim_ifchannel *ch,
+ enum pim_ifassert_state new_state,
+ struct in_addr winner,
+ struct pim_assert_metric winner_metric)
{
- int winner_changed = (ch->ifassert_winner.s_addr != winner.s_addr);
- int metric_changed = !pim_assert_metric_match(&ch->ifassert_winner_metric,
- &winner_metric);
-
- if (PIM_DEBUG_PIM_EVENTS) {
- if (ch->ifassert_state != new_state) {
- zlog_debug("%s: (S,G)=%s assert state changed from %s to %s on interface %s",
- __PRETTY_FUNCTION__,
- ch->sg_str,
- pim_ifchannel_ifassert_name(ch->ifassert_state),
- pim_ifchannel_ifassert_name(new_state),
- ch->interface->name);
- }
-
- if (winner_changed) {
- char was_str[INET_ADDRSTRLEN];
- char winner_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<was?>", ch->ifassert_winner, was_str, sizeof(was_str));
- pim_inet4_dump("<winner?>", winner, winner_str, sizeof(winner_str));
- zlog_debug("%s: (S,G)=%s assert winner changed from %s to %s on interface %s",
- __PRETTY_FUNCTION__,
- ch->sg_str,
- was_str, winner_str, ch->interface->name);
- }
- } /* PIM_DEBUG_PIM_EVENTS */
-
- ch->ifassert_state = new_state;
- ch->ifassert_winner = winner;
- ch->ifassert_winner_metric = winner_metric;
- ch->ifassert_creation = pim_time_monotonic_sec();
-
- if (winner_changed || metric_changed) {
- pim_upstream_update_join_desired(ch->upstream);
- pim_ifchannel_update_could_assert(ch);
- pim_ifchannel_update_assert_tracking_desired(ch);
- }
+ int winner_changed = (ch->ifassert_winner.s_addr != winner.s_addr);
+ int metric_changed = !pim_assert_metric_match(
+ &ch->ifassert_winner_metric, &winner_metric);
+
+ if (PIM_DEBUG_PIM_EVENTS) {
+ if (ch->ifassert_state != new_state) {
+ zlog_debug(
+ "%s: (S,G)=%s assert state changed from %s to %s on interface %s",
+ __PRETTY_FUNCTION__, ch->sg_str,
+ pim_ifchannel_ifassert_name(ch->ifassert_state),
+ pim_ifchannel_ifassert_name(new_state),
+ ch->interface->name);
+ }
+
+ if (winner_changed) {
+ char was_str[INET_ADDRSTRLEN];
+ char winner_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<was?>", ch->ifassert_winner, was_str,
+ sizeof(was_str));
+ pim_inet4_dump("<winner?>", winner, winner_str,
+ sizeof(winner_str));
+ zlog_debug(
+ "%s: (S,G)=%s assert winner changed from %s to %s on interface %s",
+ __PRETTY_FUNCTION__, ch->sg_str, was_str,
+ winner_str, ch->interface->name);
+ }
+ } /* PIM_DEBUG_PIM_EVENTS */
+
+ ch->ifassert_state = new_state;
+ ch->ifassert_winner = winner;
+ ch->ifassert_winner_metric = winner_metric;
+ ch->ifassert_creation = pim_time_monotonic_sec();
+
+ if (winner_changed || metric_changed) {
+ pim_upstream_update_join_desired(ch->upstream);
+ pim_ifchannel_update_could_assert(ch);
+ pim_ifchannel_update_assert_tracking_desired(ch);
+ }
}
-static void on_trace(const char *label,
- struct interface *ifp, struct in_addr src)
+static void on_trace(const char *label, struct interface *ifp,
+ struct in_addr src)
{
- if (PIM_DEBUG_PIM_TRACE) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src, src_str, sizeof(src_str));
- zlog_debug("%s: from %s on %s",
- label, src_str, ifp->name);
- }
+ if (PIM_DEBUG_PIM_TRACE) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src, src_str, sizeof(src_str));
+ zlog_debug("%s: from %s on %s", label, src_str, ifp->name);
+ }
}
static int preferred_assert(const struct pim_ifchannel *ch,
const struct pim_assert_metric *recv_metric)
{
- return pim_assert_metric_better(recv_metric,
- &ch->ifassert_winner_metric);
+ return pim_assert_metric_better(recv_metric,
+ &ch->ifassert_winner_metric);
}
static int acceptable_assert(const struct pim_assert_metric *my_metric,
const struct pim_assert_metric *recv_metric)
{
- return pim_assert_metric_better(recv_metric,
- my_metric);
+ return pim_assert_metric_better(recv_metric, my_metric);
}
static int inferior_assert(const struct pim_assert_metric *my_metric,
const struct pim_assert_metric *recv_metric)
{
- return pim_assert_metric_better(my_metric,
- recv_metric);
+ return pim_assert_metric_better(my_metric, recv_metric);
}
static int cancel_assert(const struct pim_assert_metric *recv_metric)
{
- return (recv_metric->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
- &&
- (recv_metric->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX);
+ return (recv_metric->metric_preference
+ == PIM_ASSERT_METRIC_PREFERENCE_MAX)
+ && (recv_metric->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX);
}
-static void if_could_assert_do_a1(const char *caller,
- struct pim_ifchannel *ch)
+static void if_could_assert_do_a1(const char *caller, struct pim_ifchannel *ch)
{
- if (PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags)) {
- if (assert_action_a1(ch)) {
- zlog_warn("%s: %s: (S,G)=%s assert_action_a1 failure on interface %s",
- __PRETTY_FUNCTION__, caller,
- ch->sg_str, ch->interface->name);
- /* log warning only */
- }
- }
+ if (PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags)) {
+ if (assert_action_a1(ch)) {
+ zlog_warn(
+ "%s: %s: (S,G)=%s assert_action_a1 failure on interface %s",
+ __PRETTY_FUNCTION__, caller, ch->sg_str,
+ ch->interface->name);
+ /* log warning only */
+ }
+ }
}
-static int dispatch_assert(struct interface *ifp,
- struct in_addr source_addr,
+static int dispatch_assert(struct interface *ifp, struct in_addr source_addr,
struct in_addr group_addr,
struct pim_assert_metric recv_metric)
{
- struct pim_ifchannel *ch;
- struct prefix_sg sg;
-
- memset (&sg, 0, sizeof (struct prefix_sg));
- sg.src = source_addr;
- sg.grp = group_addr;
- ch = pim_ifchannel_add(ifp, &sg, 0);
- if (!ch) {
- zlog_warn("%s: (S,G)=%s failure creating channel on interface %s",
- __PRETTY_FUNCTION__,
- pim_str_sg_dump (&sg), ifp->name);
- return -1;
- }
-
- switch (ch->ifassert_state) {
- case PIM_IFASSERT_NOINFO:
- if (recv_metric.rpt_bit_flag) {
- /* RPT bit set */
- if_could_assert_do_a1(__PRETTY_FUNCTION__, ch);
- }
- else {
- /* RPT bit clear */
- if (inferior_assert(&ch->ifassert_my_metric, &recv_metric)) {
- if_could_assert_do_a1(__PRETTY_FUNCTION__, ch);
- }
- else if (acceptable_assert(&ch->ifassert_my_metric, &recv_metric)) {
- if (PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags)) {
- assert_action_a6(ch, recv_metric);
- }
- }
- }
- break;
- case PIM_IFASSERT_I_AM_WINNER:
- if (preferred_assert(ch, &recv_metric)) {
- assert_action_a2(ch, recv_metric);
- }
- else {
- if (inferior_assert(&ch->ifassert_my_metric, &recv_metric)) {
- assert_action_a3(ch);
- }
- }
- break;
- case PIM_IFASSERT_I_AM_LOSER:
- if (recv_metric.ip_address.s_addr == ch->ifassert_winner.s_addr) {
- /* Assert from current winner */
-
- if (cancel_assert(&recv_metric)) {
- assert_action_a5(ch);
- }
- else {
- if (inferior_assert(&ch->ifassert_my_metric, &recv_metric)) {
- assert_action_a5(ch);
- }
- else if (acceptable_assert(&ch->ifassert_my_metric, &recv_metric)) {
- if (!recv_metric.rpt_bit_flag) {
- assert_action_a2(ch, recv_metric);
- }
- }
- }
- }
- else if (preferred_assert(ch, &recv_metric)) {
- assert_action_a2(ch, recv_metric);
- }
- break;
- default:
- {
- zlog_warn("%s: (S,G)=%s invalid assert state %d on interface %s",
- __PRETTY_FUNCTION__,
- ch->sg_str, ch->ifassert_state, ifp->name);
- }
- return -2;
- }
-
- return 0;
+ struct pim_ifchannel *ch;
+ struct prefix_sg sg;
+
+ memset(&sg, 0, sizeof(struct prefix_sg));
+ sg.src = source_addr;
+ sg.grp = group_addr;
+ ch = pim_ifchannel_add(ifp, &sg, 0);
+ if (!ch) {
+ zlog_warn(
+ "%s: (S,G)=%s failure creating channel on interface %s",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(&sg), ifp->name);
+ return -1;
+ }
+
+ switch (ch->ifassert_state) {
+ case PIM_IFASSERT_NOINFO:
+ if (recv_metric.rpt_bit_flag) {
+ /* RPT bit set */
+ if_could_assert_do_a1(__PRETTY_FUNCTION__, ch);
+ } else {
+ /* RPT bit clear */
+ if (inferior_assert(&ch->ifassert_my_metric,
+ &recv_metric)) {
+ if_could_assert_do_a1(__PRETTY_FUNCTION__, ch);
+ } else if (acceptable_assert(&ch->ifassert_my_metric,
+ &recv_metric)) {
+ if (PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(
+ ch->flags)) {
+ assert_action_a6(ch, recv_metric);
+ }
+ }
+ }
+ break;
+ case PIM_IFASSERT_I_AM_WINNER:
+ if (preferred_assert(ch, &recv_metric)) {
+ assert_action_a2(ch, recv_metric);
+ } else {
+ if (inferior_assert(&ch->ifassert_my_metric,
+ &recv_metric)) {
+ assert_action_a3(ch);
+ }
+ }
+ break;
+ case PIM_IFASSERT_I_AM_LOSER:
+ if (recv_metric.ip_address.s_addr
+ == ch->ifassert_winner.s_addr) {
+ /* Assert from current winner */
+
+ if (cancel_assert(&recv_metric)) {
+ assert_action_a5(ch);
+ } else {
+ if (inferior_assert(&ch->ifassert_my_metric,
+ &recv_metric)) {
+ assert_action_a5(ch);
+ } else if (acceptable_assert(
+ &ch->ifassert_my_metric,
+ &recv_metric)) {
+ if (!recv_metric.rpt_bit_flag) {
+ assert_action_a2(ch,
+ recv_metric);
+ }
+ }
+ }
+ } else if (preferred_assert(ch, &recv_metric)) {
+ assert_action_a2(ch, recv_metric);
+ }
+ break;
+ default: {
+ zlog_warn(
+ "%s: (S,G)=%s invalid assert state %d on interface %s",
+ __PRETTY_FUNCTION__, ch->sg_str, ch->ifassert_state,
+ ifp->name);
+ }
+ return -2;
+ }
+
+ return 0;
}
-int pim_assert_recv(struct interface *ifp,
- struct pim_neighbor *neigh,
- struct in_addr src_addr,
- uint8_t *buf, int buf_size)
+int pim_assert_recv(struct interface *ifp, struct pim_neighbor *neigh,
+ struct in_addr src_addr, uint8_t *buf, int buf_size)
{
- struct prefix_sg sg;
- struct prefix msg_source_addr;
- struct pim_assert_metric msg_metric;
- int offset;
- uint8_t *curr;
- int curr_size;
- struct pim_interface *pim_ifp = NULL;
-
- on_trace(__PRETTY_FUNCTION__, ifp, src_addr);
-
- curr = buf;
- curr_size = buf_size;
-
- /*
- Parse assert group addr
- */
- memset (&sg, 0, sizeof (struct prefix_sg));
- offset = pim_parse_addr_group (&sg, curr, curr_size);
- if (offset < 1) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_warn("%s: pim_parse_addr_group() failure: from %s on %s",
- __PRETTY_FUNCTION__,
- src_str, ifp->name);
- return -1;
- }
- curr += offset;
- curr_size -= offset;
-
- /*
- Parse assert source addr
- */
- offset = pim_parse_addr_ucast (&msg_source_addr, curr, curr_size);
- if (offset < 1) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_warn("%s: pim_parse_addr_ucast() failure: from %s on %s",
- __PRETTY_FUNCTION__,
- src_str, ifp->name);
- return -2;
- }
- curr += offset;
- curr_size -= offset;
-
- if (curr_size != 8) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_warn("%s: preference/metric size is not 8: size=%d from %s on interface %s",
- __PRETTY_FUNCTION__,
- curr_size,
- src_str, ifp->name);
- return -3;
- }
-
- /*
- Parse assert metric preference
- */
-
- msg_metric.metric_preference = pim_read_uint32_host(curr);
-
- msg_metric.rpt_bit_flag = msg_metric.metric_preference & 0x80000000; /* save highest bit */
- msg_metric.metric_preference &= ~0x80000000; /* clear highest bit */
-
- curr += 4;
-
- /*
- Parse assert route metric
- */
-
- msg_metric.route_metric = pim_read_uint32_host(curr);
-
- if (PIM_DEBUG_PIM_TRACE) {
- char neigh_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<neigh?>", src_addr, neigh_str, sizeof(neigh_str));
- pim_inet4_dump("<src?>", msg_source_addr.u.prefix4, source_str, sizeof(source_str));
- pim_inet4_dump("<grp?>", sg.grp, group_str, sizeof(group_str));
- zlog_debug("%s: from %s on %s: (S,G)=(%s,%s) pref=%u metric=%u rpt_bit=%u",
- __PRETTY_FUNCTION__, neigh_str, ifp->name,
- source_str, group_str,
- msg_metric.metric_preference,
- msg_metric.route_metric,
- PIM_FORCE_BOOLEAN(msg_metric.rpt_bit_flag));
- }
-
- msg_metric.ip_address = src_addr;
-
- pim_ifp = ifp->info;
- zassert(pim_ifp);
- ++pim_ifp->pim_ifstat_assert_recv;
-
- return dispatch_assert(ifp,
- msg_source_addr.u.prefix4,
- sg.grp,
- msg_metric);
+ struct prefix_sg sg;
+ struct prefix msg_source_addr;
+ struct pim_assert_metric msg_metric;
+ int offset;
+ uint8_t *curr;
+ int curr_size;
+ struct pim_interface *pim_ifp = NULL;
+
+ on_trace(__PRETTY_FUNCTION__, ifp, src_addr);
+
+ curr = buf;
+ curr_size = buf_size;
+
+ /*
+ Parse assert group addr
+ */
+ memset(&sg, 0, sizeof(struct prefix_sg));
+ offset = pim_parse_addr_group(&sg, curr, curr_size);
+ if (offset < 1) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ zlog_warn("%s: pim_parse_addr_group() failure: from %s on %s",
+ __PRETTY_FUNCTION__, src_str, ifp->name);
+ return -1;
+ }
+ curr += offset;
+ curr_size -= offset;
+
+ /*
+ Parse assert source addr
+ */
+ offset = pim_parse_addr_ucast(&msg_source_addr, curr, curr_size);
+ if (offset < 1) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ zlog_warn("%s: pim_parse_addr_ucast() failure: from %s on %s",
+ __PRETTY_FUNCTION__, src_str, ifp->name);
+ return -2;
+ }
+ curr += offset;
+ curr_size -= offset;
+
+ if (curr_size != 8) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ zlog_warn(
+ "%s: preference/metric size is not 8: size=%d from %s on interface %s",
+ __PRETTY_FUNCTION__, curr_size, src_str, ifp->name);
+ return -3;
+ }
+
+ /*
+ Parse assert metric preference
+ */
+
+ msg_metric.metric_preference = pim_read_uint32_host(curr);
+
+ msg_metric.rpt_bit_flag = msg_metric.metric_preference
+ & 0x80000000; /* save highest bit */
+ msg_metric.metric_preference &= ~0x80000000; /* clear highest bit */
+
+ curr += 4;
+
+ /*
+ Parse assert route metric
+ */
+
+ msg_metric.route_metric = pim_read_uint32_host(curr);
+
+ if (PIM_DEBUG_PIM_TRACE) {
+ char neigh_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<neigh?>", src_addr, neigh_str,
+ sizeof(neigh_str));
+ pim_inet4_dump("<src?>", msg_source_addr.u.prefix4, source_str,
+ sizeof(source_str));
+ pim_inet4_dump("<grp?>", sg.grp, group_str, sizeof(group_str));
+ zlog_debug(
+ "%s: from %s on %s: (S,G)=(%s,%s) pref=%u metric=%u rpt_bit=%u",
+ __PRETTY_FUNCTION__, neigh_str, ifp->name, source_str,
+ group_str, msg_metric.metric_preference,
+ msg_metric.route_metric,
+ PIM_FORCE_BOOLEAN(msg_metric.rpt_bit_flag));
+ }
+
+ msg_metric.ip_address = src_addr;
+
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+ ++pim_ifp->pim_ifstat_assert_recv;
+
+ return dispatch_assert(ifp, msg_source_addr.u.prefix4, sg.grp,
+ msg_metric);
}
/*
@@ -335,167 +332,164 @@ int pim_assert_recv(struct interface *ifp,
int pim_assert_metric_better(const struct pim_assert_metric *m1,
const struct pim_assert_metric *m2)
{
- if (m1->rpt_bit_flag < m2->rpt_bit_flag)
- return 1;
- if (m1->rpt_bit_flag > m2->rpt_bit_flag)
- return 0;
-
- if (m1->metric_preference < m2->metric_preference)
- return 1;
- if (m1->metric_preference > m2->metric_preference)
- return 0;
-
- if (m1->route_metric < m2->route_metric)
- return 1;
- if (m1->route_metric > m2->route_metric)
- return 0;
-
- return ntohl(m1->ip_address.s_addr) > ntohl(m2->ip_address.s_addr);
+ if (m1->rpt_bit_flag < m2->rpt_bit_flag)
+ return 1;
+ if (m1->rpt_bit_flag > m2->rpt_bit_flag)
+ return 0;
+
+ if (m1->metric_preference < m2->metric_preference)
+ return 1;
+ if (m1->metric_preference > m2->metric_preference)
+ return 0;
+
+ if (m1->route_metric < m2->route_metric)
+ return 1;
+ if (m1->route_metric > m2->route_metric)
+ return 0;
+
+ return ntohl(m1->ip_address.s_addr) > ntohl(m2->ip_address.s_addr);
}
int pim_assert_metric_match(const struct pim_assert_metric *m1,
const struct pim_assert_metric *m2)
{
- if (m1->rpt_bit_flag != m2->rpt_bit_flag)
- return 0;
- if (m1->metric_preference != m2->metric_preference)
- return 0;
- if (m1->route_metric != m2->route_metric)
- return 0;
-
- return m1->ip_address.s_addr == m2->ip_address.s_addr;
+ if (m1->rpt_bit_flag != m2->rpt_bit_flag)
+ return 0;
+ if (m1->metric_preference != m2->metric_preference)
+ return 0;
+ if (m1->route_metric != m2->route_metric)
+ return 0;
+
+ return m1->ip_address.s_addr == m2->ip_address.s_addr;
}
-int pim_assert_build_msg(uint8_t *pim_msg, int buf_size,
- struct interface *ifp,
- struct in_addr group_addr,
- struct in_addr source_addr,
- uint32_t metric_preference,
- uint32_t route_metric,
+int pim_assert_build_msg(uint8_t *pim_msg, int buf_size, struct interface *ifp,
+ struct in_addr group_addr, struct in_addr source_addr,
+ uint32_t metric_preference, uint32_t route_metric,
uint32_t rpt_bit_flag)
{
- uint8_t *buf_pastend = pim_msg + buf_size;
- uint8_t *pim_msg_curr;
- int pim_msg_size;
- int remain;
-
- pim_msg_curr = pim_msg + PIM_MSG_HEADER_LEN; /* skip room for pim header */
-
- /* Encode group */
- remain = buf_pastend - pim_msg_curr;
- pim_msg_curr = pim_msg_addr_encode_ipv4_group(pim_msg_curr, group_addr);
- if (!pim_msg_curr) {
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
- zlog_warn("%s: failure encoding group address %s: space left=%d",
- __PRETTY_FUNCTION__, group_str, remain);
- return -1;
- }
-
- /* Encode source */
- remain = buf_pastend - pim_msg_curr;
- pim_msg_curr = pim_msg_addr_encode_ipv4_ucast(pim_msg_curr, source_addr);
- if (!pim_msg_curr) {
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- zlog_warn("%s: failure encoding source address %s: space left=%d",
- __PRETTY_FUNCTION__, source_str, remain);
- return -2;
- }
-
- /* Metric preference */
- pim_write_uint32(pim_msg_curr, rpt_bit_flag ?
- metric_preference | 0x80000000 :
- metric_preference);
- pim_msg_curr += 4;
-
- /* Route metric */
- pim_write_uint32(pim_msg_curr, route_metric);
- pim_msg_curr += 4;
-
- /*
- Add PIM header
- */
- pim_msg_size = pim_msg_curr - pim_msg;
- pim_msg_build_header(pim_msg, pim_msg_size,
- PIM_MSG_TYPE_ASSERT);
-
- return pim_msg_size;
+ uint8_t *buf_pastend = pim_msg + buf_size;
+ uint8_t *pim_msg_curr;
+ int pim_msg_size;
+ int remain;
+
+ pim_msg_curr =
+ pim_msg + PIM_MSG_HEADER_LEN; /* skip room for pim header */
+
+ /* Encode group */
+ remain = buf_pastend - pim_msg_curr;
+ pim_msg_curr = pim_msg_addr_encode_ipv4_group(pim_msg_curr, group_addr);
+ if (!pim_msg_curr) {
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<grp?>", group_addr, group_str,
+ sizeof(group_str));
+ zlog_warn(
+ "%s: failure encoding group address %s: space left=%d",
+ __PRETTY_FUNCTION__, group_str, remain);
+ return -1;
+ }
+
+ /* Encode source */
+ remain = buf_pastend - pim_msg_curr;
+ pim_msg_curr =
+ pim_msg_addr_encode_ipv4_ucast(pim_msg_curr, source_addr);
+ if (!pim_msg_curr) {
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", source_addr, source_str,
+ sizeof(source_str));
+ zlog_warn(
+ "%s: failure encoding source address %s: space left=%d",
+ __PRETTY_FUNCTION__, source_str, remain);
+ return -2;
+ }
+
+ /* Metric preference */
+ pim_write_uint32(pim_msg_curr,
+ rpt_bit_flag ? metric_preference | 0x80000000
+ : metric_preference);
+ pim_msg_curr += 4;
+
+ /* Route metric */
+ pim_write_uint32(pim_msg_curr, route_metric);
+ pim_msg_curr += 4;
+
+ /*
+ Add PIM header
+ */
+ pim_msg_size = pim_msg_curr - pim_msg;
+ pim_msg_build_header(pim_msg, pim_msg_size, PIM_MSG_TYPE_ASSERT);
+
+ return pim_msg_size;
}
static int pim_assert_do(struct pim_ifchannel *ch,
struct pim_assert_metric metric)
{
- struct interface *ifp;
- struct pim_interface *pim_ifp;
- uint8_t pim_msg[1000];
- int pim_msg_size;
-
- ifp = ch->interface;
- if (!ifp)
- {
- if (PIM_DEBUG_PIM_TRACE)
- zlog_debug("%s: channel%s has no associated interface!",
- __PRETTY_FUNCTION__, ch->sg_str);
- return -1;
- }
- pim_ifp = ifp->info;
- if (!pim_ifp) {
- if (PIM_DEBUG_PIM_TRACE)
- zlog_debug("%s: channel %s pim not enabled on interface: %s",
- __PRETTY_FUNCTION__, ch->sg_str, ifp->name);
- return -1;
- }
-
- pim_msg_size = pim_assert_build_msg(pim_msg, sizeof(pim_msg), ifp,
- ch->sg.grp, ch->sg.src,
- metric.metric_preference,
- metric.route_metric,
- metric.rpt_bit_flag);
- if (pim_msg_size < 1) {
- zlog_warn("%s: failure building PIM assert message: msg_size=%d",
- __PRETTY_FUNCTION__, pim_msg_size);
- return -2;
- }
-
- /*
- RFC 4601: 4.3.1. Sending Hello Messages
-
- Thus, if a router needs to send a Join/Prune or Assert message on
- an interface on which it has not yet sent a Hello message with the
- currently configured IP address, then it MUST immediately send the
- relevant Hello message without waiting for the Hello Timer to
- expire, followed by the Join/Prune or Assert message.
- */
- pim_hello_require(ifp);
-
- if (PIM_DEBUG_PIM_TRACE) {
- zlog_debug("%s: to %s: (S,G)=%s pref=%u metric=%u rpt_bit=%u",
- __PRETTY_FUNCTION__,
- ifp->name, ch->sg_str,
- metric.metric_preference,
- metric.route_metric,
- PIM_FORCE_BOOLEAN(metric.rpt_bit_flag));
- }
- ++pim_ifp->pim_ifstat_assert_send;
-
- if (pim_msg_send(pim_ifp->pim_sock_fd,
- pim_ifp->primary_address,
- qpim_all_pim_routers_addr,
- pim_msg,
- pim_msg_size,
- ifp->name)) {
- zlog_warn("%s: could not send PIM message on interface %s",
- __PRETTY_FUNCTION__, ifp->name);
- return -3;
- }
-
- return 0;
+ struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ uint8_t pim_msg[1000];
+ int pim_msg_size;
+
+ ifp = ch->interface;
+ if (!ifp) {
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug("%s: channel%s has no associated interface!",
+ __PRETTY_FUNCTION__, ch->sg_str);
+ return -1;
+ }
+ pim_ifp = ifp->info;
+ if (!pim_ifp) {
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug(
+ "%s: channel %s pim not enabled on interface: %s",
+ __PRETTY_FUNCTION__, ch->sg_str, ifp->name);
+ return -1;
+ }
+
+ pim_msg_size =
+ pim_assert_build_msg(pim_msg, sizeof(pim_msg), ifp, ch->sg.grp,
+ ch->sg.src, metric.metric_preference,
+ metric.route_metric, metric.rpt_bit_flag);
+ if (pim_msg_size < 1) {
+ zlog_warn(
+ "%s: failure building PIM assert message: msg_size=%d",
+ __PRETTY_FUNCTION__, pim_msg_size);
+ return -2;
+ }
+
+ /*
+ RFC 4601: 4.3.1. Sending Hello Messages
+
+ Thus, if a router needs to send a Join/Prune or Assert message on
+ an interface on which it has not yet sent a Hello message with the
+ currently configured IP address, then it MUST immediately send the
+ relevant Hello message without waiting for the Hello Timer to
+ expire, followed by the Join/Prune or Assert message.
+ */
+ pim_hello_require(ifp);
+
+ if (PIM_DEBUG_PIM_TRACE) {
+ zlog_debug("%s: to %s: (S,G)=%s pref=%u metric=%u rpt_bit=%u",
+ __PRETTY_FUNCTION__, ifp->name, ch->sg_str,
+ metric.metric_preference, metric.route_metric,
+ PIM_FORCE_BOOLEAN(metric.rpt_bit_flag));
+ }
+ ++pim_ifp->pim_ifstat_assert_send;
+
+ if (pim_msg_send(pim_ifp->pim_sock_fd, pim_ifp->primary_address,
+ qpim_all_pim_routers_addr, pim_msg, pim_msg_size,
+ ifp->name)) {
+ zlog_warn("%s: could not send PIM message on interface %s",
+ __PRETTY_FUNCTION__, ifp->name);
+ return -3;
+ }
+
+ return 0;
}
int pim_assert_send(struct pim_ifchannel *ch)
{
- return pim_assert_do(ch, ch->ifassert_my_metric);
+ return pim_assert_do(ch, ch->ifassert_my_metric);
}
/*
@@ -506,82 +500,82 @@ int pim_assert_send(struct pim_ifchannel *ch)
*/
static int pim_assert_cancel(struct pim_ifchannel *ch)
{
- struct pim_assert_metric metric;
+ struct pim_assert_metric metric;
- metric.rpt_bit_flag = 0;
- metric.metric_preference = PIM_ASSERT_METRIC_PREFERENCE_MAX;
- metric.route_metric = PIM_ASSERT_ROUTE_METRIC_MAX;
- metric.ip_address = ch->sg.src;
+ metric.rpt_bit_flag = 0;
+ metric.metric_preference = PIM_ASSERT_METRIC_PREFERENCE_MAX;
+ metric.route_metric = PIM_ASSERT_ROUTE_METRIC_MAX;
+ metric.ip_address = ch->sg.src;
- return pim_assert_do(ch, metric);
+ return pim_assert_do(ch, metric);
}
static int on_assert_timer(struct thread *t)
{
- struct pim_ifchannel *ch;
- struct interface *ifp;
-
- ch = THREAD_ARG(t);
-
- ifp = ch->interface;
-
- if (PIM_DEBUG_PIM_TRACE) {
- zlog_debug("%s: (S,G)=%s timer expired on interface %s",
- __PRETTY_FUNCTION__,
- ch->sg_str, ifp->name);
- }
-
- ch->t_ifassert_timer = NULL;
-
- switch (ch->ifassert_state) {
- case PIM_IFASSERT_I_AM_WINNER:
- assert_action_a3(ch);
- break;
- case PIM_IFASSERT_I_AM_LOSER:
- assert_action_a5(ch);
- break;
- default:
- {
- if (PIM_DEBUG_PIM_EVENTS)
- zlog_warn("%s: (S,G)=%s invalid assert state %d on interface %s",
- __PRETTY_FUNCTION__,
- ch->sg_str, ch->ifassert_state, ifp->name);
- }
- }
-
- return 0;
+ struct pim_ifchannel *ch;
+ struct interface *ifp;
+
+ ch = THREAD_ARG(t);
+
+ ifp = ch->interface;
+
+ if (PIM_DEBUG_PIM_TRACE) {
+ zlog_debug("%s: (S,G)=%s timer expired on interface %s",
+ __PRETTY_FUNCTION__, ch->sg_str, ifp->name);
+ }
+
+ ch->t_ifassert_timer = NULL;
+
+ switch (ch->ifassert_state) {
+ case PIM_IFASSERT_I_AM_WINNER:
+ assert_action_a3(ch);
+ break;
+ case PIM_IFASSERT_I_AM_LOSER:
+ assert_action_a5(ch);
+ break;
+ default: {
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_warn(
+ "%s: (S,G)=%s invalid assert state %d on interface %s",
+ __PRETTY_FUNCTION__, ch->sg_str,
+ ch->ifassert_state, ifp->name);
+ }
+ }
+
+ return 0;
}
static void assert_timer_off(struct pim_ifchannel *ch)
{
- if (PIM_DEBUG_PIM_TRACE) {
- if (ch->t_ifassert_timer) {
- zlog_debug("%s: (S,G)=%s cancelling timer on interface %s",
- __PRETTY_FUNCTION__,
- ch->sg_str, ch->interface->name);
- }
- }
- THREAD_OFF(ch->t_ifassert_timer);
+ if (PIM_DEBUG_PIM_TRACE) {
+ if (ch->t_ifassert_timer) {
+ zlog_debug(
+ "%s: (S,G)=%s cancelling timer on interface %s",
+ __PRETTY_FUNCTION__, ch->sg_str,
+ ch->interface->name);
+ }
+ }
+ THREAD_OFF(ch->t_ifassert_timer);
}
-static void pim_assert_timer_set(struct pim_ifchannel *ch,
- int interval)
+static void pim_assert_timer_set(struct pim_ifchannel *ch, int interval)
{
- assert_timer_off(ch);
+ assert_timer_off(ch);
- if (PIM_DEBUG_PIM_TRACE) {
- zlog_debug("%s: (S,G)=%s starting %u sec timer on interface %s",
- __PRETTY_FUNCTION__,
- ch->sg_str, interval, ch->interface->name);
- }
+ if (PIM_DEBUG_PIM_TRACE) {
+ zlog_debug("%s: (S,G)=%s starting %u sec timer on interface %s",
+ __PRETTY_FUNCTION__, ch->sg_str, interval,
+ ch->interface->name);
+ }
- thread_add_timer(master, on_assert_timer, ch, interval,
- &ch->t_ifassert_timer);
+ thread_add_timer(master, on_assert_timer, ch, interval,
+ &ch->t_ifassert_timer);
}
static void pim_assert_timer_reset(struct pim_ifchannel *ch)
{
- pim_assert_timer_set(ch, PIM_ASSERT_TIME - PIM_ASSERT_OVERRIDE_INTERVAL);
+ pim_assert_timer_set(ch,
+ PIM_ASSERT_TIME - PIM_ASSERT_OVERRIDE_INTERVAL);
}
/*
@@ -596,38 +590,37 @@ static void pim_assert_timer_reset(struct pim_ifchannel *ch)
*/
int assert_action_a1(struct pim_ifchannel *ch)
{
- struct interface *ifp = ch->interface;
- struct pim_interface *pim_ifp;
-
- pim_ifp = ifp->info;
- if (!pim_ifp) {
- zlog_warn("%s: (S,G)=%s multicast not enabled on interface %s",
- __PRETTY_FUNCTION__,
- ch->sg_str, ifp->name);
- return -1; /* must return since pim_ifp is used below */
- }
-
- /* Switch to I_AM_WINNER before performing action_a3 below */
- pim_ifassert_winner_set(ch, PIM_IFASSERT_I_AM_WINNER,
- pim_ifp->primary_address,
- pim_macro_spt_assert_metric(&ch->upstream->rpf,
- pim_ifp->primary_address));
-
- if (assert_action_a3(ch)) {
- zlog_warn("%s: (S,G)=%s assert_action_a3 failure on interface %s",
- __PRETTY_FUNCTION__,
- ch->sg_str, ifp->name);
- /* warning only */
- }
-
- if (ch->ifassert_state != PIM_IFASSERT_I_AM_WINNER)
- {
- if (PIM_DEBUG_PIM_EVENTS)
- zlog_warn("%s: channel%s not in expected PIM_IFASSERT_I_AM_WINNER state",
- __PRETTY_FUNCTION__, ch->sg_str);
- }
-
- return 0;
+ struct interface *ifp = ch->interface;
+ struct pim_interface *pim_ifp;
+
+ pim_ifp = ifp->info;
+ if (!pim_ifp) {
+ zlog_warn("%s: (S,G)=%s multicast not enabled on interface %s",
+ __PRETTY_FUNCTION__, ch->sg_str, ifp->name);
+ return -1; /* must return since pim_ifp is used below */
+ }
+
+ /* Switch to I_AM_WINNER before performing action_a3 below */
+ pim_ifassert_winner_set(
+ ch, PIM_IFASSERT_I_AM_WINNER, pim_ifp->primary_address,
+ pim_macro_spt_assert_metric(&ch->upstream->rpf,
+ pim_ifp->primary_address));
+
+ if (assert_action_a3(ch)) {
+ zlog_warn(
+ "%s: (S,G)=%s assert_action_a3 failure on interface %s",
+ __PRETTY_FUNCTION__, ch->sg_str, ifp->name);
+ /* warning only */
+ }
+
+ if (ch->ifassert_state != PIM_IFASSERT_I_AM_WINNER) {
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_warn(
+ "%s: channel%s not in expected PIM_IFASSERT_I_AM_WINNER state",
+ __PRETTY_FUNCTION__, ch->sg_str);
+ }
+
+ return 0;
}
/*
@@ -636,24 +629,23 @@ int assert_action_a1(struct pim_ifchannel *ch)
(S,G) Assert State machine Actions
A2: Store new assert winner as AssertWinner(S,G,I) and assert
- winner metric as AssertWinnerMetric(S,G,I).
- Set Assert Timer to Assert_Time.
+ winner metric as AssertWinnerMetric(S,G,I).
+ Set Assert Timer to Assert_Time.
*/
static void assert_action_a2(struct pim_ifchannel *ch,
struct pim_assert_metric winner_metric)
{
- pim_ifassert_winner_set(ch, PIM_IFASSERT_I_AM_LOSER,
- winner_metric.ip_address,
- winner_metric);
-
- pim_assert_timer_set(ch, PIM_ASSERT_TIME);
-
- if (ch->ifassert_state != PIM_IFASSERT_I_AM_LOSER)
- {
- if (PIM_DEBUG_PIM_EVENTS)
- zlog_warn("%s: channel%s not in expected PIM_IFASSERT_I_AM_LOSER state",
- __PRETTY_FUNCTION__, ch->sg_str);
- }
+ pim_ifassert_winner_set(ch, PIM_IFASSERT_I_AM_LOSER,
+ winner_metric.ip_address, winner_metric);
+
+ pim_assert_timer_set(ch, PIM_ASSERT_TIME);
+
+ if (ch->ifassert_state != PIM_IFASSERT_I_AM_LOSER) {
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_warn(
+ "%s: channel%s not in expected PIM_IFASSERT_I_AM_LOSER state",
+ __PRETTY_FUNCTION__, ch->sg_str);
+ }
}
/*
@@ -666,24 +658,23 @@ static void assert_action_a2(struct pim_ifchannel *ch,
*/
static int assert_action_a3(struct pim_ifchannel *ch)
{
- if (ch->ifassert_state != PIM_IFASSERT_I_AM_WINNER)
- {
- if (PIM_DEBUG_PIM_EVENTS)
- zlog_warn("%s: channel%s expected to be in PIM_IFASSERT_I_AM_WINNER state",
- __PRETTY_FUNCTION__, ch->sg_str);
- return -1;
- }
-
- pim_assert_timer_reset(ch);
-
- if (pim_assert_send(ch)) {
- zlog_warn("%s: (S,G)=%s failure sending assert on interface %s",
- __PRETTY_FUNCTION__,
- ch->sg_str, ch->interface->name);
- return -1;
- }
-
- return 0;
+ if (ch->ifassert_state != PIM_IFASSERT_I_AM_WINNER) {
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_warn(
+ "%s: channel%s expected to be in PIM_IFASSERT_I_AM_WINNER state",
+ __PRETTY_FUNCTION__, ch->sg_str);
+ return -1;
+ }
+
+ pim_assert_timer_reset(ch);
+
+ if (pim_assert_send(ch)) {
+ zlog_warn("%s: (S,G)=%s failure sending assert on interface %s",
+ __PRETTY_FUNCTION__, ch->sg_str, ch->interface->name);
+ return -1;
+ }
+
+ return 0;
}
/*
@@ -692,27 +683,26 @@ static int assert_action_a3(struct pim_ifchannel *ch)
(S,G) Assert State machine Actions
A4: Send AssertCancel(S,G).
- Delete assert info (AssertWinner(S,G,I) and
- AssertWinnerMetric(S,G,I) will then return their default
- values).
+ Delete assert info (AssertWinner(S,G,I) and
+ AssertWinnerMetric(S,G,I) will then return their default
+ values).
*/
void assert_action_a4(struct pim_ifchannel *ch)
{
- if (pim_assert_cancel(ch)) {
- zlog_warn("%s: failure sending AssertCancel%s on interface %s",
- __PRETTY_FUNCTION__,
- ch->sg_str, ch->interface->name);
- /* log warning only */
- }
-
- assert_action_a5(ch);
-
- if (ch->ifassert_state != PIM_IFASSERT_NOINFO)
- {
- if (PIM_DEBUG_PIM_EVENTS)
- zlog_warn("%s: channel%s not in PIM_IFASSERT_NOINFO state as expected",
- __PRETTY_FUNCTION__, ch->sg_str);
- }
+ if (pim_assert_cancel(ch)) {
+ zlog_warn("%s: failure sending AssertCancel%s on interface %s",
+ __PRETTY_FUNCTION__, ch->sg_str, ch->interface->name);
+ /* log warning only */
+ }
+
+ assert_action_a5(ch);
+
+ if (ch->ifassert_state != PIM_IFASSERT_NOINFO) {
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_warn(
+ "%s: channel%s not in PIM_IFASSERT_NOINFO state as expected",
+ __PRETTY_FUNCTION__, ch->sg_str);
+ }
}
/*
@@ -725,13 +715,13 @@ void assert_action_a4(struct pim_ifchannel *ch)
*/
void assert_action_a5(struct pim_ifchannel *ch)
{
- reset_ifassert_state(ch);
- if (ch->ifassert_state != PIM_IFASSERT_NOINFO)
- {
- if (PIM_DEBUG_PIM_EVENTS)
- zlog_warn("%s: channel%s not in PIM_IFSSERT_NOINFO state as expected",
- __PRETTY_FUNCTION__, ch->sg_str);
- }
+ reset_ifassert_state(ch);
+ if (ch->ifassert_state != PIM_IFASSERT_NOINFO) {
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_warn(
+ "%s: channel%s not in PIM_IFSSERT_NOINFO state as expected",
+ __PRETTY_FUNCTION__, ch->sg_str);
+ }
}
/*
@@ -740,29 +730,28 @@ void assert_action_a5(struct pim_ifchannel *ch)
(S,G) Assert State machine Actions
A6: Store new assert winner as AssertWinner(S,G,I) and assert
- winner metric as AssertWinnerMetric(S,G,I).
- Set Assert Timer to Assert_Time.
- If (I is RPF_interface(S)) AND (UpstreamJPState(S,G) == true)
- set SPTbit(S,G) to TRUE.
+ winner metric as AssertWinnerMetric(S,G,I).
+ Set Assert Timer to Assert_Time.
+ If (I is RPF_interface(S)) AND (UpstreamJPState(S,G) == true)
+ set SPTbit(S,G) to TRUE.
*/
static void assert_action_a6(struct pim_ifchannel *ch,
struct pim_assert_metric winner_metric)
{
- assert_action_a2(ch, winner_metric);
-
- /*
- If (I is RPF_interface(S)) AND (UpstreamJPState(S,G) == true) set
- SPTbit(S,G) to TRUE.
- */
- if (ch->upstream->rpf.source_nexthop.interface == ch->interface)
- if (ch->upstream->join_state == PIM_UPSTREAM_JOINED)
- ch->upstream->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
-
- if (ch->ifassert_state != PIM_IFASSERT_I_AM_LOSER)
- {
- if(PIM_DEBUG_PIM_EVENTS)
- zlog_warn("%s: channel%s not in PIM_IFASSERT_I_AM_LOSER state as expected",
- __PRETTY_FUNCTION__, ch->sg_str);
- }
+ assert_action_a2(ch, winner_metric);
+
+ /*
+ If (I is RPF_interface(S)) AND (UpstreamJPState(S,G) == true) set
+ SPTbit(S,G) to TRUE.
+ */
+ if (ch->upstream->rpf.source_nexthop.interface == ch->interface)
+ if (ch->upstream->join_state == PIM_UPSTREAM_JOINED)
+ ch->upstream->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
+
+ if (ch->ifassert_state != PIM_IFASSERT_I_AM_LOSER) {
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_warn(
+ "%s: channel%s not in PIM_IFASSERT_I_AM_LOSER state as expected",
+ __PRETTY_FUNCTION__, ch->sg_str);
+ }
}
-
diff --git a/pimd/pim_assert.h b/pimd/pim_assert.h
index b2fc11523..63fda3fe3 100644
--- a/pimd/pim_assert.h
+++ b/pimd/pim_assert.h
@@ -40,27 +40,22 @@
#define PIM_ASSERT_METRIC_PREFERENCE_MAX (0xFFFFFFFF)
#define PIM_ASSERT_ROUTE_METRIC_MAX (0xFFFFFFFF)
-void pim_ifassert_winner_set(struct pim_ifchannel *ch,
- enum pim_ifassert_state new_state,
- struct in_addr winner,
- struct pim_assert_metric winner_metric);
+void pim_ifassert_winner_set(struct pim_ifchannel *ch,
+ enum pim_ifassert_state new_state,
+ struct in_addr winner,
+ struct pim_assert_metric winner_metric);
-int pim_assert_recv(struct interface *ifp,
- struct pim_neighbor *neigh,
- struct in_addr src_addr,
- uint8_t *buf, int buf_size);
+int pim_assert_recv(struct interface *ifp, struct pim_neighbor *neigh,
+ struct in_addr src_addr, uint8_t *buf, int buf_size);
int pim_assert_metric_better(const struct pim_assert_metric *m1,
const struct pim_assert_metric *m2);
int pim_assert_metric_match(const struct pim_assert_metric *m1,
const struct pim_assert_metric *m2);
-int pim_assert_build_msg(uint8_t *pim_msg, int buf_size,
- struct interface *ifp,
- struct in_addr group_addr,
- struct in_addr source_addr,
- uint32_t metric_preference,
- uint32_t route_metric,
+int pim_assert_build_msg(uint8_t *pim_msg, int buf_size, struct interface *ifp,
+ struct in_addr group_addr, struct in_addr source_addr,
+ uint32_t metric_preference, uint32_t route_metric,
uint32_t rpt_bit_flag);
int pim_assert_send(struct pim_ifchannel *ch);
diff --git a/pimd/pim_bfd.c b/pimd/pim_bfd.c
index af8a8e2c5..e4c50a18b 100644
--- a/pimd/pim_bfd.c
+++ b/pimd/pim_bfd.c
@@ -38,101 +38,94 @@
/*
* pim_bfd_write_config - Write the interface BFD configuration.
*/
-void
-pim_bfd_write_config (struct vty *vty, struct interface *ifp)
+void pim_bfd_write_config(struct vty *vty, struct interface *ifp)
{
- struct pim_interface *pim_ifp = ifp->info;
- struct bfd_info *bfd_info = NULL;
-
- if (!pim_ifp)
- return;
-
- bfd_info = (struct bfd_info *) pim_ifp->bfd_info;
- if (!bfd_info)
- return;
-
- if (CHECK_FLAG (bfd_info->flags, BFD_FLAG_PARAM_CFG))
- vty_out (vty, " ip pim bfd %d %d %d\n",
- bfd_info->detect_mult, bfd_info->required_min_rx,
- bfd_info->desired_min_tx);
- else
- vty_out (vty, " ip pim bfd\n");
+ struct pim_interface *pim_ifp = ifp->info;
+ struct bfd_info *bfd_info = NULL;
+
+ if (!pim_ifp)
+ return;
+
+ bfd_info = (struct bfd_info *)pim_ifp->bfd_info;
+ if (!bfd_info)
+ return;
+
+ if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG))
+ vty_out(vty, " ip pim bfd %d %d %d\n", bfd_info->detect_mult,
+ bfd_info->required_min_rx, bfd_info->desired_min_tx);
+ else
+ vty_out(vty, " ip pim bfd\n");
}
/*
* pim_bfd_show_info - Show BFD info structure
*/
-void
-pim_bfd_show_info (struct vty *vty, void *bfd_info, json_object * json_obj,
- u_char use_json, int param_only)
+void pim_bfd_show_info(struct vty *vty, void *bfd_info, json_object *json_obj,
+ u_char use_json, int param_only)
{
- if (param_only)
- bfd_show_param (vty, (struct bfd_info *) bfd_info, 1, 0, use_json,
- json_obj);
- else
- bfd_show_info (vty, (struct bfd_info *) bfd_info, 0, 1, use_json,
- json_obj);
+ if (param_only)
+ bfd_show_param(vty, (struct bfd_info *)bfd_info, 1, 0, use_json,
+ json_obj);
+ else
+ bfd_show_info(vty, (struct bfd_info *)bfd_info, 0, 1, use_json,
+ json_obj);
}
/*
* pim_bfd_info_nbr_create - Create/update BFD information for a neighbor.
*/
-void
-pim_bfd_info_nbr_create (struct pim_interface *pim_ifp,
- struct pim_neighbor *neigh)
+void pim_bfd_info_nbr_create(struct pim_interface *pim_ifp,
+ struct pim_neighbor *neigh)
{
- struct bfd_info *nbr_bfd_info = NULL;
+ struct bfd_info *nbr_bfd_info = NULL;
- /* Check if Pim Interface BFD is enabled */
- if (!pim_ifp || !pim_ifp->bfd_info)
- return;
+ /* Check if Pim Interface BFD is enabled */
+ if (!pim_ifp || !pim_ifp->bfd_info)
+ return;
- if (!neigh->bfd_info)
- neigh->bfd_info = bfd_info_create ();
+ if (!neigh->bfd_info)
+ neigh->bfd_info = bfd_info_create();
- if (!neigh->bfd_info)
- return;
+ if (!neigh->bfd_info)
+ return;
- nbr_bfd_info = (struct bfd_info *) neigh->bfd_info;
- nbr_bfd_info->detect_mult = pim_ifp->bfd_info->detect_mult;
- nbr_bfd_info->desired_min_tx = pim_ifp->bfd_info->desired_min_tx;
- nbr_bfd_info->required_min_rx = pim_ifp->bfd_info->required_min_rx;
+ nbr_bfd_info = (struct bfd_info *)neigh->bfd_info;
+ nbr_bfd_info->detect_mult = pim_ifp->bfd_info->detect_mult;
+ nbr_bfd_info->desired_min_tx = pim_ifp->bfd_info->desired_min_tx;
+ nbr_bfd_info->required_min_rx = pim_ifp->bfd_info->required_min_rx;
}
/*
* pim_bfd_info_free - Free BFD info structure
*/
-void
-pim_bfd_info_free (void **bfd_info)
+void pim_bfd_info_free(void **bfd_info)
{
- bfd_info_free ((struct bfd_info **) bfd_info);
+ bfd_info_free((struct bfd_info **)bfd_info);
}
-static void
-pim_bfd_reg_dereg_nbr (struct pim_neighbor *nbr, int command)
+static void pim_bfd_reg_dereg_nbr(struct pim_neighbor *nbr, int command)
{
- struct pim_interface *pim_ifp = NULL;
- struct bfd_info *bfd_info = NULL;
- struct zclient *zclient = NULL;
-
- zclient = pim_zebra_zclient_get ();
-
- if (!nbr)
- return;
- pim_ifp = nbr->interface->info;
- bfd_info = (struct bfd_info *) pim_ifp->bfd_info;
- if (!bfd_info)
- return;
- if (PIM_DEBUG_PIM_TRACE)
- {
- char str[INET_ADDRSTRLEN];
- pim_inet4_dump ("<bfd_nbr?>", nbr->source_addr, str, sizeof (str));
- zlog_debug ("%s Nbr %s %s with BFD", __PRETTY_FUNCTION__, str,
- bfd_get_command_dbg_str (command));
- }
- bfd_peer_sendmsg (zclient, bfd_info, AF_INET,
- &nbr->source_addr, NULL, nbr->interface->name,
- 0, 0, command, 0, VRF_DEFAULT);
+ struct pim_interface *pim_ifp = NULL;
+ struct bfd_info *bfd_info = NULL;
+ struct zclient *zclient = NULL;
+
+ zclient = pim_zebra_zclient_get();
+
+ if (!nbr)
+ return;
+ pim_ifp = nbr->interface->info;
+ bfd_info = (struct bfd_info *)pim_ifp->bfd_info;
+ if (!bfd_info)
+ return;
+ if (PIM_DEBUG_PIM_TRACE) {
+ char str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<bfd_nbr?>", nbr->source_addr, str,
+ sizeof(str));
+ zlog_debug("%s Nbr %s %s with BFD", __PRETTY_FUNCTION__, str,
+ bfd_get_command_dbg_str(command));
+ }
+ bfd_peer_sendmsg(zclient, bfd_info, AF_INET, &nbr->source_addr, NULL,
+ nbr->interface->name, 0, 0, command, 0, VRF_DEFAULT);
}
/*
@@ -141,75 +134,68 @@ pim_bfd_reg_dereg_nbr (struct pim_neighbor *nbr, int command)
* zebra for starting/stopping the monitoring of
* the neighbor rechahability.
*/
-int
-pim_bfd_reg_dereg_all_nbr (struct interface *ifp, int command)
+int pim_bfd_reg_dereg_all_nbr(struct interface *ifp, int command)
{
- struct pim_interface *pim_ifp = NULL;
- struct listnode *node = NULL;
- struct pim_neighbor *neigh = NULL;
-
- pim_ifp = ifp->info;
- if (!pim_ifp)
- return -1;
- if (!pim_ifp->bfd_info)
- return -1;
-
- for (ALL_LIST_ELEMENTS_RO (pim_ifp->pim_neighbor_list, node, neigh))
- {
- if (command != ZEBRA_BFD_DEST_DEREGISTER)
- pim_bfd_info_nbr_create (pim_ifp, neigh);
- else
- bfd_info_free ((struct bfd_info **) &neigh->bfd_info);
-
- pim_bfd_reg_dereg_nbr (neigh, command);
- }
-
- return 0;
+ struct pim_interface *pim_ifp = NULL;
+ struct listnode *node = NULL;
+ struct pim_neighbor *neigh = NULL;
+
+ pim_ifp = ifp->info;
+ if (!pim_ifp)
+ return -1;
+ if (!pim_ifp->bfd_info)
+ return -1;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, node, neigh)) {
+ if (command != ZEBRA_BFD_DEST_DEREGISTER)
+ pim_bfd_info_nbr_create(pim_ifp, neigh);
+ else
+ bfd_info_free((struct bfd_info **)&neigh->bfd_info);
+
+ pim_bfd_reg_dereg_nbr(neigh, command);
+ }
+
+ return 0;
}
/*
* pim_bfd_trigger_event - Neighbor is registered/deregistered with BFD when
* neighbor state is changed to/from 2way.
*/
-void
-pim_bfd_trigger_event (struct pim_interface *pim_ifp, struct pim_neighbor *nbr, uint8_t nbr_up)
+void pim_bfd_trigger_event(struct pim_interface *pim_ifp,
+ struct pim_neighbor *nbr, uint8_t nbr_up)
{
- if (nbr_up)
- {
- pim_bfd_info_nbr_create (pim_ifp, nbr);
- pim_bfd_reg_dereg_nbr (nbr, ZEBRA_BFD_DEST_REGISTER);
- }
- else
- {
- pim_bfd_info_free ((void *)&nbr->bfd_info);
- pim_bfd_reg_dereg_nbr (nbr, ZEBRA_BFD_DEST_DEREGISTER);
- }
+ if (nbr_up) {
+ pim_bfd_info_nbr_create(pim_ifp, nbr);
+ pim_bfd_reg_dereg_nbr(nbr, ZEBRA_BFD_DEST_REGISTER);
+ } else {
+ pim_bfd_info_free((void *)&nbr->bfd_info);
+ pim_bfd_reg_dereg_nbr(nbr, ZEBRA_BFD_DEST_DEREGISTER);
+ }
}
/*
* pim_bfd_if_param_set - Set the configured BFD paramter values for
* interface.
*/
-void
-pim_bfd_if_param_set (struct interface *ifp, u_int32_t min_rx,
- u_int32_t min_tx, u_int8_t detect_mult, int defaults)
+void pim_bfd_if_param_set(struct interface *ifp, u_int32_t min_rx,
+ u_int32_t min_tx, u_int8_t detect_mult, int defaults)
{
- struct pim_interface *pim_ifp = ifp->info;
- int command = 0;
-
- if (!pim_ifp)
- return;
- bfd_set_param ((struct bfd_info **) &(pim_ifp->bfd_info), min_rx, min_tx,
- detect_mult, defaults, &command);
-
- if (pim_ifp->bfd_info)
- {
- if (PIM_DEBUG_PIM_TRACE)
- zlog_debug ("%s: interface %s has bfd_info", __PRETTY_FUNCTION__,
- ifp->name);
- }
- if (command)
- pim_bfd_reg_dereg_all_nbr (ifp, command);
+ struct pim_interface *pim_ifp = ifp->info;
+ int command = 0;
+
+ if (!pim_ifp)
+ return;
+ bfd_set_param((struct bfd_info **)&(pim_ifp->bfd_info), min_rx, min_tx,
+ detect_mult, defaults, &command);
+
+ if (pim_ifp->bfd_info) {
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug("%s: interface %s has bfd_info",
+ __PRETTY_FUNCTION__, ifp->name);
+ }
+ if (command)
+ pim_bfd_reg_dereg_all_nbr(ifp, command);
}
@@ -219,145 +205,133 @@ pim_bfd_if_param_set (struct interface *ifp, u_int32_t min_rx,
* connectivity if the BFD status changed to
* down.
*/
-static int
-pim_bfd_interface_dest_update (int command, struct zclient *zclient,
- zebra_size_t length, vrf_id_t vrf_id)
+static int pim_bfd_interface_dest_update(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
{
- struct interface *ifp = NULL;
- struct pim_interface *pim_ifp = NULL;
- struct prefix p;
- int status;
- char msg[100];
- int old_status;
- struct bfd_info *bfd_info = NULL;
- struct timeval tv;
- struct listnode *neigh_node = NULL;
- struct listnode *neigh_nextnode = NULL;
- struct pim_neighbor *neigh = NULL;
-
- ifp = bfd_get_peer_info (zclient->ibuf, &p, NULL, &status, vrf_id);
-
- if ((ifp == NULL) || (p.family != AF_INET))
- return 0;
-
- pim_ifp = ifp->info;
- if (!pim_ifp)
- return 0;
-
- if (!pim_ifp->bfd_info)
- {
- if (PIM_DEBUG_PIM_TRACE)
- zlog_debug ("%s: pim interface %s BFD is disabled ", __PRETTY_FUNCTION__,
- ifp->name);
- return 0;
- }
-
- if (PIM_DEBUG_PIM_TRACE)
- {
- char buf[PREFIX2STR_BUFFER];
- prefix2str (&p, buf, sizeof (buf));
- zlog_debug ("%s: interface %s bfd destination %s %s",
- __PRETTY_FUNCTION__, ifp->name, buf,
- bfd_get_status_str (status));
- }
-
- for (ALL_LIST_ELEMENTS (pim_ifp->pim_neighbor_list, neigh_node,
- neigh_nextnode, neigh))
- {
- /* Check neigh address matches with BFD address */
- if (neigh->source_addr.s_addr != p.u.prefix4.s_addr)
- continue;
-
- bfd_info = (struct bfd_info *) neigh->bfd_info;
- if (bfd_info->status == status)
- {
- if (PIM_DEBUG_PIM_TRACE)
- {
- char str[INET_ADDRSTRLEN];
- pim_inet4_dump ("<nht_nbr?>", neigh->source_addr, str,
- sizeof (str));
- zlog_debug ("%s: bfd status is same for nbr %s",
- __PRETTY_FUNCTION__, str);
- }
- continue;
- }
- old_status = bfd_info->status;
- bfd_info->status = status;
- monotime(&tv);
- bfd_info->last_update = tv.tv_sec;
-
- if (PIM_DEBUG_PIM_TRACE)
- {
- zlog_debug ("%s: status %s old_status %s", __PRETTY_FUNCTION__,
- bfd_get_status_str (status),
- bfd_get_status_str (old_status));
- }
- if ((status == BFD_STATUS_DOWN) && (old_status == BFD_STATUS_UP))
- {
- snprintf (msg, sizeof (msg), "BFD Session Expired");
- pim_neighbor_delete (ifp, neigh, msg);
- }
- }
- return 0;
+ struct interface *ifp = NULL;
+ struct pim_interface *pim_ifp = NULL;
+ struct prefix p;
+ int status;
+ char msg[100];
+ int old_status;
+ struct bfd_info *bfd_info = NULL;
+ struct timeval tv;
+ struct listnode *neigh_node = NULL;
+ struct listnode *neigh_nextnode = NULL;
+ struct pim_neighbor *neigh = NULL;
+
+ ifp = bfd_get_peer_info(zclient->ibuf, &p, NULL, &status, vrf_id);
+
+ if ((ifp == NULL) || (p.family != AF_INET))
+ return 0;
+
+ pim_ifp = ifp->info;
+ if (!pim_ifp)
+ return 0;
+
+ if (!pim_ifp->bfd_info) {
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug("%s: pim interface %s BFD is disabled ",
+ __PRETTY_FUNCTION__, ifp->name);
+ return 0;
+ }
+
+ if (PIM_DEBUG_PIM_TRACE) {
+ char buf[PREFIX2STR_BUFFER];
+ prefix2str(&p, buf, sizeof(buf));
+ zlog_debug("%s: interface %s bfd destination %s %s",
+ __PRETTY_FUNCTION__, ifp->name, buf,
+ bfd_get_status_str(status));
+ }
+
+ for (ALL_LIST_ELEMENTS(pim_ifp->pim_neighbor_list, neigh_node,
+ neigh_nextnode, neigh)) {
+ /* Check neigh address matches with BFD address */
+ if (neigh->source_addr.s_addr != p.u.prefix4.s_addr)
+ continue;
+
+ bfd_info = (struct bfd_info *)neigh->bfd_info;
+ if (bfd_info->status == status) {
+ if (PIM_DEBUG_PIM_TRACE) {
+ char str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<nht_nbr?>", neigh->source_addr,
+ str, sizeof(str));
+ zlog_debug("%s: bfd status is same for nbr %s",
+ __PRETTY_FUNCTION__, str);
+ }
+ continue;
+ }
+ old_status = bfd_info->status;
+ bfd_info->status = status;
+ monotime(&tv);
+ bfd_info->last_update = tv.tv_sec;
+
+ if (PIM_DEBUG_PIM_TRACE) {
+ zlog_debug("%s: status %s old_status %s",
+ __PRETTY_FUNCTION__,
+ bfd_get_status_str(status),
+ bfd_get_status_str(old_status));
+ }
+ if ((status == BFD_STATUS_DOWN)
+ && (old_status == BFD_STATUS_UP)) {
+ snprintf(msg, sizeof(msg), "BFD Session Expired");
+ pim_neighbor_delete(ifp, neigh, msg);
+ }
+ }
+ return 0;
}
/*
* pim_bfd_nbr_replay - Replay all the neighbors that have BFD enabled
* to zebra
*/
-static int
-pim_bfd_nbr_replay (int command, struct zclient *zclient, zebra_size_t length,
- vrf_id_t vrf_id)
+static int pim_bfd_nbr_replay(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
{
- struct interface *ifp = NULL;
- struct pim_interface *pim_ifp = NULL;
- struct pim_neighbor *neigh = NULL;
- struct listnode *node;
- struct listnode *neigh_node;
- struct listnode *neigh_nextnode;
-
- /* Send the client registration */
- bfd_client_sendmsg (zclient, ZEBRA_BFD_CLIENT_REGISTER);
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
- {
- pim_ifp = ifp->info;
-
- if (!pim_ifp)
- continue;
-
- if (pim_ifp->pim_sock_fd < 0)
- continue;
-
- for (ALL_LIST_ELEMENTS (pim_ifp->pim_neighbor_list, neigh_node,
- neigh_nextnode, neigh))
- {
- if (!neigh->bfd_info)
- continue;
- if (PIM_DEBUG_PIM_TRACE)
- {
- char str[INET_ADDRSTRLEN];
- pim_inet4_dump ("<bfd_nbr?>", neigh->source_addr, str,
- sizeof (str));
- zlog_debug ("%s: Replaying Pim Neigh %s to BFD",
- __PRETTY_FUNCTION__, str);
- }
- pim_bfd_reg_dereg_nbr (neigh, ZEBRA_BFD_DEST_UPDATE);
-
- }
- }
- return 0;
+ struct interface *ifp = NULL;
+ struct pim_interface *pim_ifp = NULL;
+ struct pim_neighbor *neigh = NULL;
+ struct listnode *node;
+ struct listnode *neigh_node;
+ struct listnode *neigh_nextnode;
+
+ /* Send the client registration */
+ bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER);
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ if (pim_ifp->pim_sock_fd < 0)
+ continue;
+
+ for (ALL_LIST_ELEMENTS(pim_ifp->pim_neighbor_list, neigh_node,
+ neigh_nextnode, neigh)) {
+ if (!neigh->bfd_info)
+ continue;
+ if (PIM_DEBUG_PIM_TRACE) {
+ char str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<bfd_nbr?>", neigh->source_addr,
+ str, sizeof(str));
+ zlog_debug("%s: Replaying Pim Neigh %s to BFD",
+ __PRETTY_FUNCTION__, str);
+ }
+ pim_bfd_reg_dereg_nbr(neigh, ZEBRA_BFD_DEST_UPDATE);
+ }
+ }
+ return 0;
}
-void
-pim_bfd_init (void)
+void pim_bfd_init(void)
{
- struct zclient *zclient = NULL;
+ struct zclient *zclient = NULL;
- zclient = pim_zebra_zclient_get ();
+ zclient = pim_zebra_zclient_get();
- bfd_gbl_init ();
+ bfd_gbl_init();
- zclient->interface_bfd_dest_update = pim_bfd_interface_dest_update;
- zclient->bfd_dest_replay = pim_bfd_nbr_replay;
+ zclient->interface_bfd_dest_update = pim_bfd_interface_dest_update;
+ zclient->bfd_dest_replay = pim_bfd_nbr_replay;
}
diff --git a/pimd/pim_bfd.h b/pimd/pim_bfd.h
index 23f286b86..316d3c1e2 100644
--- a/pimd/pim_bfd.h
+++ b/pimd/pim_bfd.h
@@ -25,18 +25,16 @@
#include "if.h"
-void pim_bfd_init (void);
-void pim_bfd_write_config (struct vty *vty, struct interface *ifp);
-void
-pim_bfd_show_info (struct vty *vty, void *bfd_info, json_object * json_obj,
- u_char use_json, int param_only);
-void
-pim_bfd_if_param_set (struct interface *ifp, u_int32_t min_rx,
- u_int32_t min_tx, u_int8_t detect_mult, int defaults);
-int pim_bfd_reg_dereg_all_nbr (struct interface *ifp, int command);
-void
-pim_bfd_trigger_event (struct pim_interface *pim_ifp, struct pim_neighbor *nbr, uint8_t nbr_up);
-void
-pim_bfd_info_nbr_create (struct pim_interface *pim_ifp, struct pim_neighbor *neigh);
+void pim_bfd_init(void);
+void pim_bfd_write_config(struct vty *vty, struct interface *ifp);
+void pim_bfd_show_info(struct vty *vty, void *bfd_info, json_object *json_obj,
+ u_char use_json, int param_only);
+void pim_bfd_if_param_set(struct interface *ifp, u_int32_t min_rx,
+ u_int32_t min_tx, u_int8_t detect_mult, int defaults);
+int pim_bfd_reg_dereg_all_nbr(struct interface *ifp, int command);
+void pim_bfd_trigger_event(struct pim_interface *pim_ifp,
+ struct pim_neighbor *nbr, uint8_t nbr_up);
+void pim_bfd_info_nbr_create(struct pim_interface *pim_ifp,
+ struct pim_neighbor *neigh);
void pim_bfd_info_free(void **bfd_info);
#endif /* _PIM_BFD_H */
diff --git a/pimd/pim_br.c b/pimd/pim_br.c
index 19a0293c4..f297b0591 100644
--- a/pimd/pim_br.c
+++ b/pimd/pim_br.c
@@ -29,83 +29,80 @@
#include "linklist.h"
struct pim_br {
- struct prefix_sg sg;
- struct in_addr pmbr;
+ struct prefix_sg sg;
+ struct in_addr pmbr;
};
-struct in_addr pim_br_unknown = { .s_addr = 0 };
+struct in_addr pim_br_unknown = {.s_addr = 0};
static struct list *pim_br_list = NULL;
-struct in_addr
-pim_br_get_pmbr (struct prefix_sg *sg)
+struct in_addr pim_br_get_pmbr(struct prefix_sg *sg)
{
- struct listnode *node;
- struct pim_br *pim_br;
+ struct listnode *node;
+ struct pim_br *pim_br;
- for (ALL_LIST_ELEMENTS_RO (pim_br_list, node, pim_br)) {
- if (sg->src.s_addr == pim_br->sg.src.s_addr &&
- sg->grp.s_addr == pim_br->sg.grp.s_addr)
- return pim_br->pmbr;
- }
+ for (ALL_LIST_ELEMENTS_RO(pim_br_list, node, pim_br)) {
+ if (sg->src.s_addr == pim_br->sg.src.s_addr
+ && sg->grp.s_addr == pim_br->sg.grp.s_addr)
+ return pim_br->pmbr;
+ }
- return pim_br_unknown;
+ return pim_br_unknown;
}
-void
-pim_br_set_pmbr (struct prefix_sg *sg, struct in_addr br)
+void pim_br_set_pmbr(struct prefix_sg *sg, struct in_addr br)
{
- struct listnode *node, *next;
- struct pim_br *pim_br;
+ struct listnode *node, *next;
+ struct pim_br *pim_br;
- for (ALL_LIST_ELEMENTS (pim_br_list, node, next, pim_br)) {
- if (sg->src.s_addr == pim_br->sg.src.s_addr &&
- sg->grp.s_addr == pim_br->sg.grp.s_addr)
- break;
- }
+ for (ALL_LIST_ELEMENTS(pim_br_list, node, next, pim_br)) {
+ if (sg->src.s_addr == pim_br->sg.src.s_addr
+ && sg->grp.s_addr == pim_br->sg.grp.s_addr)
+ break;
+ }
- if (!pim_br) {
- pim_br = XCALLOC(MTYPE_PIM_BR, sizeof (*pim_br));
- if (!pim_br) {
- zlog_err("PIM XCALLOC(%zu) failure", sizeof(*pim_br));
- return;
- }
+ if (!pim_br) {
+ pim_br = XCALLOC(MTYPE_PIM_BR, sizeof(*pim_br));
+ if (!pim_br) {
+ zlog_err("PIM XCALLOC(%zu) failure", sizeof(*pim_br));
+ return;
+ }
- pim_br->sg = *sg;
+ pim_br->sg = *sg;
- listnode_add(pim_br_list, pim_br);
- }
+ listnode_add(pim_br_list, pim_br);
+ }
- pim_br->pmbr = br;
+ pim_br->pmbr = br;
}
/*
* Remove the (S,G) from the stored values
*/
-void
-pim_br_clear_pmbr (struct prefix_sg *sg)
+void pim_br_clear_pmbr(struct prefix_sg *sg)
{
- struct listnode *node, *next;
- struct pim_br *pim_br;
+ struct listnode *node, *next;
+ struct pim_br *pim_br;
- for (ALL_LIST_ELEMENTS (pim_br_list, node, next, pim_br)) {
- if (sg->src.s_addr == pim_br->sg.src.s_addr &&
- sg->grp.s_addr == pim_br->sg.grp.s_addr)
- break;
- }
+ for (ALL_LIST_ELEMENTS(pim_br_list, node, next, pim_br)) {
+ if (sg->src.s_addr == pim_br->sg.src.s_addr
+ && sg->grp.s_addr == pim_br->sg.grp.s_addr)
+ break;
+ }
- if (!pim_br)
- return;
+ if (!pim_br)
+ return;
- listnode_delete (pim_br_list, pim_br);
+ listnode_delete(pim_br_list, pim_br);
}
-void pim_br_init (void)
+void pim_br_init(void)
{
- pim_br_list = list_new();
- if (!pim_br_list) {
- zlog_err("%s: Failure to create pim_br_list",
- __PRETTY_FUNCTION__);
- return;
- }
+ pim_br_list = list_new();
+ if (!pim_br_list) {
+ zlog_err("%s: Failure to create pim_br_list",
+ __PRETTY_FUNCTION__);
+ return;
+ }
}
diff --git a/pimd/pim_br.h b/pimd/pim_br.h
index 345dd011e..836ff5ee8 100644
--- a/pimd/pim_br.h
+++ b/pimd/pim_br.h
@@ -20,12 +20,12 @@
#ifndef PIM_BR_H
#define PIM_BR_H
-struct in_addr pim_br_get_pmbr (struct prefix_sg *sg);
+struct in_addr pim_br_get_pmbr(struct prefix_sg *sg);
-void pim_br_set_pmbr (struct prefix_sg *sg, struct in_addr value);
-void pim_br_clear_pmbr (struct prefix_sg *sg);
+void pim_br_set_pmbr(struct prefix_sg *sg, struct in_addr value);
+void pim_br_clear_pmbr(struct prefix_sg *sg);
-void pim_br_init (void);
+void pim_br_init(void);
extern struct in_addr pim_br_unknown;
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 88c43104c..1c9fe40c2 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -61,37 +61,28 @@
#include "bfd.h"
static struct cmd_node pim_global_node = {
- PIM_NODE,
- "",
- 1 /* vtysh ? yes */
+ PIM_NODE, "", 1 /* vtysh ? yes */
};
static struct cmd_node interface_node = {
- INTERFACE_NODE,
- "%s(config-if)# ",
- 1 /* vtysh ? yes */
+ INTERFACE_NODE, "%s(config-if)# ", 1 /* vtysh ? yes */
};
-static struct cmd_node debug_node =
-{
- DEBUG_NODE,
- "",
- 1
-};
+static struct cmd_node debug_node = {DEBUG_NODE, "", 1};
static void pim_if_membership_clear(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
+ struct pim_interface *pim_ifp;
- pim_ifp = ifp->info;
- zassert(pim_ifp);
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
- if (PIM_IF_TEST_PIM(pim_ifp->options) &&
- PIM_IF_TEST_IGMP(pim_ifp->options)) {
- return;
- }
+ if (PIM_IF_TEST_PIM(pim_ifp->options)
+ && PIM_IF_TEST_IGMP(pim_ifp->options)) {
+ return;
+ }
- pim_ifchannel_membership_clear(ifp);
+ pim_ifchannel_membership_clear(ifp);
}
/*
@@ -105,2492 +96,2953 @@ static void pim_if_membership_clear(struct interface *ifp)
*/
static void pim_if_membership_refresh(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
- struct listnode *sock_node;
- struct igmp_sock *igmp;
+ struct pim_interface *pim_ifp;
+ struct listnode *sock_node;
+ struct igmp_sock *igmp;
- pim_ifp = ifp->info;
- zassert(pim_ifp);
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
- if (!PIM_IF_TEST_PIM(pim_ifp->options))
- return;
- if (!PIM_IF_TEST_IGMP(pim_ifp->options))
- return;
+ if (!PIM_IF_TEST_PIM(pim_ifp->options))
+ return;
+ if (!PIM_IF_TEST_IGMP(pim_ifp->options))
+ return;
- /*
- First clear off membership from all PIM (S,G) entries on the
- interface
- */
+ /*
+ First clear off membership from all PIM (S,G) entries on the
+ interface
+ */
- pim_ifchannel_membership_clear(ifp);
+ pim_ifchannel_membership_clear(ifp);
- /*
- Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
- the interface
- */
+ /*
+ Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
+ the interface
+ */
- /* scan igmp sockets */
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
- struct listnode *grpnode;
- struct igmp_group *grp;
-
- /* scan igmp groups */
- for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
- struct listnode *srcnode;
- struct igmp_source *src;
-
- /* scan group sources */
- for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
+ /* scan igmp sockets */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
+ struct listnode *grpnode;
+ struct igmp_group *grp;
- if (IGMP_SOURCE_TEST_FORWARDING(src->source_flags)) {
- struct prefix_sg sg;
+ /* scan igmp groups */
+ for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode,
+ grp)) {
+ struct listnode *srcnode;
+ struct igmp_source *src;
- memset (&sg, 0, sizeof (struct prefix_sg));
- sg.src = src->source_addr;
- sg.grp = grp->group_addr;
- pim_ifchannel_local_membership_add(ifp, &sg);
- }
-
- } /* scan group sources */
- } /* scan igmp groups */
- } /* scan igmp sockets */
+ /* scan group sources */
+ for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
+ srcnode, src)) {
+
+ if (IGMP_SOURCE_TEST_FORWARDING(
+ src->source_flags)) {
+ struct prefix_sg sg;
+
+ memset(&sg, 0,
+ sizeof(struct prefix_sg));
+ sg.src = src->source_addr;
+ sg.grp = grp->group_addr;
+ pim_ifchannel_local_membership_add(ifp,
+ &sg);
+ }
- /*
- Finally delete every PIM (S,G) entry lacking all state info
- */
+ } /* scan group sources */
+ } /* scan igmp groups */
+ } /* scan igmp sockets */
- pim_ifchannel_delete_on_noinfo(ifp);
+ /*
+ Finally delete every PIM (S,G) entry lacking all state info
+ */
+ pim_ifchannel_delete_on_noinfo(ifp);
}
static void pim_show_assert(struct vty *vty)
{
- struct pim_interface *pim_ifp;
- struct pim_ifchannel *ch;
- struct listnode *ch_node;
- struct in_addr ifaddr;
- time_t now;
-
- now = pim_time_monotonic_sec();
-
- vty_out (vty,
- "Interface Address Source Group State Winner Uptime Timer\n");
-
- for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
- char ch_src_str[INET_ADDRSTRLEN];
- char ch_grp_str[INET_ADDRSTRLEN];
- char winner_str[INET_ADDRSTRLEN];
- char uptime[10];
- char timer[10];
-
- pim_ifp = ch->interface->info;
-
- if (!pim_ifp)
- continue;
-
- ifaddr = pim_ifp->primary_address;
-
- pim_inet4_dump("<ch_src?>", ch->sg.src,
- ch_src_str, sizeof(ch_src_str));
- pim_inet4_dump("<ch_grp?>", ch->sg.grp,
- ch_grp_str, sizeof(ch_grp_str));
- pim_inet4_dump("<assrt_win?>", ch->ifassert_winner,
- winner_str, sizeof(winner_str));
-
- pim_time_uptime(uptime, sizeof(uptime), now - ch->ifassert_creation);
- pim_time_timer_to_mmss(timer, sizeof(timer),
- ch->t_ifassert_timer);
-
- vty_out (vty, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
- ch->interface->name,
- inet_ntoa(ifaddr),
- ch_src_str,
- ch_grp_str,
- pim_ifchannel_ifassert_name(ch->ifassert_state),
- winner_str,
- uptime,
- timer);
- } /* scan interface channels */
+ struct pim_interface *pim_ifp;
+ struct pim_ifchannel *ch;
+ struct listnode *ch_node;
+ struct in_addr ifaddr;
+ time_t now;
+
+ now = pim_time_monotonic_sec();
+
+ vty_out(vty,
+ "Interface Address Source Group State Winner Uptime Timer\n");
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
+ char ch_src_str[INET_ADDRSTRLEN];
+ char ch_grp_str[INET_ADDRSTRLEN];
+ char winner_str[INET_ADDRSTRLEN];
+ char uptime[10];
+ char timer[10];
+
+ pim_ifp = ch->interface->info;
+
+ if (!pim_ifp)
+ continue;
+
+ ifaddr = pim_ifp->primary_address;
+
+ pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
+ sizeof(ch_src_str));
+ pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str,
+ sizeof(ch_grp_str));
+ pim_inet4_dump("<assrt_win?>", ch->ifassert_winner, winner_str,
+ sizeof(winner_str));
+
+ pim_time_uptime(uptime, sizeof(uptime),
+ now - ch->ifassert_creation);
+ pim_time_timer_to_mmss(timer, sizeof(timer),
+ ch->t_ifassert_timer);
+
+ vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
+ ch->interface->name, inet_ntoa(ifaddr), ch_src_str,
+ ch_grp_str,
+ pim_ifchannel_ifassert_name(ch->ifassert_state),
+ winner_str, uptime, timer);
+ } /* scan interface channels */
}
static void pim_show_assert_internal(struct vty *vty)
{
- struct pim_interface *pim_ifp;
- struct listnode *ch_node;
- struct pim_ifchannel *ch;
- struct in_addr ifaddr;
-
- vty_out (vty,
- "CA: CouldAssert\n"
- "ECA: Evaluate CouldAssert\n"
- "ATD: AssertTrackingDesired\n"
- "eATD: Evaluate AssertTrackingDesired\n\n");
-
- vty_out (vty,
- "Interface Address Source Group CA eCA ATD eATD\n");
-
- for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
- pim_ifp = ch->interface->info;
-
- if (!pim_ifp)
- continue;
-
- ifaddr = pim_ifp->primary_address;
-
- char ch_src_str[INET_ADDRSTRLEN];
- char ch_grp_str[INET_ADDRSTRLEN];
-
- pim_inet4_dump("<ch_src?>", ch->sg.src,
- ch_src_str, sizeof(ch_src_str));
- pim_inet4_dump("<ch_grp?>", ch->sg.grp,
- ch_grp_str, sizeof(ch_grp_str));
- vty_out (vty, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
- ch->interface->name,
- inet_ntoa(ifaddr),
- ch_src_str,
- ch_grp_str,
- PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
- pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
- PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags) ? "yes" : "no",
- pim_macro_assert_tracking_desired_eval(ch) ? "yes" : "no");
- } /* scan interface channels */
+ struct pim_interface *pim_ifp;
+ struct listnode *ch_node;
+ struct pim_ifchannel *ch;
+ struct in_addr ifaddr;
+
+ vty_out(vty,
+ "CA: CouldAssert\n"
+ "ECA: Evaluate CouldAssert\n"
+ "ATD: AssertTrackingDesired\n"
+ "eATD: Evaluate AssertTrackingDesired\n\n");
+
+ vty_out(vty,
+ "Interface Address Source Group CA eCA ATD eATD\n");
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
+ pim_ifp = ch->interface->info;
+
+ if (!pim_ifp)
+ continue;
+
+ ifaddr = pim_ifp->primary_address;
+
+ char ch_src_str[INET_ADDRSTRLEN];
+ char ch_grp_str[INET_ADDRSTRLEN];
+
+ pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
+ sizeof(ch_src_str));
+ pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str,
+ sizeof(ch_grp_str));
+ vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
+ ch->interface->name, inet_ntoa(ifaddr), ch_src_str,
+ ch_grp_str,
+ PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
+ pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
+ PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags)
+ ? "yes"
+ : "no",
+ pim_macro_assert_tracking_desired_eval(ch) ? "yes"
+ : "no");
+ } /* scan interface channels */
}
static void pim_show_assert_metric(struct vty *vty)
{
- struct pim_interface *pim_ifp;
- struct listnode *ch_node;
- struct pim_ifchannel *ch;
- struct in_addr ifaddr;
+ struct pim_interface *pim_ifp;
+ struct listnode *ch_node;
+ struct pim_ifchannel *ch;
+ struct in_addr ifaddr;
- vty_out (vty,
- "Interface Address Source Group RPT Pref Metric Address \n");
+ vty_out(vty,
+ "Interface Address Source Group RPT Pref Metric Address \n");
- for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
- pim_ifp = ch->interface->info;
+ for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
+ pim_ifp = ch->interface->info;
- if (!pim_ifp)
- continue;
+ if (!pim_ifp)
+ continue;
- ifaddr = pim_ifp->primary_address;
+ ifaddr = pim_ifp->primary_address;
- char ch_src_str[INET_ADDRSTRLEN];
- char ch_grp_str[INET_ADDRSTRLEN];
- char addr_str[INET_ADDRSTRLEN];
- struct pim_assert_metric am;
+ char ch_src_str[INET_ADDRSTRLEN];
+ char ch_grp_str[INET_ADDRSTRLEN];
+ char addr_str[INET_ADDRSTRLEN];
+ struct pim_assert_metric am;
- am = pim_macro_spt_assert_metric(&ch->upstream->rpf, pim_ifp->primary_address);
+ am = pim_macro_spt_assert_metric(&ch->upstream->rpf,
+ pim_ifp->primary_address);
- pim_inet4_dump("<ch_src?>", ch->sg.src,
- ch_src_str, sizeof(ch_src_str));
- pim_inet4_dump("<ch_grp?>", ch->sg.grp,
- ch_grp_str, sizeof(ch_grp_str));
- pim_inet4_dump("<addr?>", am.ip_address,
- addr_str, sizeof(addr_str));
+ pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
+ sizeof(ch_src_str));
+ pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str,
+ sizeof(ch_grp_str));
+ pim_inet4_dump("<addr?>", am.ip_address, addr_str,
+ sizeof(addr_str));
- vty_out (vty, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
- ch->interface->name,
- inet_ntoa(ifaddr),
- ch_src_str,
- ch_grp_str,
- am.rpt_bit_flag ? "yes" : "no",
- am.metric_preference,
- am.route_metric,
- addr_str);
- } /* scan interface channels */
+ vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
+ ch->interface->name, inet_ntoa(ifaddr), ch_src_str,
+ ch_grp_str, am.rpt_bit_flag ? "yes" : "no",
+ am.metric_preference, am.route_metric, addr_str);
+ } /* scan interface channels */
}
static void pim_show_assert_winner_metric(struct vty *vty)
{
- struct pim_interface *pim_ifp;
- struct listnode *ch_node;
- struct pim_ifchannel *ch;
- struct in_addr ifaddr;
-
- vty_out (vty,
- "Interface Address Source Group RPT Pref Metric Address \n");
+ struct pim_interface *pim_ifp;
+ struct listnode *ch_node;
+ struct pim_ifchannel *ch;
+ struct in_addr ifaddr;
+
+ vty_out(vty,
+ "Interface Address Source Group RPT Pref Metric Address \n");
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
+ pim_ifp = ch->interface->info;
- for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
- pim_ifp = ch->interface->info;
-
- if (!pim_ifp)
- continue;
+ if (!pim_ifp)
+ continue;
- ifaddr = pim_ifp->primary_address;
+ ifaddr = pim_ifp->primary_address;
- char ch_src_str[INET_ADDRSTRLEN];
- char ch_grp_str[INET_ADDRSTRLEN];
- char addr_str[INET_ADDRSTRLEN];
- struct pim_assert_metric *am;
- char pref_str[5];
- char metr_str[7];
+ char ch_src_str[INET_ADDRSTRLEN];
+ char ch_grp_str[INET_ADDRSTRLEN];
+ char addr_str[INET_ADDRSTRLEN];
+ struct pim_assert_metric *am;
+ char pref_str[5];
+ char metr_str[7];
- am = &ch->ifassert_winner_metric;
+ am = &ch->ifassert_winner_metric;
- pim_inet4_dump("<ch_src?>", ch->sg.src,
- ch_src_str, sizeof(ch_src_str));
- pim_inet4_dump("<ch_grp?>", ch->sg.grp,
- ch_grp_str, sizeof(ch_grp_str));
- pim_inet4_dump("<addr?>", am->ip_address,
- addr_str, sizeof(addr_str));
+ pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
+ sizeof(ch_src_str));
+ pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str,
+ sizeof(ch_grp_str));
+ pim_inet4_dump("<addr?>", am->ip_address, addr_str,
+ sizeof(addr_str));
- if (am->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
- snprintf(pref_str, sizeof(pref_str), "INFI");
- else
- snprintf(pref_str, sizeof(pref_str), "%4u", am->metric_preference);
+ if (am->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
+ snprintf(pref_str, sizeof(pref_str), "INFI");
+ else
+ snprintf(pref_str, sizeof(pref_str), "%4u",
+ am->metric_preference);
- if (am->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX)
- snprintf(metr_str, sizeof(metr_str), "INFI");
- else
- snprintf(metr_str, sizeof(metr_str), "%6u", am->route_metric);
+ if (am->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX)
+ snprintf(metr_str, sizeof(metr_str), "INFI");
+ else
+ snprintf(metr_str, sizeof(metr_str), "%6u",
+ am->route_metric);
- vty_out (vty, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
- ch->interface->name,
- inet_ntoa(ifaddr),
- ch_src_str,
- ch_grp_str,
- am->rpt_bit_flag ? "yes" : "no",
- pref_str,
- metr_str,
- addr_str);
- } /* scan interface channels */
+ vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
+ ch->interface->name, inet_ntoa(ifaddr), ch_src_str,
+ ch_grp_str, am->rpt_bit_flag ? "yes" : "no", pref_str,
+ metr_str, addr_str);
+ } /* scan interface channels */
}
-static void json_object_pim_ifp_add(struct json_object *json, struct interface *ifp)
+static void json_object_pim_ifp_add(struct json_object *json,
+ struct interface *ifp)
{
- struct pim_interface *pim_ifp;
+ struct pim_interface *pim_ifp;
- pim_ifp = ifp->info;
- json_object_string_add(json, "name", ifp->name);
- json_object_string_add(json, "state", if_is_up(ifp) ? "up" : "down");
- json_object_string_add(json, "address", inet_ntoa(pim_ifp->primary_address));
- json_object_int_add(json, "index", ifp->ifindex);
+ pim_ifp = ifp->info;
+ json_object_string_add(json, "name", ifp->name);
+ json_object_string_add(json, "state", if_is_up(ifp) ? "up" : "down");
+ json_object_string_add(json, "address",
+ inet_ntoa(pim_ifp->primary_address));
+ json_object_int_add(json, "index", ifp->ifindex);
- if (if_is_multicast(ifp))
- json_object_boolean_true_add(json, "flagMulticast");
+ if (if_is_multicast(ifp))
+ json_object_boolean_true_add(json, "flagMulticast");
- if (if_is_broadcast(ifp))
- json_object_boolean_true_add(json, "flagBroadcast");
+ if (if_is_broadcast(ifp))
+ json_object_boolean_true_add(json, "flagBroadcast");
- if (ifp->flags & IFF_ALLMULTI)
- json_object_boolean_true_add(json, "flagAllMulticast");
+ if (ifp->flags & IFF_ALLMULTI)
+ json_object_boolean_true_add(json, "flagAllMulticast");
- if (ifp->flags & IFF_PROMISC)
- json_object_boolean_true_add(json, "flagPromiscuous");
+ if (ifp->flags & IFF_PROMISC)
+ json_object_boolean_true_add(json, "flagPromiscuous");
- if (PIM_IF_IS_DELETED(ifp))
- json_object_boolean_true_add(json, "flagDeleted");
+ if (PIM_IF_IS_DELETED(ifp))
+ json_object_boolean_true_add(json, "flagDeleted");
- if (pim_if_lan_delay_enabled(ifp))
- json_object_boolean_true_add(json, "lanDelayEnabled");
+ if (pim_if_lan_delay_enabled(ifp))
+ json_object_boolean_true_add(json, "lanDelayEnabled");
}
static void pim_show_membership(struct vty *vty, u_char uj)
{
- struct pim_interface *pim_ifp;
- struct listnode *ch_node;
- struct pim_ifchannel *ch;
- enum json_type type;
- json_object *json = NULL;
- json_object *json_iface = NULL;
- json_object *json_row = NULL;
- json_object *json_tmp = NULL;
-
- json = json_object_new_object();
-
- for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
-
- pim_ifp = ch->interface->info;
-
- if (!pim_ifp)
- continue;
-
- char ch_src_str[INET_ADDRSTRLEN];
- char ch_grp_str[INET_ADDRSTRLEN];
-
- pim_inet4_dump("<ch_src?>", ch->sg.src,
- ch_src_str, sizeof(ch_src_str));
- pim_inet4_dump("<ch_grp?>", ch->sg.grp,
- ch_grp_str, sizeof(ch_grp_str));
-
- json_object_object_get_ex(json, ch->interface->name, &json_iface);
-
- if (!json_iface) {
- json_iface = json_object_new_object();
- json_object_pim_ifp_add(json_iface, ch->interface);
- json_object_object_add(json, ch->interface->name, json_iface);
- }
-
- json_row = json_object_new_object();
- json_object_string_add(json_row, "source", ch_src_str);
- json_object_string_add(json_row, "group", ch_grp_str);
- json_object_string_add(json_row, "localMembership",
- ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO ? "NOINFO" : "INCLUDE");
- json_object_object_add(json_iface, ch_grp_str, json_row);
- } /* scan interface channels */
-
- if (uj) {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- } else {
- vty_out (vty,
- "Interface Address Source Group Membership\n");
-
- /*
- * Example of the json data we are traversing
- *
- * {
- * "swp3":{
- * "name":"swp3",
- * "state":"up",
- * "address":"10.1.20.1",
- * "index":5,
- * "flagMulticast":true,
- * "flagBroadcast":true,
- * "lanDelayEnabled":true,
- * "226.10.10.10":{
- * "source":"*",
- * "group":"226.10.10.10",
- * "localMembership":"INCLUDE"
- * }
- * }
- * }
- */
-
- /* foreach interface */
- json_object_object_foreach(json, key, val) {
-
- /* Find all of the keys where the val is an object. In the example
- * above the only one is 226.10.10.10
- */
- json_object_object_foreach(val, if_field_key, if_field_val) {
- type = json_object_get_type(if_field_val);
-
- if (type == json_type_object) {
- vty_out(vty, "%-9s ", key);
-
- json_object_object_get_ex(val, "address", &json_tmp);
- vty_out(vty, "%-15s ", json_object_get_string(json_tmp));
-
- json_object_object_get_ex(if_field_val, "source", &json_tmp);
- vty_out(vty, "%-15s ", json_object_get_string(json_tmp));
-
- /* Group */
- vty_out(vty, "%-15s ", if_field_key);
-
- json_object_object_get_ex(if_field_val, "localMembership", &json_tmp);
- vty_out (vty, "%-10s\n", json_object_get_string(json_tmp));
- }
- }
- }
- }
-
- json_object_free(json);
-}
-
-static void pim_print_ifp_flags(struct vty *vty, struct interface *ifp, int mloop)
-{
- vty_out (vty, "Flags\n");
- vty_out (vty, "-----\n");
- vty_out (vty, "All Multicast : %s\n",
- (ifp->flags & IFF_ALLMULTI) ? "yes" : "no");
- vty_out (vty, "Broadcast : %s\n",
- if_is_broadcast(ifp) ? "yes" : "no");
- vty_out (vty, "Deleted : %s\n",
- PIM_IF_IS_DELETED(ifp) ? "yes" : "no");
- vty_out (vty, "Interface Index : %d\n", ifp->ifindex);
- vty_out (vty, "Multicast : %s\n",
- if_is_multicast(ifp) ? "yes" : "no");
- vty_out (vty, "Multicast Loop : %d\n", mloop);
- vty_out (vty, "Promiscuous : %s\n",
- (ifp->flags & IFF_PROMISC) ? "yes" : "no");
- vty_out (vty, "\n");
- vty_out (vty, "\n");
+ struct pim_interface *pim_ifp;
+ struct listnode *ch_node;
+ struct pim_ifchannel *ch;
+ enum json_type type;
+ json_object *json = NULL;
+ json_object *json_iface = NULL;
+ json_object *json_row = NULL;
+ json_object *json_tmp = NULL;
+
+ json = json_object_new_object();
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
+
+ pim_ifp = ch->interface->info;
+
+ if (!pim_ifp)
+ continue;
+
+ char ch_src_str[INET_ADDRSTRLEN];
+ char ch_grp_str[INET_ADDRSTRLEN];
+
+ pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
+ sizeof(ch_src_str));
+ pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str,
+ sizeof(ch_grp_str));
+
+ json_object_object_get_ex(json, ch->interface->name,
+ &json_iface);
+
+ if (!json_iface) {
+ json_iface = json_object_new_object();
+ json_object_pim_ifp_add(json_iface, ch->interface);
+ json_object_object_add(json, ch->interface->name,
+ json_iface);
+ }
+
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "source", ch_src_str);
+ json_object_string_add(json_row, "group", ch_grp_str);
+ json_object_string_add(
+ json_row, "localMembership",
+ ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO
+ ? "NOINFO"
+ : "INCLUDE");
+ json_object_object_add(json_iface, ch_grp_str, json_row);
+ } /* scan interface channels */
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ } else {
+ vty_out(vty,
+ "Interface Address Source Group Membership\n");
+
+ /*
+ * Example of the json data we are traversing
+ *
+ * {
+ * "swp3":{
+ * "name":"swp3",
+ * "state":"up",
+ * "address":"10.1.20.1",
+ * "index":5,
+ * "flagMulticast":true,
+ * "flagBroadcast":true,
+ * "lanDelayEnabled":true,
+ * "226.10.10.10":{
+ * "source":"*",
+ * "group":"226.10.10.10",
+ * "localMembership":"INCLUDE"
+ * }
+ * }
+ * }
+ */
+
+ /* foreach interface */
+ json_object_object_foreach(json, key, val)
+ {
+
+ /* Find all of the keys where the val is an object. In
+ * the example
+ * above the only one is 226.10.10.10
+ */
+ json_object_object_foreach(val, if_field_key,
+ if_field_val)
+ {
+ type = json_object_get_type(if_field_val);
+
+ if (type == json_type_object) {
+ vty_out(vty, "%-9s ", key);
+
+ json_object_object_get_ex(
+ val, "address", &json_tmp);
+ vty_out(vty, "%-15s ",
+ json_object_get_string(
+ json_tmp));
+
+ json_object_object_get_ex(if_field_val,
+ "source",
+ &json_tmp);
+ vty_out(vty, "%-15s ",
+ json_object_get_string(
+ json_tmp));
+
+ /* Group */
+ vty_out(vty, "%-15s ", if_field_key);
+
+ json_object_object_get_ex(
+ if_field_val, "localMembership",
+ &json_tmp);
+ vty_out(vty, "%-10s\n",
+ json_object_get_string(
+ json_tmp));
+ }
+ }
+ }
+ }
+
+ json_object_free(json);
+}
+
+static void pim_print_ifp_flags(struct vty *vty, struct interface *ifp,
+ int mloop)
+{
+ vty_out(vty, "Flags\n");
+ vty_out(vty, "-----\n");
+ vty_out(vty, "All Multicast : %s\n",
+ (ifp->flags & IFF_ALLMULTI) ? "yes" : "no");
+ vty_out(vty, "Broadcast : %s\n",
+ if_is_broadcast(ifp) ? "yes" : "no");
+ vty_out(vty, "Deleted : %s\n",
+ PIM_IF_IS_DELETED(ifp) ? "yes" : "no");
+ vty_out(vty, "Interface Index : %d\n", ifp->ifindex);
+ vty_out(vty, "Multicast : %s\n",
+ if_is_multicast(ifp) ? "yes" : "no");
+ vty_out(vty, "Multicast Loop : %d\n", mloop);
+ vty_out(vty, "Promiscuous : %s\n",
+ (ifp->flags & IFF_PROMISC) ? "yes" : "no");
+ vty_out(vty, "\n");
+ vty_out(vty, "\n");
}
static void igmp_show_interfaces(struct vty *vty, u_char uj)
{
- struct listnode *node;
- struct interface *ifp;
- time_t now;
- json_object *json = NULL;
- json_object *json_row = NULL;
-
- now = pim_time_monotonic_sec();
-
- if (uj)
- json = json_object_new_object();
- else
- vty_out (vty,
- "Interface State Address V Querier Query Timer Uptime\n");
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
- struct pim_interface *pim_ifp;
- struct listnode *sock_node;
- struct igmp_sock *igmp;
-
- pim_ifp = ifp->info;
-
- if (!pim_ifp)
- continue;
-
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
- char uptime[10];
- char query_hhmmss[10];
-
- pim_time_uptime(uptime, sizeof(uptime), now - igmp->sock_creation);
- pim_time_timer_to_hhmmss(query_hhmmss, sizeof(query_hhmmss), igmp->t_igmp_query_timer);
-
- if (uj) {
- json_row = json_object_new_object();
- json_object_pim_ifp_add(json_row, ifp);
- json_object_string_add(json_row, "upTime", uptime);
- json_object_int_add(json_row, "version", pim_ifp->igmp_version);
-
- if (igmp->t_igmp_query_timer) {
- json_object_boolean_true_add(json_row, "querier");
- json_object_string_add(json_row, "queryTimer", query_hhmmss);
- }
-
- json_object_object_add(json, ifp->name, json_row);
-
- } else {
- vty_out (vty, "%-9s %5s %15s %d %7s %11s %8s\n",
- ifp->name,
- if_is_up(ifp) ? "up" : "down",
- inet_ntoa(igmp->ifaddr),
- pim_ifp->igmp_version,
- igmp->t_igmp_query_timer ? "local" : "other",
- query_hhmmss,
- uptime);
- }
- }
- }
-
- if (uj) {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
-}
-
-static void igmp_show_interfaces_single(struct vty *vty, const char *ifname, u_char uj)
-{
- struct igmp_sock *igmp;
- struct interface *ifp;
- struct listnode *node;
- struct listnode *sock_node;
- struct pim_interface *pim_ifp;
- char uptime[10];
- char query_hhmmss[10];
- char other_hhmmss[10];
- int found_ifname = 0;
- int sqi;
- int mloop;
- long gmi_msec; /* Group Membership Interval */
- long lmqt_msec;
- long ohpi_msec;
- long oqpi_msec; /* Other Querier Present Interval */
- long qri_msec;
- time_t now;
-
- json_object *json = NULL;
- json_object *json_row = NULL;
-
- if (uj)
- json = json_object_new_object();
-
- now = pim_time_monotonic_sec();
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
- pim_ifp = ifp->info;
-
- if (!pim_ifp)
- continue;
-
- if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
- continue;
-
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
- found_ifname = 1;
- pim_time_uptime(uptime, sizeof(uptime), now - igmp->sock_creation);
- pim_time_timer_to_hhmmss(query_hhmmss, sizeof(query_hhmmss), igmp->t_igmp_query_timer);
- pim_time_timer_to_hhmmss(other_hhmmss, sizeof(other_hhmmss), igmp->t_other_querier_timer);
-
- gmi_msec = PIM_IGMP_GMI_MSEC(igmp->querier_robustness_variable,
- igmp->querier_query_interval,
- pim_ifp->igmp_query_max_response_time_dsec);
-
- sqi = PIM_IGMP_SQI(pim_ifp->igmp_default_query_interval);
-
- oqpi_msec = PIM_IGMP_OQPI_MSEC(igmp->querier_robustness_variable,
- igmp->querier_query_interval,
- pim_ifp->igmp_query_max_response_time_dsec);
-
- lmqt_msec = PIM_IGMP_LMQT_MSEC(pim_ifp->igmp_query_max_response_time_dsec,
- igmp->querier_robustness_variable);
-
- ohpi_msec = PIM_IGMP_OHPI_DSEC(igmp->querier_robustness_variable,
- igmp->querier_query_interval,
- pim_ifp->igmp_query_max_response_time_dsec) * 100;
-
- qri_msec = pim_ifp->igmp_query_max_response_time_dsec * 100;
- mloop = pim_socket_mcastloop_get(pim_ifp->pim_sock_fd);
-
- if (uj) {
- json_row = json_object_new_object();
- json_object_pim_ifp_add(json_row, ifp);
- json_object_string_add(json_row, "upTime", uptime);
- json_object_string_add(json_row, "querier", igmp->t_igmp_query_timer ? "local" : "other");
- json_object_int_add(json_row, "queryStartCount", igmp->startup_query_count);
- json_object_string_add(json_row, "queryQueryTimer", query_hhmmss);
- json_object_string_add(json_row, "queryOtherTimer", other_hhmmss);
- json_object_int_add(json_row, "version", pim_ifp->igmp_version);
- json_object_int_add(json_row, "timerGroupMembershipIntervalMsec", gmi_msec);
- json_object_int_add(json_row, "timerLastMemberQueryMsec", lmqt_msec);
- json_object_int_add(json_row, "timerOlderHostPresentIntervalMsec", ohpi_msec);
- json_object_int_add(json_row, "timerOtherQuerierPresentIntervalMsec", oqpi_msec);
- json_object_int_add(json_row, "timerQueryInterval", igmp->querier_query_interval);
- json_object_int_add(json_row, "timerQueryResponseIntervalMsec", qri_msec);
- json_object_int_add(json_row, "timerRobustnessVariable", igmp->querier_robustness_variable);
- json_object_int_add(json_row, "timerStartupQueryInterval", sqi);
-
- json_object_object_add(json, ifp->name, json_row);
-
- } else {
- vty_out (vty, "Interface : %s\n", ifp->name);
- vty_out (vty, "State : %s\n", if_is_up(ifp) ? "up" : "down");
- vty_out (vty, "Address : %s\n",
- inet_ntoa(pim_ifp->primary_address));
- vty_out (vty, "Uptime : %s\n", uptime);
- vty_out (vty, "Version : %d\n", pim_ifp->igmp_version);
- vty_out (vty, "\n");
- vty_out (vty, "\n");
-
- vty_out (vty, "Querier\n");
- vty_out (vty, "-------\n");
- vty_out (vty, "Querier : %s\n",
- igmp->t_igmp_query_timer ? "local" : "other");
- vty_out (vty, "Start Count : %d\n", igmp->startup_query_count);
- vty_out (vty, "Query Timer : %s\n", query_hhmmss);
- vty_out (vty, "Other Timer : %s\n", other_hhmmss);
- vty_out (vty, "\n");
- vty_out (vty, "\n");
-
- vty_out (vty, "Timers\n");
- vty_out (vty, "------\n");
- vty_out (vty, "Group Membership Interval : %lis\n",
- gmi_msec / 1000);
- vty_out (vty, "Last Member Query Time : %lis\n",
- lmqt_msec / 1000);
- vty_out (vty, "Older Host Present Interval : %lis\n",
- ohpi_msec / 1000);
- vty_out (vty, "Other Querier Present Interval : %lis\n",
- oqpi_msec / 1000);
- vty_out (vty, "Query Interval : %ds\n",
- igmp->querier_query_interval);
- vty_out (vty, "Query Response Interval : %lis\n",
- qri_msec / 1000);
- vty_out (vty, "Robustness Variable : %d\n",
- igmp->querier_robustness_variable);
- vty_out (vty, "Startup Query Interval : %ds\n", sqi);
- vty_out (vty, "\n");
- vty_out (vty, "\n");
-
- pim_print_ifp_flags(vty, ifp, mloop);
- }
- }
- }
-
- if (uj) {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- } else {
- if (!found_ifname)
- vty_out (vty, "%% No such interface\n");
- }
+ struct listnode *node;
+ struct interface *ifp;
+ time_t now;
+ json_object *json = NULL;
+ json_object *json_row = NULL;
+
+ now = pim_time_monotonic_sec();
+
+ if (uj)
+ json = json_object_new_object();
+ else
+ vty_out(vty,
+ "Interface State Address V Querier Query Timer Uptime\n");
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ struct pim_interface *pim_ifp;
+ struct listnode *sock_node;
+ struct igmp_sock *igmp;
+
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
+ igmp)) {
+ char uptime[10];
+ char query_hhmmss[10];
+
+ pim_time_uptime(uptime, sizeof(uptime),
+ now - igmp->sock_creation);
+ pim_time_timer_to_hhmmss(query_hhmmss,
+ sizeof(query_hhmmss),
+ igmp->t_igmp_query_timer);
+
+ if (uj) {
+ json_row = json_object_new_object();
+ json_object_pim_ifp_add(json_row, ifp);
+ json_object_string_add(json_row, "upTime",
+ uptime);
+ json_object_int_add(json_row, "version",
+ pim_ifp->igmp_version);
+
+ if (igmp->t_igmp_query_timer) {
+ json_object_boolean_true_add(json_row,
+ "querier");
+ json_object_string_add(json_row,
+ "queryTimer",
+ query_hhmmss);
+ }
+
+ json_object_object_add(json, ifp->name,
+ json_row);
+
+ } else {
+ vty_out(vty,
+ "%-9s %5s %15s %d %7s %11s %8s\n",
+ ifp->name,
+ if_is_up(ifp) ? "up" : "down",
+ inet_ntoa(igmp->ifaddr),
+ pim_ifp->igmp_version,
+ igmp->t_igmp_query_timer ? "local"
+ : "other",
+ query_hhmmss, uptime);
+ }
+ }
+ }
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
+}
+
+static void igmp_show_interfaces_single(struct vty *vty, const char *ifname,
+ u_char uj)
+{
+ struct igmp_sock *igmp;
+ struct interface *ifp;
+ struct listnode *node;
+ struct listnode *sock_node;
+ struct pim_interface *pim_ifp;
+ char uptime[10];
+ char query_hhmmss[10];
+ char other_hhmmss[10];
+ int found_ifname = 0;
+ int sqi;
+ int mloop;
+ long gmi_msec; /* Group Membership Interval */
+ long lmqt_msec;
+ long ohpi_msec;
+ long oqpi_msec; /* Other Querier Present Interval */
+ long qri_msec;
+ time_t now;
+
+ json_object *json = NULL;
+ json_object *json_row = NULL;
+
+ if (uj)
+ json = json_object_new_object();
+
+ now = pim_time_monotonic_sec();
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
+ igmp)) {
+ found_ifname = 1;
+ pim_time_uptime(uptime, sizeof(uptime),
+ now - igmp->sock_creation);
+ pim_time_timer_to_hhmmss(query_hhmmss,
+ sizeof(query_hhmmss),
+ igmp->t_igmp_query_timer);
+ pim_time_timer_to_hhmmss(other_hhmmss,
+ sizeof(other_hhmmss),
+ igmp->t_other_querier_timer);
+
+ gmi_msec = PIM_IGMP_GMI_MSEC(
+ igmp->querier_robustness_variable,
+ igmp->querier_query_interval,
+ pim_ifp->igmp_query_max_response_time_dsec);
+
+ sqi = PIM_IGMP_SQI(
+ pim_ifp->igmp_default_query_interval);
+
+ oqpi_msec = PIM_IGMP_OQPI_MSEC(
+ igmp->querier_robustness_variable,
+ igmp->querier_query_interval,
+ pim_ifp->igmp_query_max_response_time_dsec);
+
+ lmqt_msec = PIM_IGMP_LMQT_MSEC(
+ pim_ifp->igmp_query_max_response_time_dsec,
+ igmp->querier_robustness_variable);
+
+ ohpi_msec =
+ PIM_IGMP_OHPI_DSEC(
+ igmp->querier_robustness_variable,
+ igmp->querier_query_interval,
+ pim_ifp->igmp_query_max_response_time_dsec)
+ * 100;
+
+ qri_msec = pim_ifp->igmp_query_max_response_time_dsec
+ * 100;
+ mloop = pim_socket_mcastloop_get(pim_ifp->pim_sock_fd);
+
+ if (uj) {
+ json_row = json_object_new_object();
+ json_object_pim_ifp_add(json_row, ifp);
+ json_object_string_add(json_row, "upTime",
+ uptime);
+ json_object_string_add(json_row, "querier",
+ igmp->t_igmp_query_timer
+ ? "local"
+ : "other");
+ json_object_int_add(json_row, "queryStartCount",
+ igmp->startup_query_count);
+ json_object_string_add(json_row,
+ "queryQueryTimer",
+ query_hhmmss);
+ json_object_string_add(json_row,
+ "queryOtherTimer",
+ other_hhmmss);
+ json_object_int_add(json_row, "version",
+ pim_ifp->igmp_version);
+ json_object_int_add(
+ json_row,
+ "timerGroupMembershipIntervalMsec",
+ gmi_msec);
+ json_object_int_add(json_row,
+ "timerLastMemberQueryMsec",
+ lmqt_msec);
+ json_object_int_add(
+ json_row,
+ "timerOlderHostPresentIntervalMsec",
+ ohpi_msec);
+ json_object_int_add(
+ json_row,
+ "timerOtherQuerierPresentIntervalMsec",
+ oqpi_msec);
+ json_object_int_add(
+ json_row, "timerQueryInterval",
+ igmp->querier_query_interval);
+ json_object_int_add(
+ json_row,
+ "timerQueryResponseIntervalMsec",
+ qri_msec);
+ json_object_int_add(
+ json_row, "timerRobustnessVariable",
+ igmp->querier_robustness_variable);
+ json_object_int_add(json_row,
+ "timerStartupQueryInterval",
+ sqi);
+
+ json_object_object_add(json, ifp->name,
+ json_row);
+
+ } else {
+ vty_out(vty, "Interface : %s\n", ifp->name);
+ vty_out(vty, "State : %s\n",
+ if_is_up(ifp) ? "up" : "down");
+ vty_out(vty, "Address : %s\n",
+ inet_ntoa(pim_ifp->primary_address));
+ vty_out(vty, "Uptime : %s\n", uptime);
+ vty_out(vty, "Version : %d\n",
+ pim_ifp->igmp_version);
+ vty_out(vty, "\n");
+ vty_out(vty, "\n");
+
+ vty_out(vty, "Querier\n");
+ vty_out(vty, "-------\n");
+ vty_out(vty, "Querier : %s\n",
+ igmp->t_igmp_query_timer ? "local"
+ : "other");
+ vty_out(vty, "Start Count : %d\n",
+ igmp->startup_query_count);
+ vty_out(vty, "Query Timer : %s\n",
+ query_hhmmss);
+ vty_out(vty, "Other Timer : %s\n",
+ other_hhmmss);
+ vty_out(vty, "\n");
+ vty_out(vty, "\n");
+
+ vty_out(vty, "Timers\n");
+ vty_out(vty, "------\n");
+ vty_out(vty,
+ "Group Membership Interval : %lis\n",
+ gmi_msec / 1000);
+ vty_out(vty,
+ "Last Member Query Time : %lis\n",
+ lmqt_msec / 1000);
+ vty_out(vty,
+ "Older Host Present Interval : %lis\n",
+ ohpi_msec / 1000);
+ vty_out(vty,
+ "Other Querier Present Interval : %lis\n",
+ oqpi_msec / 1000);
+ vty_out(vty,
+ "Query Interval : %ds\n",
+ igmp->querier_query_interval);
+ vty_out(vty,
+ "Query Response Interval : %lis\n",
+ qri_msec / 1000);
+ vty_out(vty,
+ "Robustness Variable : %d\n",
+ igmp->querier_robustness_variable);
+ vty_out(vty,
+ "Startup Query Interval : %ds\n",
+ sqi);
+ vty_out(vty, "\n");
+ vty_out(vty, "\n");
+
+ pim_print_ifp_flags(vty, ifp, mloop);
+ }
+ }
+ }
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ } else {
+ if (!found_ifname)
+ vty_out(vty, "%% No such interface\n");
+ }
}
static void igmp_show_interface_join(struct vty *vty)
{
- struct listnode *node;
- struct interface *ifp;
- time_t now;
-
- now = pim_time_monotonic_sec();
-
- vty_out (vty,
- "Interface Address Source Group Socket Uptime \n");
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
- struct pim_interface *pim_ifp;
- struct listnode *join_node;
- struct igmp_join *ij;
- struct in_addr pri_addr;
- char pri_addr_str[INET_ADDRSTRLEN];
-
- pim_ifp = ifp->info;
-
- if (!pim_ifp)
- continue;
-
- if (!pim_ifp->igmp_join_list)
- continue;
-
- pri_addr = pim_find_primary_addr(ifp);
- pim_inet4_dump("<pri?>", pri_addr, pri_addr_str, sizeof(pri_addr_str));
-
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_join_list, join_node, ij)) {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- char uptime[10];
-
- pim_time_uptime(uptime, sizeof(uptime), now - ij->sock_creation);
- pim_inet4_dump("<grp?>", ij->group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<src?>", ij->source_addr, source_str, sizeof(source_str));
-
- vty_out (vty, "%-9s %-15s %-15s %-15s %6d %8s\n",
- ifp->name,
- pri_addr_str,
- source_str,
- group_str,
- ij->sock_fd,
- uptime);
- } /* for (pim_ifp->igmp_join_list) */
-
- } /* for (iflist) */
-
-}
-
-static void pim_show_interfaces_single(struct vty *vty, const char *ifname, u_char uj)
-{
- struct in_addr ifaddr;
- struct interface *ifp;
- struct listnode *neighnode;
- struct listnode*node;
- struct listnode *upnode;
- struct pim_interface *pim_ifp;
- struct pim_neighbor *neigh;
- struct pim_upstream *up;
- time_t now;
- char dr_str[INET_ADDRSTRLEN];
- char dr_uptime[10];
- char expire[10];
- char grp_str[INET_ADDRSTRLEN];
- char hello_period[10];
- char hello_timer[10];
- char neigh_src_str[INET_ADDRSTRLEN];
- char src_str[INET_ADDRSTRLEN];
- char stat_uptime[10];
- char uptime[10];
- int mloop;
- int found_ifname = 0;
- int print_header;
- json_object *json = NULL;
- json_object *json_row = NULL;
- json_object *json_pim_neighbor = NULL;
- json_object *json_pim_neighbors = NULL;
- json_object *json_group = NULL;
- json_object *json_group_source = NULL;
- json_object *json_fhr_sources = NULL;
- struct pim_secondary_addr *sec_addr;
- struct listnode *sec_node;
-
- now = pim_time_monotonic_sec();
-
- if (uj)
- json = json_object_new_object();
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
- pim_ifp = ifp->info;
-
- if (!pim_ifp)
- continue;
-
- if (pim_ifp->pim_sock_fd < 0)
- continue;
-
- if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
- continue;
-
- found_ifname = 1;
- ifaddr = pim_ifp->primary_address;
- pim_inet4_dump("<dr?>", pim_ifp->pim_dr_addr, dr_str, sizeof(dr_str));
- pim_time_uptime_begin(dr_uptime, sizeof(dr_uptime), now, pim_ifp->pim_dr_election_last);
- pim_time_timer_to_hhmmss(hello_timer, sizeof(hello_timer), pim_ifp->t_pim_hello_timer);
- pim_time_mmss(hello_period, sizeof(hello_period), pim_ifp->pim_hello_period);
- pim_time_uptime(stat_uptime, sizeof(stat_uptime), now - pim_ifp->pim_ifstat_start);
- mloop = pim_socket_mcastloop_get(pim_ifp->pim_sock_fd);
-
- if (uj) {
- char pbuf[PREFIX2STR_BUFFER];
- json_row = json_object_new_object();
- json_object_pim_ifp_add(json_row, ifp);
-
- if (pim_ifp->update_source.s_addr != INADDR_ANY) {
- json_object_string_add(json_row, "useSource", inet_ntoa(pim_ifp->update_source));
- }
- if (pim_ifp->sec_addr_list) {
- json_object *sec_list = NULL;
-
- sec_list = json_object_new_array();
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, sec_node, sec_addr)) {
- json_object_array_add(sec_list,
- json_object_new_string(prefix2str(&sec_addr->addr,
- pbuf,
- sizeof(pbuf))));
- }
- json_object_object_add(json_row, "secondaryAddressList", sec_list);
- }
-
- // PIM neighbors
- if (pim_ifp->pim_neighbor_list->count) {
- json_pim_neighbors = json_object_new_object();
-
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
- json_pim_neighbor = json_object_new_object();
- pim_inet4_dump("<src?>", neigh->source_addr, neigh_src_str, sizeof(neigh_src_str));
- pim_time_uptime(uptime, sizeof(uptime), now - neigh->creation);
- pim_time_timer_to_hhmmss(expire, sizeof(expire), neigh->t_expire_timer);
-
- json_object_string_add(json_pim_neighbor, "address", neigh_src_str);
- json_object_string_add(json_pim_neighbor, "upTime", uptime);
- json_object_string_add(json_pim_neighbor, "holdtime", expire);
-
- json_object_object_add(json_pim_neighbors, neigh_src_str, json_pim_neighbor);
- }
-
- json_object_object_add(json_row, "neighbors", json_pim_neighbors);
- }
-
- json_object_string_add(json_row, "drAddress", dr_str);
- json_object_int_add(json_row, "drPriority", pim_ifp->pim_dr_priority);
- json_object_string_add(json_row, "drUptime", dr_uptime);
- json_object_int_add(json_row, "drElections", pim_ifp->pim_dr_election_count);
- json_object_int_add(json_row, "drChanges", pim_ifp->pim_dr_election_changes);
-
- // FHR
- for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode, up)) {
- if (ifp == up->rpf.source_nexthop.interface) {
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR) {
- if (!json_fhr_sources) {
- json_fhr_sources = json_object_new_object();
- }
-
- pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
- pim_time_uptime(uptime, sizeof(uptime), now - up->state_transition);
-
- /* Does this group live in json_fhr_sources? If not create it. */
- json_object_object_get_ex(json_fhr_sources, grp_str, &json_group);
-
- if (!json_group) {
- json_group = json_object_new_object();
- json_object_object_add(json_fhr_sources, grp_str, json_group);
- }
-
- json_group_source = json_object_new_object();
- json_object_string_add(json_group_source, "source", src_str);
- json_object_string_add(json_group_source, "group", grp_str);
- json_object_string_add(json_group_source, "upTime", uptime);
- json_object_object_add(json_group, src_str, json_group_source);
- }
- }
- }
-
- if (json_fhr_sources) {
- json_object_object_add(json_row, "firstHopRouter", json_fhr_sources);
- }
-
- json_object_int_add(json_row, "helloPeriod", pim_ifp->pim_hello_period);
- json_object_string_add(json_row, "helloTimer", hello_timer);
- json_object_string_add(json_row, "helloStatStart", stat_uptime);
- json_object_int_add(json_row, "helloReceived", pim_ifp->pim_ifstat_hello_recv);
- json_object_int_add(json_row, "helloReceivedFailed", pim_ifp->pim_ifstat_hello_recvfail);
- json_object_int_add(json_row, "helloSend", pim_ifp->pim_ifstat_hello_sent);
- json_object_int_add(json_row, "hellosendFailed", pim_ifp->pim_ifstat_hello_sendfail);
- json_object_int_add(json_row, "helloGenerationId", pim_ifp->pim_generation_id);
- json_object_int_add(json_row, "flagMulticastLoop", mloop);
-
- json_object_int_add(json_row, "effectivePropagationDelay", pim_if_effective_propagation_delay_msec(ifp));
- json_object_int_add(json_row, "effectiveOverrideInterval", pim_if_effective_override_interval_msec(ifp));
- json_object_int_add(json_row, "joinPruneOverrideInterval", pim_if_jp_override_interval_msec(ifp));
-
- json_object_int_add(json_row, "propagationDelay", pim_ifp->pim_propagation_delay_msec);
- json_object_int_add(json_row, "propagationDelayHighest", pim_ifp->pim_neighbors_highest_propagation_delay_msec);
- json_object_int_add(json_row, "overrideInterval", pim_ifp->pim_override_interval_msec);
- json_object_int_add(json_row, "overrideIntervalHighest", pim_ifp->pim_neighbors_highest_override_interval_msec);
- json_object_object_add(json, ifp->name, json_row);
-
- } else {
- vty_out (vty, "Interface : %s\n", ifp->name);
- vty_out (vty, "State : %s\n", if_is_up(ifp) ? "up" : "down");
- if (pim_ifp->update_source.s_addr != INADDR_ANY) {
- vty_out (vty, "Use Source : %s\n", inet_ntoa(pim_ifp->update_source));
- }
- if (pim_ifp->sec_addr_list) {
- char pbuf[PREFIX2STR_BUFFER];
- vty_out (vty, "Address : %s (primary)\n",
- inet_ntoa(ifaddr));
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, sec_node, sec_addr)) {
- vty_out (vty, " %s\n",
- prefix2str(&sec_addr->addr, pbuf, sizeof(pbuf)));
- }
- } else {
- vty_out (vty, "Address : %s\n", inet_ntoa(ifaddr));
- }
- vty_out (vty, "\n");
-
- // PIM neighbors
- print_header = 1;
-
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
-
- if (print_header) {
- vty_out (vty, "PIM Neighbors\n");
- vty_out (vty, "-------------\n");
- print_header = 0;
- }
-
- pim_inet4_dump("<src?>", neigh->source_addr, neigh_src_str, sizeof(neigh_src_str));
- pim_time_uptime(uptime, sizeof(uptime), now - neigh->creation);
- pim_time_timer_to_hhmmss(expire, sizeof(expire), neigh->t_expire_timer);
- vty_out (vty, "%-15s : up for %s, holdtime expires in %s\n", neigh_src_str, uptime,
- expire);
- }
-
- if (!print_header) {
- vty_out (vty, "\n");
- vty_out (vty, "\n");
- }
-
- vty_out (vty, "Designated Router\n");
- vty_out (vty, "-----------------\n");
- vty_out (vty, "Address : %s\n", dr_str);
- vty_out (vty, "Priority : %d\n", pim_ifp->pim_dr_priority);
- vty_out (vty, "Uptime : %s\n", dr_uptime);
- vty_out (vty, "Elections : %d\n", pim_ifp->pim_dr_election_count);
- vty_out (vty, "Changes : %d\n", pim_ifp->pim_dr_election_changes);
- vty_out (vty, "\n");
- vty_out (vty, "\n");
-
- // FHR
- print_header = 1;
- for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode, up)) {
- if (strcmp(ifp->name, up->rpf.source_nexthop.interface->name) == 0) {
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR) {
-
- if (print_header) {
- vty_out (vty, "FHR - First Hop Router\n");
- vty_out (vty, "----------------------\n");
- print_header = 0;
- }
-
- pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
- pim_time_uptime(uptime, sizeof(uptime), now - up->state_transition);
- vty_out (vty, "%s : %s is a source, uptime is %s\n", grp_str, src_str,
- uptime);
- }
- }
- }
-
- if (!print_header) {
- vty_out (vty, "\n");
- vty_out (vty, "\n");
- }
-
- vty_out (vty, "Hellos\n");
- vty_out (vty, "------\n");
- vty_out (vty, "Period : %d\n", pim_ifp->pim_hello_period);
- vty_out (vty, "Timer : %s\n", hello_timer);
- vty_out (vty, "StatStart : %s\n", stat_uptime);
- vty_out (vty, "Receive : %d\n", pim_ifp->pim_ifstat_hello_recv);
- vty_out (vty, "Receive Failed : %d\n",
- pim_ifp->pim_ifstat_hello_recvfail);
- vty_out (vty, "Send : %d\n", pim_ifp->pim_ifstat_hello_sent);
- vty_out (vty, "Send Failed : %d\n",
- pim_ifp->pim_ifstat_hello_sendfail);
- vty_out (vty, "Generation ID : %08x\n", pim_ifp->pim_generation_id);
- vty_out (vty, "\n");
- vty_out (vty, "\n");
-
- pim_print_ifp_flags(vty, ifp, mloop);
-
- vty_out (vty, "Join Prune Interval\n");
- vty_out (vty, "-------------------\n");
- vty_out (vty, "LAN Delay : %s\n",
- pim_if_lan_delay_enabled(ifp) ? "yes" : "no");
- vty_out (vty, "Effective Propagation Delay : %d msec\n",
- pim_if_effective_propagation_delay_msec(ifp));
- vty_out (vty, "Effective Override Interval : %d msec\n",
- pim_if_effective_override_interval_msec(ifp));
- vty_out (vty, "Join Prune Override Interval : %d msec\n",
- pim_if_jp_override_interval_msec(ifp));
- vty_out (vty, "\n");
- vty_out (vty, "\n");
-
- vty_out (vty, "LAN Prune Delay\n");
- vty_out (vty, "---------------\n");
- vty_out (vty, "Propagation Delay : %d msec\n",
- pim_ifp->pim_propagation_delay_msec);
- vty_out (vty, "Propagation Delay (Highest) : %d msec\n",
- pim_ifp->pim_neighbors_highest_propagation_delay_msec);
- vty_out (vty, "Override Interval : %d msec\n",
- pim_ifp->pim_override_interval_msec);
- vty_out (vty, "Override Interval (Highest) : %d msec\n",
- pim_ifp->pim_neighbors_highest_override_interval_msec);
- vty_out (vty, "\n");
- vty_out (vty, "\n");
- }
- }
-
- if (uj) {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- } else {
- if (!found_ifname)
- vty_out (vty, "%% No such interface\n");
- }
+ struct listnode *node;
+ struct interface *ifp;
+ time_t now;
+
+ now = pim_time_monotonic_sec();
+
+ vty_out(vty,
+ "Interface Address Source Group Socket Uptime \n");
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ struct pim_interface *pim_ifp;
+ struct listnode *join_node;
+ struct igmp_join *ij;
+ struct in_addr pri_addr;
+ char pri_addr_str[INET_ADDRSTRLEN];
+
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ if (!pim_ifp->igmp_join_list)
+ continue;
+
+ pri_addr = pim_find_primary_addr(ifp);
+ pim_inet4_dump("<pri?>", pri_addr, pri_addr_str,
+ sizeof(pri_addr_str));
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_join_list, join_node,
+ ij)) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ char uptime[10];
+
+ pim_time_uptime(uptime, sizeof(uptime),
+ now - ij->sock_creation);
+ pim_inet4_dump("<grp?>", ij->group_addr, group_str,
+ sizeof(group_str));
+ pim_inet4_dump("<src?>", ij->source_addr, source_str,
+ sizeof(source_str));
+
+ vty_out(vty, "%-9s %-15s %-15s %-15s %6d %8s\n",
+ ifp->name, pri_addr_str, source_str, group_str,
+ ij->sock_fd, uptime);
+ } /* for (pim_ifp->igmp_join_list) */
+
+ } /* for (iflist) */
+}
+
+static void pim_show_interfaces_single(struct vty *vty, const char *ifname,
+ u_char uj)
+{
+ struct in_addr ifaddr;
+ struct interface *ifp;
+ struct listnode *neighnode;
+ struct listnode *node;
+ struct listnode *upnode;
+ struct pim_interface *pim_ifp;
+ struct pim_neighbor *neigh;
+ struct pim_upstream *up;
+ time_t now;
+ char dr_str[INET_ADDRSTRLEN];
+ char dr_uptime[10];
+ char expire[10];
+ char grp_str[INET_ADDRSTRLEN];
+ char hello_period[10];
+ char hello_timer[10];
+ char neigh_src_str[INET_ADDRSTRLEN];
+ char src_str[INET_ADDRSTRLEN];
+ char stat_uptime[10];
+ char uptime[10];
+ int mloop;
+ int found_ifname = 0;
+ int print_header;
+ json_object *json = NULL;
+ json_object *json_row = NULL;
+ json_object *json_pim_neighbor = NULL;
+ json_object *json_pim_neighbors = NULL;
+ json_object *json_group = NULL;
+ json_object *json_group_source = NULL;
+ json_object *json_fhr_sources = NULL;
+ struct pim_secondary_addr *sec_addr;
+ struct listnode *sec_node;
+
+ now = pim_time_monotonic_sec();
+
+ if (uj)
+ json = json_object_new_object();
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ if (pim_ifp->pim_sock_fd < 0)
+ continue;
+
+ if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
+ continue;
+
+ found_ifname = 1;
+ ifaddr = pim_ifp->primary_address;
+ pim_inet4_dump("<dr?>", pim_ifp->pim_dr_addr, dr_str,
+ sizeof(dr_str));
+ pim_time_uptime_begin(dr_uptime, sizeof(dr_uptime), now,
+ pim_ifp->pim_dr_election_last);
+ pim_time_timer_to_hhmmss(hello_timer, sizeof(hello_timer),
+ pim_ifp->t_pim_hello_timer);
+ pim_time_mmss(hello_period, sizeof(hello_period),
+ pim_ifp->pim_hello_period);
+ pim_time_uptime(stat_uptime, sizeof(stat_uptime),
+ now - pim_ifp->pim_ifstat_start);
+ mloop = pim_socket_mcastloop_get(pim_ifp->pim_sock_fd);
+
+ if (uj) {
+ char pbuf[PREFIX2STR_BUFFER];
+ json_row = json_object_new_object();
+ json_object_pim_ifp_add(json_row, ifp);
+
+ if (pim_ifp->update_source.s_addr != INADDR_ANY) {
+ json_object_string_add(
+ json_row, "useSource",
+ inet_ntoa(pim_ifp->update_source));
+ }
+ if (pim_ifp->sec_addr_list) {
+ json_object *sec_list = NULL;
+
+ sec_list = json_object_new_array();
+ for (ALL_LIST_ELEMENTS_RO(
+ pim_ifp->sec_addr_list, sec_node,
+ sec_addr)) {
+ json_object_array_add(
+ sec_list,
+ json_object_new_string(
+ prefix2str(
+ &sec_addr->addr,
+ pbuf,
+ sizeof(pbuf))));
+ }
+ json_object_object_add(json_row,
+ "secondaryAddressList",
+ sec_list);
+ }
+
+ // PIM neighbors
+ if (pim_ifp->pim_neighbor_list->count) {
+ json_pim_neighbors = json_object_new_object();
+
+ for (ALL_LIST_ELEMENTS_RO(
+ pim_ifp->pim_neighbor_list,
+ neighnode, neigh)) {
+ json_pim_neighbor =
+ json_object_new_object();
+ pim_inet4_dump("<src?>",
+ neigh->source_addr,
+ neigh_src_str,
+ sizeof(neigh_src_str));
+ pim_time_uptime(uptime, sizeof(uptime),
+ now - neigh->creation);
+ pim_time_timer_to_hhmmss(
+ expire, sizeof(expire),
+ neigh->t_expire_timer);
+
+ json_object_string_add(
+ json_pim_neighbor, "address",
+ neigh_src_str);
+ json_object_string_add(
+ json_pim_neighbor, "upTime",
+ uptime);
+ json_object_string_add(
+ json_pim_neighbor, "holdtime",
+ expire);
+
+ json_object_object_add(
+ json_pim_neighbors,
+ neigh_src_str,
+ json_pim_neighbor);
+ }
+
+ json_object_object_add(json_row, "neighbors",
+ json_pim_neighbors);
+ }
+
+ json_object_string_add(json_row, "drAddress", dr_str);
+ json_object_int_add(json_row, "drPriority",
+ pim_ifp->pim_dr_priority);
+ json_object_string_add(json_row, "drUptime", dr_uptime);
+ json_object_int_add(json_row, "drElections",
+ pim_ifp->pim_dr_election_count);
+ json_object_int_add(json_row, "drChanges",
+ pim_ifp->pim_dr_election_changes);
+
+ // FHR
+ for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode,
+ up)) {
+ if (ifp == up->rpf.source_nexthop.interface) {
+ if (up->flags
+ & PIM_UPSTREAM_FLAG_MASK_FHR) {
+ if (!json_fhr_sources) {
+ json_fhr_sources =
+ json_object_new_object();
+ }
+
+ pim_inet4_dump("<src?>",
+ up->sg.src,
+ src_str,
+ sizeof(src_str));
+ pim_inet4_dump("<grp?>",
+ up->sg.grp,
+ grp_str,
+ sizeof(grp_str));
+ pim_time_uptime(
+ uptime, sizeof(uptime),
+ now - up->state_transition);
+
+ /* Does this group live in
+ * json_fhr_sources? If not
+ * create it. */
+ json_object_object_get_ex(
+ json_fhr_sources,
+ grp_str, &json_group);
+
+ if (!json_group) {
+ json_group =
+ json_object_new_object();
+ json_object_object_add(
+ json_fhr_sources,
+ grp_str,
+ json_group);
+ }
+
+ json_group_source =
+ json_object_new_object();
+ json_object_string_add(
+ json_group_source,
+ "source", src_str);
+ json_object_string_add(
+ json_group_source,
+ "group", grp_str);
+ json_object_string_add(
+ json_group_source,
+ "upTime", uptime);
+ json_object_object_add(
+ json_group, src_str,
+ json_group_source);
+ }
+ }
+ }
+
+ if (json_fhr_sources) {
+ json_object_object_add(json_row,
+ "firstHopRouter",
+ json_fhr_sources);
+ }
+
+ json_object_int_add(json_row, "helloPeriod",
+ pim_ifp->pim_hello_period);
+ json_object_string_add(json_row, "helloTimer",
+ hello_timer);
+ json_object_string_add(json_row, "helloStatStart",
+ stat_uptime);
+ json_object_int_add(json_row, "helloReceived",
+ pim_ifp->pim_ifstat_hello_recv);
+ json_object_int_add(json_row, "helloReceivedFailed",
+ pim_ifp->pim_ifstat_hello_recvfail);
+ json_object_int_add(json_row, "helloSend",
+ pim_ifp->pim_ifstat_hello_sent);
+ json_object_int_add(json_row, "hellosendFailed",
+ pim_ifp->pim_ifstat_hello_sendfail);
+ json_object_int_add(json_row, "helloGenerationId",
+ pim_ifp->pim_generation_id);
+ json_object_int_add(json_row, "flagMulticastLoop",
+ mloop);
+
+ json_object_int_add(
+ json_row, "effectivePropagationDelay",
+ pim_if_effective_propagation_delay_msec(ifp));
+ json_object_int_add(
+ json_row, "effectiveOverrideInterval",
+ pim_if_effective_override_interval_msec(ifp));
+ json_object_int_add(
+ json_row, "joinPruneOverrideInterval",
+ pim_if_jp_override_interval_msec(ifp));
+
+ json_object_int_add(
+ json_row, "propagationDelay",
+ pim_ifp->pim_propagation_delay_msec);
+ json_object_int_add(
+ json_row, "propagationDelayHighest",
+ pim_ifp->pim_neighbors_highest_propagation_delay_msec);
+ json_object_int_add(
+ json_row, "overrideInterval",
+ pim_ifp->pim_override_interval_msec);
+ json_object_int_add(
+ json_row, "overrideIntervalHighest",
+ pim_ifp->pim_neighbors_highest_override_interval_msec);
+ json_object_object_add(json, ifp->name, json_row);
+
+ } else {
+ vty_out(vty, "Interface : %s\n", ifp->name);
+ vty_out(vty, "State : %s\n",
+ if_is_up(ifp) ? "up" : "down");
+ if (pim_ifp->update_source.s_addr != INADDR_ANY) {
+ vty_out(vty, "Use Source : %s\n",
+ inet_ntoa(pim_ifp->update_source));
+ }
+ if (pim_ifp->sec_addr_list) {
+ char pbuf[PREFIX2STR_BUFFER];
+ vty_out(vty, "Address : %s (primary)\n",
+ inet_ntoa(ifaddr));
+ for (ALL_LIST_ELEMENTS_RO(
+ pim_ifp->sec_addr_list, sec_node,
+ sec_addr)) {
+ vty_out(vty, " %s\n",
+ prefix2str(&sec_addr->addr,
+ pbuf, sizeof(pbuf)));
+ }
+ } else {
+ vty_out(vty, "Address : %s\n",
+ inet_ntoa(ifaddr));
+ }
+ vty_out(vty, "\n");
+
+ // PIM neighbors
+ print_header = 1;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list,
+ neighnode, neigh)) {
+
+ if (print_header) {
+ vty_out(vty, "PIM Neighbors\n");
+ vty_out(vty, "-------------\n");
+ print_header = 0;
+ }
+
+ pim_inet4_dump("<src?>", neigh->source_addr,
+ neigh_src_str,
+ sizeof(neigh_src_str));
+ pim_time_uptime(uptime, sizeof(uptime),
+ now - neigh->creation);
+ pim_time_timer_to_hhmmss(expire, sizeof(expire),
+ neigh->t_expire_timer);
+ vty_out(vty,
+ "%-15s : up for %s, holdtime expires in %s\n",
+ neigh_src_str, uptime, expire);
+ }
+
+ if (!print_header) {
+ vty_out(vty, "\n");
+ vty_out(vty, "\n");
+ }
+
+ vty_out(vty, "Designated Router\n");
+ vty_out(vty, "-----------------\n");
+ vty_out(vty, "Address : %s\n", dr_str);
+ vty_out(vty, "Priority : %d\n",
+ pim_ifp->pim_dr_priority);
+ vty_out(vty, "Uptime : %s\n", dr_uptime);
+ vty_out(vty, "Elections : %d\n",
+ pim_ifp->pim_dr_election_count);
+ vty_out(vty, "Changes : %d\n",
+ pim_ifp->pim_dr_election_changes);
+ vty_out(vty, "\n");
+ vty_out(vty, "\n");
+
+ // FHR
+ print_header = 1;
+ for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode,
+ up)) {
+ if (strcmp(ifp->name,
+ up->rpf.source_nexthop
+ .interface->name)
+ == 0) {
+ if (up->flags
+ & PIM_UPSTREAM_FLAG_MASK_FHR) {
+
+ if (print_header) {
+ vty_out(vty,
+ "FHR - First Hop Router\n");
+ vty_out(vty,
+ "----------------------\n");
+ print_header = 0;
+ }
+
+ pim_inet4_dump("<src?>",
+ up->sg.src,
+ src_str,
+ sizeof(src_str));
+ pim_inet4_dump("<grp?>",
+ up->sg.grp,
+ grp_str,
+ sizeof(grp_str));
+ pim_time_uptime(
+ uptime, sizeof(uptime),
+ now - up->state_transition);
+ vty_out(vty,
+ "%s : %s is a source, uptime is %s\n",
+ grp_str, src_str,
+ uptime);
+ }
+ }
+ }
+
+ if (!print_header) {
+ vty_out(vty, "\n");
+ vty_out(vty, "\n");
+ }
+
+ vty_out(vty, "Hellos\n");
+ vty_out(vty, "------\n");
+ vty_out(vty, "Period : %d\n",
+ pim_ifp->pim_hello_period);
+ vty_out(vty, "Timer : %s\n", hello_timer);
+ vty_out(vty, "StatStart : %s\n", stat_uptime);
+ vty_out(vty, "Receive : %d\n",
+ pim_ifp->pim_ifstat_hello_recv);
+ vty_out(vty, "Receive Failed : %d\n",
+ pim_ifp->pim_ifstat_hello_recvfail);
+ vty_out(vty, "Send : %d\n",
+ pim_ifp->pim_ifstat_hello_sent);
+ vty_out(vty, "Send Failed : %d\n",
+ pim_ifp->pim_ifstat_hello_sendfail);
+ vty_out(vty, "Generation ID : %08x\n",
+ pim_ifp->pim_generation_id);
+ vty_out(vty, "\n");
+ vty_out(vty, "\n");
+
+ pim_print_ifp_flags(vty, ifp, mloop);
+
+ vty_out(vty, "Join Prune Interval\n");
+ vty_out(vty, "-------------------\n");
+ vty_out(vty, "LAN Delay : %s\n",
+ pim_if_lan_delay_enabled(ifp) ? "yes" : "no");
+ vty_out(vty, "Effective Propagation Delay : %d msec\n",
+ pim_if_effective_propagation_delay_msec(ifp));
+ vty_out(vty, "Effective Override Interval : %d msec\n",
+ pim_if_effective_override_interval_msec(ifp));
+ vty_out(vty, "Join Prune Override Interval : %d msec\n",
+ pim_if_jp_override_interval_msec(ifp));
+ vty_out(vty, "\n");
+ vty_out(vty, "\n");
+
+ vty_out(vty, "LAN Prune Delay\n");
+ vty_out(vty, "---------------\n");
+ vty_out(vty, "Propagation Delay : %d msec\n",
+ pim_ifp->pim_propagation_delay_msec);
+ vty_out(vty, "Propagation Delay (Highest) : %d msec\n",
+ pim_ifp->pim_neighbors_highest_propagation_delay_msec);
+ vty_out(vty, "Override Interval : %d msec\n",
+ pim_ifp->pim_override_interval_msec);
+ vty_out(vty, "Override Interval (Highest) : %d msec\n",
+ pim_ifp->pim_neighbors_highest_override_interval_msec);
+ vty_out(vty, "\n");
+ vty_out(vty, "\n");
+ }
+ }
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ } else {
+ if (!found_ifname)
+ vty_out(vty, "%% No such interface\n");
+ }
}
static void pim_show_interfaces(struct vty *vty, u_char uj)
{
- struct interface *ifp;
- struct listnode *node;
- struct listnode *upnode;
- struct pim_interface *pim_ifp;
- struct pim_upstream *up;
- int fhr = 0;
- int pim_nbrs = 0;
- int pim_ifchannels = 0;
- json_object *json = NULL;
- json_object *json_row = NULL;
- json_object *json_tmp;
-
- json = json_object_new_object();
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
- pim_ifp = ifp->info;
-
- if (!pim_ifp)
- continue;
-
- if (pim_ifp->pim_sock_fd < 0)
- continue;
-
- pim_nbrs = pim_ifp->pim_neighbor_list->count;
- pim_ifchannels = pim_ifp->pim_ifchannel_list->count;
- fhr = 0;
-
- for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode, up))
- if (ifp == up->rpf.source_nexthop.interface)
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
- fhr++;
-
- json_row = json_object_new_object();
- json_object_pim_ifp_add(json_row, ifp);
- json_object_int_add(json_row, "pimNeighbors", pim_nbrs);
- json_object_int_add(json_row, "pimIfChannels", pim_ifchannels);
- json_object_int_add(json_row, "firstHopRouter", fhr);
- json_object_string_add(json_row, "pimDesignatedRouter", inet_ntoa(pim_ifp->pim_dr_addr));
-
- if (pim_ifp->pim_dr_addr.s_addr == pim_ifp->primary_address.s_addr)
- json_object_boolean_true_add(json_row, "pimDesignatedRouterLocal");
-
- json_object_object_add(json, ifp->name, json_row);
- }
-
- if (uj) {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- } else {
- vty_out (vty,
- "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
-
- json_object_object_foreach(json, key, val) {
- vty_out(vty, "%-9s ", key);
-
- json_object_object_get_ex(val, "state", &json_tmp);
- vty_out(vty, "%5s ", json_object_get_string(json_tmp));
-
- json_object_object_get_ex(val, "address", &json_tmp);
- vty_out(vty, "%15s ", json_object_get_string(json_tmp));
-
- json_object_object_get_ex(val, "pimNeighbors", &json_tmp);
- vty_out(vty, "%8d ", json_object_get_int(json_tmp));
-
- if (json_object_object_get_ex(val, "pimDesignatedRouterLocal", &json_tmp)) {
- vty_out(vty, "%15s ", "local");
- } else {
- json_object_object_get_ex(val, "pimDesignatedRouter", &json_tmp);
- vty_out(vty, "%15s ", json_object_get_string(json_tmp));
- }
-
- json_object_object_get_ex(val, "firstHopRouter", &json_tmp);
- vty_out(vty, "%3d ", json_object_get_int(json_tmp));
-
- json_object_object_get_ex(val, "pimIfChannels", &json_tmp);
- vty_out (vty, "%9d\n", json_object_get_int(json_tmp));
- }
- }
-
- json_object_free(json);
-}
-
-static void pim_show_interface_traffic (struct vty *vty, u_char uj)
-{
- struct interface *ifp = NULL;
- struct pim_interface *pim_ifp = NULL;
- struct listnode *node = NULL;
- json_object *json = NULL;
- json_object *json_row = NULL;
-
- if (uj)
- json = json_object_new_object ();
- else
- {
- vty_out (vty, "\n");
- vty_out (vty, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
- " HELLO", " JOIN", " PRUNE", " REGISTER",
- " REGISTER-STOP", " ASSERT");
- vty_out (vty,
- "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n",
- "", " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
- " Rx/Tx", " Rx/Tx");
- vty_out (vty,
- "---------------------------------------------------------------------------------------------------------------\n");
- }
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
- {
- pim_ifp = ifp->info;
-
- if (!pim_ifp)
- continue;
-
- if (pim_ifp->pim_sock_fd < 0)
- continue;
- if (uj)
- {
- json_row = json_object_new_object ();
- json_object_pim_ifp_add (json_row, ifp);
- json_object_int_add (json_row, "helloRx", pim_ifp->pim_ifstat_hello_recv);
- json_object_int_add (json_row, "helloTx", pim_ifp->pim_ifstat_hello_sent);
- json_object_int_add (json_row, "joinRx", pim_ifp->pim_ifstat_join_recv);
- json_object_int_add (json_row, "joinTx", pim_ifp->pim_ifstat_join_send);
- json_object_int_add (json_row, "registerRx", pim_ifp->pim_ifstat_reg_recv);
- json_object_int_add (json_row, "registerTx", pim_ifp->pim_ifstat_reg_recv);
- json_object_int_add (json_row, "registerStopRx", pim_ifp->pim_ifstat_reg_stop_recv);
- json_object_int_add (json_row, "registerStopTx", pim_ifp->pim_ifstat_reg_stop_send);
- json_object_int_add (json_row, "assertRx", pim_ifp->pim_ifstat_assert_recv);
- json_object_int_add (json_row, "assertTx", pim_ifp->pim_ifstat_assert_send);
-
- json_object_object_add (json, ifp->name, json_row);
- }
- else
- {
- vty_out (vty,
- "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
- ifp->name, pim_ifp->pim_ifstat_hello_recv,
- pim_ifp->pim_ifstat_hello_sent, pim_ifp->pim_ifstat_join_recv,
- pim_ifp->pim_ifstat_join_send, pim_ifp->pim_ifstat_prune_recv,
- pim_ifp->pim_ifstat_prune_send, pim_ifp->pim_ifstat_reg_recv,
- pim_ifp->pim_ifstat_reg_send,
- pim_ifp->pim_ifstat_reg_stop_recv,
- pim_ifp->pim_ifstat_reg_stop_send,
- pim_ifp->pim_ifstat_assert_recv,
- pim_ifp->pim_ifstat_assert_send);
- }
- }
- if (uj)
- {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free (json);
- }
-}
-
-static void pim_show_interface_traffic_single (struct vty *vty, const char *ifname, u_char uj)
-{
- struct interface *ifp = NULL;
- struct pim_interface *pim_ifp = NULL;
- struct listnode *node = NULL;
- json_object *json = NULL;
- json_object *json_row = NULL;
- uint8_t found_ifname = 0;
-
- if (uj)
- json = json_object_new_object ();
- else
- {
- vty_out (vty, "\n");
- vty_out (vty, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
- " HELLO", " JOIN", " PRUNE", " REGISTER",
- " REGISTER-STOP", " ASSERT");
- vty_out (vty,
- "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n",
- "", " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
- " Rx/Tx", " Rx/Tx");
- vty_out (vty,
- "---------------------------------------------------------------------------------------------------------------\n");
- }
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
- {
- if (strcmp (ifname, ifp->name))
- continue;
-
- pim_ifp = ifp->info;
-
- if (!pim_ifp)
- continue;
-
- if (pim_ifp->pim_sock_fd < 0)
- continue;
-
- found_ifname = 1;
- if (uj)
- {
- json_row = json_object_new_object ();
- json_object_pim_ifp_add (json_row, ifp);
- json_object_int_add (json_row, "helloRx", pim_ifp->pim_ifstat_hello_recv);
- json_object_int_add (json_row, "helloTx", pim_ifp->pim_ifstat_hello_sent);
- json_object_int_add (json_row, "joinRx", pim_ifp->pim_ifstat_join_recv);
- json_object_int_add (json_row, "joinTx", pim_ifp->pim_ifstat_join_send);
- json_object_int_add (json_row, "registerRx", pim_ifp->pim_ifstat_reg_recv);
- json_object_int_add (json_row, "registerTx", pim_ifp->pim_ifstat_reg_recv);
- json_object_int_add (json_row, "registerStopRx", pim_ifp->pim_ifstat_reg_stop_recv);
- json_object_int_add (json_row, "registerStopTx", pim_ifp->pim_ifstat_reg_stop_send);
- json_object_int_add (json_row, "assertRx", pim_ifp->pim_ifstat_assert_recv);
- json_object_int_add (json_row, "assertTx", pim_ifp->pim_ifstat_assert_send);
-
- json_object_object_add (json, ifp->name, json_row);
- }
- else
- {
- vty_out (vty,
- "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
- ifp->name, pim_ifp->pim_ifstat_hello_recv,
- pim_ifp->pim_ifstat_hello_sent, pim_ifp->pim_ifstat_join_recv,
- pim_ifp->pim_ifstat_join_send, pim_ifp->pim_ifstat_prune_recv,
- pim_ifp->pim_ifstat_prune_send, pim_ifp->pim_ifstat_reg_recv,
- pim_ifp->pim_ifstat_reg_send,
- pim_ifp->pim_ifstat_reg_stop_recv,
- pim_ifp->pim_ifstat_reg_stop_send,
- pim_ifp->pim_ifstat_assert_recv,
- pim_ifp->pim_ifstat_assert_send);
- }
- }
- if (uj)
- {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free (json);
- }
- else
- {
- if (!found_ifname)
- vty_out (vty, "%% No such interface\n");
- }
+ struct interface *ifp;
+ struct listnode *node;
+ struct listnode *upnode;
+ struct pim_interface *pim_ifp;
+ struct pim_upstream *up;
+ int fhr = 0;
+ int pim_nbrs = 0;
+ int pim_ifchannels = 0;
+ json_object *json = NULL;
+ json_object *json_row = NULL;
+ json_object *json_tmp;
+
+ json = json_object_new_object();
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ if (pim_ifp->pim_sock_fd < 0)
+ continue;
+
+ pim_nbrs = pim_ifp->pim_neighbor_list->count;
+ pim_ifchannels = pim_ifp->pim_ifchannel_list->count;
+ fhr = 0;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode, up))
+ if (ifp == up->rpf.source_nexthop.interface)
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
+ fhr++;
+
+ json_row = json_object_new_object();
+ json_object_pim_ifp_add(json_row, ifp);
+ json_object_int_add(json_row, "pimNeighbors", pim_nbrs);
+ json_object_int_add(json_row, "pimIfChannels", pim_ifchannels);
+ json_object_int_add(json_row, "firstHopRouter", fhr);
+ json_object_string_add(json_row, "pimDesignatedRouter",
+ inet_ntoa(pim_ifp->pim_dr_addr));
+
+ if (pim_ifp->pim_dr_addr.s_addr
+ == pim_ifp->primary_address.s_addr)
+ json_object_boolean_true_add(
+ json_row, "pimDesignatedRouterLocal");
+
+ json_object_object_add(json, ifp->name, json_row);
+ }
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ } else {
+ vty_out(vty,
+ "Interface State Address PIM Nbrs PIM DR FHR IfChannels\n");
+
+ json_object_object_foreach(json, key, val)
+ {
+ vty_out(vty, "%-9s ", key);
+
+ json_object_object_get_ex(val, "state", &json_tmp);
+ vty_out(vty, "%5s ", json_object_get_string(json_tmp));
+
+ json_object_object_get_ex(val, "address", &json_tmp);
+ vty_out(vty, "%15s ",
+ json_object_get_string(json_tmp));
+
+ json_object_object_get_ex(val, "pimNeighbors",
+ &json_tmp);
+ vty_out(vty, "%8d ", json_object_get_int(json_tmp));
+
+ if (json_object_object_get_ex(
+ val, "pimDesignatedRouterLocal",
+ &json_tmp)) {
+ vty_out(vty, "%15s ", "local");
+ } else {
+ json_object_object_get_ex(
+ val, "pimDesignatedRouter", &json_tmp);
+ vty_out(vty, "%15s ",
+ json_object_get_string(json_tmp));
+ }
+
+ json_object_object_get_ex(val, "firstHopRouter",
+ &json_tmp);
+ vty_out(vty, "%3d ", json_object_get_int(json_tmp));
+
+ json_object_object_get_ex(val, "pimIfChannels",
+ &json_tmp);
+ vty_out(vty, "%9d\n", json_object_get_int(json_tmp));
+ }
+ }
+
+ json_object_free(json);
+}
+
+static void pim_show_interface_traffic(struct vty *vty, u_char uj)
+{
+ struct interface *ifp = NULL;
+ struct pim_interface *pim_ifp = NULL;
+ struct listnode *node = NULL;
+ json_object *json = NULL;
+ json_object *json_row = NULL;
+
+ if (uj)
+ json = json_object_new_object();
+ else {
+ vty_out(vty, "\n");
+ vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
+ "Interface", " HELLO", " JOIN", " PRUNE",
+ " REGISTER", " REGISTER-STOP", " ASSERT");
+ vty_out(vty, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
+ " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
+ " Rx/Tx", " Rx/Tx");
+ vty_out(vty,
+ "---------------------------------------------------------------------------------------------------------------\n");
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ if (pim_ifp->pim_sock_fd < 0)
+ continue;
+ if (uj) {
+ json_row = json_object_new_object();
+ json_object_pim_ifp_add(json_row, ifp);
+ json_object_int_add(json_row, "helloRx",
+ pim_ifp->pim_ifstat_hello_recv);
+ json_object_int_add(json_row, "helloTx",
+ pim_ifp->pim_ifstat_hello_sent);
+ json_object_int_add(json_row, "joinRx",
+ pim_ifp->pim_ifstat_join_recv);
+ json_object_int_add(json_row, "joinTx",
+ pim_ifp->pim_ifstat_join_send);
+ json_object_int_add(json_row, "registerRx",
+ pim_ifp->pim_ifstat_reg_recv);
+ json_object_int_add(json_row, "registerTx",
+ pim_ifp->pim_ifstat_reg_recv);
+ json_object_int_add(json_row, "registerStopRx",
+ pim_ifp->pim_ifstat_reg_stop_recv);
+ json_object_int_add(json_row, "registerStopTx",
+ pim_ifp->pim_ifstat_reg_stop_send);
+ json_object_int_add(json_row, "assertRx",
+ pim_ifp->pim_ifstat_assert_recv);
+ json_object_int_add(json_row, "assertTx",
+ pim_ifp->pim_ifstat_assert_send);
+
+ json_object_object_add(json, ifp->name, json_row);
+ } else {
+ vty_out(vty,
+ "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
+ ifp->name, pim_ifp->pim_ifstat_hello_recv,
+ pim_ifp->pim_ifstat_hello_sent,
+ pim_ifp->pim_ifstat_join_recv,
+ pim_ifp->pim_ifstat_join_send,
+ pim_ifp->pim_ifstat_prune_recv,
+ pim_ifp->pim_ifstat_prune_send,
+ pim_ifp->pim_ifstat_reg_recv,
+ pim_ifp->pim_ifstat_reg_send,
+ pim_ifp->pim_ifstat_reg_stop_recv,
+ pim_ifp->pim_ifstat_reg_stop_send,
+ pim_ifp->pim_ifstat_assert_recv,
+ pim_ifp->pim_ifstat_assert_send);
+ }
+ }
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
+}
+
+static void pim_show_interface_traffic_single(struct vty *vty,
+ const char *ifname, u_char uj)
+{
+ struct interface *ifp = NULL;
+ struct pim_interface *pim_ifp = NULL;
+ struct listnode *node = NULL;
+ json_object *json = NULL;
+ json_object *json_row = NULL;
+ uint8_t found_ifname = 0;
+
+ if (uj)
+ json = json_object_new_object();
+ else {
+ vty_out(vty, "\n");
+ vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
+ "Interface", " HELLO", " JOIN", " PRUNE",
+ " REGISTER", " REGISTER-STOP", " ASSERT");
+ vty_out(vty, "%-10s%-18s%-17s%-17s%-17s%-17s%-17s\n", "",
+ " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
+ " Rx/Tx", " Rx/Tx");
+ vty_out(vty,
+ "---------------------------------------------------------------------------------------------------------------\n");
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ if (strcmp(ifname, ifp->name))
+ continue;
+
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ if (pim_ifp->pim_sock_fd < 0)
+ continue;
+
+ found_ifname = 1;
+ if (uj) {
+ json_row = json_object_new_object();
+ json_object_pim_ifp_add(json_row, ifp);
+ json_object_int_add(json_row, "helloRx",
+ pim_ifp->pim_ifstat_hello_recv);
+ json_object_int_add(json_row, "helloTx",
+ pim_ifp->pim_ifstat_hello_sent);
+ json_object_int_add(json_row, "joinRx",
+ pim_ifp->pim_ifstat_join_recv);
+ json_object_int_add(json_row, "joinTx",
+ pim_ifp->pim_ifstat_join_send);
+ json_object_int_add(json_row, "registerRx",
+ pim_ifp->pim_ifstat_reg_recv);
+ json_object_int_add(json_row, "registerTx",
+ pim_ifp->pim_ifstat_reg_recv);
+ json_object_int_add(json_row, "registerStopRx",
+ pim_ifp->pim_ifstat_reg_stop_recv);
+ json_object_int_add(json_row, "registerStopTx",
+ pim_ifp->pim_ifstat_reg_stop_send);
+ json_object_int_add(json_row, "assertRx",
+ pim_ifp->pim_ifstat_assert_recv);
+ json_object_int_add(json_row, "assertTx",
+ pim_ifp->pim_ifstat_assert_send);
+
+ json_object_object_add(json, ifp->name, json_row);
+ } else {
+ vty_out(vty,
+ "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u \n",
+ ifp->name, pim_ifp->pim_ifstat_hello_recv,
+ pim_ifp->pim_ifstat_hello_sent,
+ pim_ifp->pim_ifstat_join_recv,
+ pim_ifp->pim_ifstat_join_send,
+ pim_ifp->pim_ifstat_prune_recv,
+ pim_ifp->pim_ifstat_prune_send,
+ pim_ifp->pim_ifstat_reg_recv,
+ pim_ifp->pim_ifstat_reg_send,
+ pim_ifp->pim_ifstat_reg_stop_recv,
+ pim_ifp->pim_ifstat_reg_stop_send,
+ pim_ifp->pim_ifstat_assert_recv,
+ pim_ifp->pim_ifstat_assert_send);
+ }
+ }
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ } else {
+ if (!found_ifname)
+ vty_out(vty, "%% No such interface\n");
+ }
}
static void pim_show_join(struct vty *vty, u_char uj)
{
- struct pim_interface *pim_ifp;
- struct in_addr ifaddr;
- struct listnode *ch_node;
- struct pim_ifchannel *ch;
- time_t now;
- json_object *json = NULL;
- json_object *json_iface = NULL;
- json_object *json_row = NULL;
- json_object *json_grp = NULL;
-
- now = pim_time_monotonic_sec();
-
- if (uj)
- json = json_object_new_object();
- else
- vty_out (vty,
- "Interface Address Source Group State Uptime Expire Prune\n");
-
- for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
-
- pim_ifp = ch->interface->info;
-
- if (!pim_ifp)
- continue;
-
- ifaddr = pim_ifp->primary_address;
-
- char ch_src_str[INET_ADDRSTRLEN];
- char ch_grp_str[INET_ADDRSTRLEN];
- char uptime[10];
- char expire[10];
- char prune[10];
-
- pim_inet4_dump("<ch_src?>", ch->sg.src,
- ch_src_str, sizeof(ch_src_str));
- pim_inet4_dump("<ch_grp?>", ch->sg.grp,
- ch_grp_str, sizeof(ch_grp_str));
-
- pim_time_uptime_begin(uptime, sizeof(uptime), now, ch->ifjoin_creation);
- pim_time_timer_to_mmss(expire, sizeof(expire),
- ch->t_ifjoin_expiry_timer);
- pim_time_timer_to_mmss(prune, sizeof(prune),
- ch->t_ifjoin_prune_pending_timer);
-
- if (uj) {
- json_object_object_get_ex(json, ch->interface->name, &json_iface);
-
- if (!json_iface) {
- json_iface = json_object_new_object();
- json_object_pim_ifp_add(json_iface, ch->interface);
- json_object_object_add(json, ch->interface->name, json_iface);
- }
-
- json_row = json_object_new_object();
- json_object_string_add(json_row, "source", ch_src_str);
- json_object_string_add(json_row, "group", ch_grp_str);
- json_object_string_add(json_row, "upTime", uptime);
- json_object_string_add(json_row, "expire", expire);
- json_object_string_add(json_row, "prune", prune);
- json_object_string_add(json_row, "channelJoinName",
- pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags));
- if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags))
- json_object_int_add(json_row, "SGRpt", 1);
-
- json_object_object_get_ex(json_iface, ch_grp_str, &json_grp);
- if (!json_grp)
- {
- json_grp = json_object_new_object();
- json_object_object_add(json_grp, ch_src_str, json_row);
- json_object_object_add(json_iface, ch_grp_str, json_grp);
- }
- else
- json_object_object_add(json_grp, ch_src_str, json_row);
- } else {
- vty_out (vty, "%-9s %-15s %-15s %-15s %-6s %8s %-6s %5s\n",
- ch->interface->name,
- inet_ntoa(ifaddr),
- ch_src_str,
- ch_grp_str,
- pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags),
- uptime,
- expire,
- prune);
- }
- } /* scan interface channels */
-
- if (uj) {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
-}
-
-static void pim_show_neighbors_single(struct vty *vty, const char *neighbor, u_char uj)
-{
- struct listnode *node;
- struct listnode *neighnode;
- struct interface *ifp;
- struct pim_interface *pim_ifp;
- struct pim_neighbor *neigh;
- time_t now;
- int found_neighbor = 0;
- int option_address_list;
- int option_dr_priority;
- int option_generation_id;
- int option_holdtime;
- int option_lan_prune_delay;
- int option_t_bit;
- char uptime[10];
- char expire[10];
- char neigh_src_str[INET_ADDRSTRLEN];
-
- json_object *json = NULL;
- json_object *json_ifp = NULL;
- json_object *json_row = NULL;
-
- now = pim_time_monotonic_sec();
-
- if (uj)
- json = json_object_new_object();
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
- pim_ifp = ifp->info;
-
- if (!pim_ifp)
- continue;
-
- if (pim_ifp->pim_sock_fd < 0)
- continue;
-
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
- pim_inet4_dump("<src?>", neigh->source_addr,
- neigh_src_str, sizeof(neigh_src_str));
-
- /*
- * The user can specify either the interface name or the PIM neighbor IP.
- * If this pim_ifp matches neither then skip.
- */
- if (strcmp(neighbor, "detail") &&
- strcmp(neighbor, ifp->name) &&
- strcmp(neighbor, neigh_src_str))
- continue;
-
- found_neighbor = 1;
- pim_time_uptime(uptime, sizeof(uptime), now - neigh->creation);
- pim_time_timer_to_hhmmss(expire, sizeof(expire), neigh->t_expire_timer);
-
- option_address_list = 0;
- option_dr_priority = 0;
- option_generation_id = 0;
- option_holdtime = 0;
- option_lan_prune_delay = 0;
- option_t_bit = 0;
-
- if (PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_ADDRESS_LIST))
- option_address_list = 1;
-
- if (PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_DR_PRIORITY))
- option_dr_priority = 1;
-
- if (PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_GENERATION_ID))
- option_generation_id = 1;
-
- if (PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_HOLDTIME))
- option_holdtime = 1;
-
- if (PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY))
- option_lan_prune_delay = 1;
-
- if (PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION))
- option_t_bit = 1;
-
- if (uj) {
-
- /* Does this ifp live in json? If not create it. */
- json_object_object_get_ex(json, ifp->name, &json_ifp);
-
- if (!json_ifp) {
- json_ifp = json_object_new_object();
- json_object_pim_ifp_add(json_ifp, ifp);
- json_object_object_add(json, ifp->name, json_ifp);
- }
-
- json_row = json_object_new_object();
- json_object_string_add(json_row, "interface", ifp->name);
- json_object_string_add(json_row, "address", neigh_src_str);
- json_object_string_add(json_row, "upTime", uptime);
- json_object_string_add(json_row, "holdtime", expire);
- json_object_int_add(json_row, "drPriority", neigh->dr_priority);
- json_object_int_add(json_row, "generationId", neigh->generation_id);
-
- if (option_address_list)
- json_object_boolean_true_add(json_row, "helloOptionAddressList");
-
- if (option_dr_priority)
- json_object_boolean_true_add(json_row, "helloOptionDrPriority");
-
- if (option_generation_id)
- json_object_boolean_true_add(json_row, "helloOptionGenerationId");
-
- if (option_holdtime)
- json_object_boolean_true_add(json_row, "helloOptionHoldtime");
-
- if (option_lan_prune_delay)
- json_object_boolean_true_add(json_row, "helloOptionLanPruneDelay");
-
- if (option_t_bit)
- json_object_boolean_true_add(json_row, "helloOptionTBit");
-
- json_object_object_add(json_ifp, neigh_src_str, json_row);
-
- } else {
- vty_out (vty, "Interface : %s\n", ifp->name);
- vty_out (vty, "Neighbor : %s\n", neigh_src_str);
- vty_out (vty, " Uptime : %s\n", uptime);
- vty_out (vty, " Holdtime : %s\n", expire);
- vty_out (vty, " DR Priority : %d\n",
- neigh->dr_priority);
- vty_out (vty, " Generation ID : %08x\n",
- neigh->generation_id);
- vty_out (vty, " Override Interval (msec) : %d\n",
- neigh->override_interval_msec);
- vty_out (vty, " Propagation Delay (msec) : %d\n",
- neigh->propagation_delay_msec);
- vty_out (vty, " Hello Option - Address List : %s\n",
- option_address_list ? "yes" : "no");
- vty_out (vty, " Hello Option - DR Priority : %s\n",
- option_dr_priority ? "yes" : "no");
- vty_out (vty, " Hello Option - Generation ID : %s\n",
- option_generation_id ? "yes" : "no");
- vty_out (vty, " Hello Option - Holdtime : %s\n",
- option_holdtime ? "yes" : "no");
- vty_out (vty, " Hello Option - LAN Prune Delay : %s\n",
- option_lan_prune_delay ? "yes" : "no");
- vty_out (vty, " Hello Option - T-bit : %s\n",
- option_t_bit ? "yes" : "no");
- pim_bfd_show_info (vty, neigh->bfd_info, json_ifp, uj, 0);
- vty_out (vty, "\n");
- }
- }
- }
-
- if (uj) {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- } else {
- {
- if (!found_neighbor)
- vty_out (vty, "%% No such interface or neighbor\n");
- }
- }
-}
-
-static void
-pim_show_state(struct vty *vty, const char *src_or_group, const char *group, u_char uj)
-{
- struct channel_oil *c_oil;
- struct listnode *node;
- json_object *json = NULL;
- json_object *json_group = NULL;
- json_object *json_ifp_in = NULL;
- json_object *json_ifp_out = NULL;
- json_object *json_source = NULL;
- time_t now;
- int first_oif;
- now = pim_time_monotonic_sec();
-
- if (uj) {
- json = json_object_new_object();
- } else {
- vty_out(vty, "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
- vty_out (vty, "\nInstalled Source Group IIF OIL\n");
- }
-
- for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
- char grp_str[INET_ADDRSTRLEN];
- char src_str[INET_ADDRSTRLEN];
- char in_ifname[INTERFACE_NAMSIZ+1];
- char out_ifname[INTERFACE_NAMSIZ+1];
- int oif_vif_index;
- struct interface *ifp_in;
- first_oif = 1;
-
- pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str, sizeof(grp_str));
- pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str, sizeof(src_str));
- ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
-
- if (ifp_in)
- strcpy(in_ifname, ifp_in->name);
- else
- strcpy(in_ifname, "<iif?>");
-
- if (src_or_group)
- {
- if (strcmp(src_or_group, src_str) && strcmp(src_or_group, grp_str))
- continue;
-
- if (group && strcmp(group, grp_str))
- continue;
- }
-
- if (uj) {
-
- /* Find the group, create it if it doesn't exist */
- json_object_object_get_ex(json, grp_str, &json_group);
-
- if (!json_group) {
- json_group = json_object_new_object();
- json_object_object_add(json, grp_str, json_group);
- }
-
- /* Find the source nested under the group, create it if it doesn't exist */
- json_object_object_get_ex(json_group, src_str, &json_source);
-
- if (!json_source) {
- json_source = json_object_new_object();
- json_object_object_add(json_group, src_str, json_source);
- }
-
- /* Find the inbound interface nested under the source, create it if it doesn't exist */
- json_object_object_get_ex(json_source, in_ifname, &json_ifp_in);
-
- if (!json_ifp_in) {
- json_ifp_in = json_object_new_object();
- json_object_object_add(json_source, in_ifname, json_ifp_in);
- json_object_int_add (json_source, "Installed", c_oil->installed);
- json_object_int_add (json_source, "RefCount", c_oil->oil_ref_count);
- json_object_int_add (json_source, "OilListSize", c_oil->oil_size);
- json_object_int_add (json_source, "OilRescan", c_oil->oil_inherited_rescan);
- json_object_int_add (json_source, "LastUsed", c_oil->cc.lastused);
- json_object_int_add (json_source, "PacketCount", c_oil->cc.pktcnt);
- json_object_int_add (json_source, "ByteCount", c_oil->cc.bytecnt);
- json_object_int_add (json_source, "WrongInterface", c_oil->cc.wrong_if);
- }
- } else {
- vty_out(vty, "%-9d %-15s %-15s %-7s ",
- c_oil->installed,
- src_str,
- grp_str,
- ifp_in->name);
- }
-
- for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
- struct interface *ifp_out;
- char oif_uptime[10];
- int ttl;
-
- ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
- if (ttl < 1)
- continue;
-
- ifp_out = pim_if_find_by_vif_index(oif_vif_index);
- pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - c_oil->oif_creation[oif_vif_index]);
-
- if (ifp_out)
- strcpy(out_ifname, ifp_out->name);
- else
- strcpy(out_ifname, "<oif?>");
-
- if (uj) {
- json_ifp_out = json_object_new_object();
- json_object_string_add(json_ifp_out, "source", src_str);
- json_object_string_add(json_ifp_out, "group", grp_str);
- json_object_string_add(json_ifp_out, "inboundInterface", in_ifname);
- json_object_string_add(json_ifp_out, "outboundInterface", out_ifname);
- json_object_int_add(json_ifp_out, "installed", c_oil->installed);
-
- json_object_object_add(json_ifp_in, out_ifname, json_ifp_out);
- } else {
- if (first_oif)
- {
- first_oif = 0;
- vty_out(vty, "%s(%c%c%c%c)", out_ifname,
- (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) ? 'I' : ' ',
- (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) ? 'J' : ' ',
- (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE) ? 'S' : ' ',
- (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR) ? '*' : ' ');
- }
- else
- vty_out(vty, ", %s(%c%c%c%c)", out_ifname,
- (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) ? 'I' : ' ',
- (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) ? 'J' : ' ',
- (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE) ? 'S' : ' ',
- (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR) ? '*' : ' ' );
- }
- }
-
- if (!uj)
- vty_out (vty, "\n");
- }
-
-
- if (uj) {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- } else {
- vty_out (vty, "\n");
- }
+ struct pim_interface *pim_ifp;
+ struct in_addr ifaddr;
+ struct listnode *ch_node;
+ struct pim_ifchannel *ch;
+ time_t now;
+ json_object *json = NULL;
+ json_object *json_iface = NULL;
+ json_object *json_row = NULL;
+ json_object *json_grp = NULL;
+
+ now = pim_time_monotonic_sec();
+
+ if (uj)
+ json = json_object_new_object();
+ else
+ vty_out(vty,
+ "Interface Address Source Group State Uptime Expire Prune\n");
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, ch_node, ch)) {
+
+ pim_ifp = ch->interface->info;
+
+ if (!pim_ifp)
+ continue;
+
+ ifaddr = pim_ifp->primary_address;
+
+ char ch_src_str[INET_ADDRSTRLEN];
+ char ch_grp_str[INET_ADDRSTRLEN];
+ char uptime[10];
+ char expire[10];
+ char prune[10];
+
+ pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
+ sizeof(ch_src_str));
+ pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str,
+ sizeof(ch_grp_str));
+
+ pim_time_uptime_begin(uptime, sizeof(uptime), now,
+ ch->ifjoin_creation);
+ pim_time_timer_to_mmss(expire, sizeof(expire),
+ ch->t_ifjoin_expiry_timer);
+ pim_time_timer_to_mmss(prune, sizeof(prune),
+ ch->t_ifjoin_prune_pending_timer);
+
+ if (uj) {
+ json_object_object_get_ex(json, ch->interface->name,
+ &json_iface);
+
+ if (!json_iface) {
+ json_iface = json_object_new_object();
+ json_object_pim_ifp_add(json_iface,
+ ch->interface);
+ json_object_object_add(
+ json, ch->interface->name, json_iface);
+ }
+
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "source", ch_src_str);
+ json_object_string_add(json_row, "group", ch_grp_str);
+ json_object_string_add(json_row, "upTime", uptime);
+ json_object_string_add(json_row, "expire", expire);
+ json_object_string_add(json_row, "prune", prune);
+ json_object_string_add(
+ json_row, "channelJoinName",
+ pim_ifchannel_ifjoin_name(ch->ifjoin_state,
+ ch->flags));
+ if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags))
+ json_object_int_add(json_row, "SGRpt", 1);
+
+ json_object_object_get_ex(json_iface, ch_grp_str,
+ &json_grp);
+ if (!json_grp) {
+ json_grp = json_object_new_object();
+ json_object_object_add(json_grp, ch_src_str,
+ json_row);
+ json_object_object_add(json_iface, ch_grp_str,
+ json_grp);
+ } else
+ json_object_object_add(json_grp, ch_src_str,
+ json_row);
+ } else {
+ vty_out(vty,
+ "%-9s %-15s %-15s %-15s %-6s %8s %-6s %5s\n",
+ ch->interface->name, inet_ntoa(ifaddr),
+ ch_src_str, ch_grp_str,
+ pim_ifchannel_ifjoin_name(ch->ifjoin_state,
+ ch->flags),
+ uptime, expire, prune);
+ }
+ } /* scan interface channels */
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
+}
+
+static void pim_show_neighbors_single(struct vty *vty, const char *neighbor,
+ u_char uj)
+{
+ struct listnode *node;
+ struct listnode *neighnode;
+ struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ struct pim_neighbor *neigh;
+ time_t now;
+ int found_neighbor = 0;
+ int option_address_list;
+ int option_dr_priority;
+ int option_generation_id;
+ int option_holdtime;
+ int option_lan_prune_delay;
+ int option_t_bit;
+ char uptime[10];
+ char expire[10];
+ char neigh_src_str[INET_ADDRSTRLEN];
+
+ json_object *json = NULL;
+ json_object *json_ifp = NULL;
+ json_object *json_row = NULL;
+
+ now = pim_time_monotonic_sec();
+
+ if (uj)
+ json = json_object_new_object();
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ if (pim_ifp->pim_sock_fd < 0)
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
+ neigh)) {
+ pim_inet4_dump("<src?>", neigh->source_addr,
+ neigh_src_str, sizeof(neigh_src_str));
+
+ /*
+ * The user can specify either the interface name or the
+ * PIM neighbor IP.
+ * If this pim_ifp matches neither then skip.
+ */
+ if (strcmp(neighbor, "detail")
+ && strcmp(neighbor, ifp->name)
+ && strcmp(neighbor, neigh_src_str))
+ continue;
+
+ found_neighbor = 1;
+ pim_time_uptime(uptime, sizeof(uptime),
+ now - neigh->creation);
+ pim_time_timer_to_hhmmss(expire, sizeof(expire),
+ neigh->t_expire_timer);
+
+ option_address_list = 0;
+ option_dr_priority = 0;
+ option_generation_id = 0;
+ option_holdtime = 0;
+ option_lan_prune_delay = 0;
+ option_t_bit = 0;
+
+ if (PIM_OPTION_IS_SET(neigh->hello_options,
+ PIM_OPTION_MASK_ADDRESS_LIST))
+ option_address_list = 1;
+
+ if (PIM_OPTION_IS_SET(neigh->hello_options,
+ PIM_OPTION_MASK_DR_PRIORITY))
+ option_dr_priority = 1;
+
+ if (PIM_OPTION_IS_SET(neigh->hello_options,
+ PIM_OPTION_MASK_GENERATION_ID))
+ option_generation_id = 1;
+
+ if (PIM_OPTION_IS_SET(neigh->hello_options,
+ PIM_OPTION_MASK_HOLDTIME))
+ option_holdtime = 1;
+
+ if (PIM_OPTION_IS_SET(neigh->hello_options,
+ PIM_OPTION_MASK_LAN_PRUNE_DELAY))
+ option_lan_prune_delay = 1;
+
+ if (PIM_OPTION_IS_SET(
+ neigh->hello_options,
+ PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION))
+ option_t_bit = 1;
+
+ if (uj) {
+
+ /* Does this ifp live in json? If not create
+ * it. */
+ json_object_object_get_ex(json, ifp->name,
+ &json_ifp);
+
+ if (!json_ifp) {
+ json_ifp = json_object_new_object();
+ json_object_pim_ifp_add(json_ifp, ifp);
+ json_object_object_add(json, ifp->name,
+ json_ifp);
+ }
+
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "interface",
+ ifp->name);
+ json_object_string_add(json_row, "address",
+ neigh_src_str);
+ json_object_string_add(json_row, "upTime",
+ uptime);
+ json_object_string_add(json_row, "holdtime",
+ expire);
+ json_object_int_add(json_row, "drPriority",
+ neigh->dr_priority);
+ json_object_int_add(json_row, "generationId",
+ neigh->generation_id);
+
+ if (option_address_list)
+ json_object_boolean_true_add(
+ json_row,
+ "helloOptionAddressList");
+
+ if (option_dr_priority)
+ json_object_boolean_true_add(
+ json_row,
+ "helloOptionDrPriority");
+
+ if (option_generation_id)
+ json_object_boolean_true_add(
+ json_row,
+ "helloOptionGenerationId");
+
+ if (option_holdtime)
+ json_object_boolean_true_add(
+ json_row,
+ "helloOptionHoldtime");
+
+ if (option_lan_prune_delay)
+ json_object_boolean_true_add(
+ json_row,
+ "helloOptionLanPruneDelay");
+
+ if (option_t_bit)
+ json_object_boolean_true_add(
+ json_row, "helloOptionTBit");
+
+ json_object_object_add(json_ifp, neigh_src_str,
+ json_row);
+
+ } else {
+ vty_out(vty, "Interface : %s\n", ifp->name);
+ vty_out(vty, "Neighbor : %s\n", neigh_src_str);
+ vty_out(vty,
+ " Uptime : %s\n",
+ uptime);
+ vty_out(vty,
+ " Holdtime : %s\n",
+ expire);
+ vty_out(vty,
+ " DR Priority : %d\n",
+ neigh->dr_priority);
+ vty_out(vty,
+ " Generation ID : %08x\n",
+ neigh->generation_id);
+ vty_out(vty,
+ " Override Interval (msec) : %d\n",
+ neigh->override_interval_msec);
+ vty_out(vty,
+ " Propagation Delay (msec) : %d\n",
+ neigh->propagation_delay_msec);
+ vty_out(vty,
+ " Hello Option - Address List : %s\n",
+ option_address_list ? "yes" : "no");
+ vty_out(vty,
+ " Hello Option - DR Priority : %s\n",
+ option_dr_priority ? "yes" : "no");
+ vty_out(vty,
+ " Hello Option - Generation ID : %s\n",
+ option_generation_id ? "yes" : "no");
+ vty_out(vty,
+ " Hello Option - Holdtime : %s\n",
+ option_holdtime ? "yes" : "no");
+ vty_out(vty,
+ " Hello Option - LAN Prune Delay : %s\n",
+ option_lan_prune_delay ? "yes" : "no");
+ vty_out(vty,
+ " Hello Option - T-bit : %s\n",
+ option_t_bit ? "yes" : "no");
+ pim_bfd_show_info(vty, neigh->bfd_info,
+ json_ifp, uj, 0);
+ vty_out(vty, "\n");
+ }
+ }
+ }
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ } else {
+ {
+ if (!found_neighbor)
+ vty_out(vty,
+ "%% No such interface or neighbor\n");
+ }
+ }
+}
+
+static void pim_show_state(struct vty *vty, const char *src_or_group,
+ const char *group, u_char uj)
+{
+ struct channel_oil *c_oil;
+ struct listnode *node;
+ json_object *json = NULL;
+ json_object *json_group = NULL;
+ json_object *json_ifp_in = NULL;
+ json_object *json_ifp_out = NULL;
+ json_object *json_source = NULL;
+ time_t now;
+ int first_oif;
+ now = pim_time_monotonic_sec();
+
+ if (uj) {
+ json = json_object_new_object();
+ } else {
+ vty_out(vty,
+ "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
+ vty_out(vty,
+ "\nInstalled Source Group IIF OIL\n");
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
+ char grp_str[INET_ADDRSTRLEN];
+ char src_str[INET_ADDRSTRLEN];
+ char in_ifname[INTERFACE_NAMSIZ + 1];
+ char out_ifname[INTERFACE_NAMSIZ + 1];
+ int oif_vif_index;
+ struct interface *ifp_in;
+ first_oif = 1;
+
+ pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str,
+ sizeof(grp_str));
+ pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str,
+ sizeof(src_str));
+ ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
+
+ if (ifp_in)
+ strcpy(in_ifname, ifp_in->name);
+ else
+ strcpy(in_ifname, "<iif?>");
+
+ if (src_or_group) {
+ if (strcmp(src_or_group, src_str)
+ && strcmp(src_or_group, grp_str))
+ continue;
+
+ if (group && strcmp(group, grp_str))
+ continue;
+ }
+
+ if (uj) {
+
+ /* Find the group, create it if it doesn't exist */
+ json_object_object_get_ex(json, grp_str, &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str,
+ json_group);
+ }
+
+ /* Find the source nested under the group, create it if
+ * it doesn't exist */
+ json_object_object_get_ex(json_group, src_str,
+ &json_source);
+
+ if (!json_source) {
+ json_source = json_object_new_object();
+ json_object_object_add(json_group, src_str,
+ json_source);
+ }
+
+ /* Find the inbound interface nested under the source,
+ * create it if it doesn't exist */
+ json_object_object_get_ex(json_source, in_ifname,
+ &json_ifp_in);
+
+ if (!json_ifp_in) {
+ json_ifp_in = json_object_new_object();
+ json_object_object_add(json_source, in_ifname,
+ json_ifp_in);
+ json_object_int_add(json_source, "Installed",
+ c_oil->installed);
+ json_object_int_add(json_source, "RefCount",
+ c_oil->oil_ref_count);
+ json_object_int_add(json_source, "OilListSize",
+ c_oil->oil_size);
+ json_object_int_add(
+ json_source, "OilRescan",
+ c_oil->oil_inherited_rescan);
+ json_object_int_add(json_source, "LastUsed",
+ c_oil->cc.lastused);
+ json_object_int_add(json_source, "PacketCount",
+ c_oil->cc.pktcnt);
+ json_object_int_add(json_source, "ByteCount",
+ c_oil->cc.bytecnt);
+ json_object_int_add(json_source,
+ "WrongInterface",
+ c_oil->cc.wrong_if);
+ }
+ } else {
+ vty_out(vty, "%-9d %-15s %-15s %-7s ",
+ c_oil->installed, src_str, grp_str,
+ ifp_in->name);
+ }
+
+ for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
+ ++oif_vif_index) {
+ struct interface *ifp_out;
+ char oif_uptime[10];
+ int ttl;
+
+ ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
+ if (ttl < 1)
+ continue;
+
+ ifp_out = pim_if_find_by_vif_index(oif_vif_index);
+ pim_time_uptime(
+ oif_uptime, sizeof(oif_uptime),
+ now - c_oil->oif_creation[oif_vif_index]);
+
+ if (ifp_out)
+ strcpy(out_ifname, ifp_out->name);
+ else
+ strcpy(out_ifname, "<oif?>");
+
+ if (uj) {
+ json_ifp_out = json_object_new_object();
+ json_object_string_add(json_ifp_out, "source",
+ src_str);
+ json_object_string_add(json_ifp_out, "group",
+ grp_str);
+ json_object_string_add(json_ifp_out,
+ "inboundInterface",
+ in_ifname);
+ json_object_string_add(json_ifp_out,
+ "outboundInterface",
+ out_ifname);
+ json_object_int_add(json_ifp_out, "installed",
+ c_oil->installed);
+
+ json_object_object_add(json_ifp_in, out_ifname,
+ json_ifp_out);
+ } else {
+ if (first_oif) {
+ first_oif = 0;
+ vty_out(vty, "%s(%c%c%c%c)", out_ifname,
+ (c_oil->oif_flags[oif_vif_index]
+ & PIM_OIF_FLAG_PROTO_IGMP)
+ ? 'I'
+ : ' ',
+ (c_oil->oif_flags[oif_vif_index]
+ & PIM_OIF_FLAG_PROTO_PIM)
+ ? 'J'
+ : ' ',
+ (c_oil->oif_flags[oif_vif_index]
+ & PIM_OIF_FLAG_PROTO_SOURCE)
+ ? 'S'
+ : ' ',
+ (c_oil->oif_flags[oif_vif_index]
+ & PIM_OIF_FLAG_PROTO_STAR)
+ ? '*'
+ : ' ');
+ } else
+ vty_out(vty, ", %s(%c%c%c%c)",
+ out_ifname,
+ (c_oil->oif_flags[oif_vif_index]
+ & PIM_OIF_FLAG_PROTO_IGMP)
+ ? 'I'
+ : ' ',
+ (c_oil->oif_flags[oif_vif_index]
+ & PIM_OIF_FLAG_PROTO_PIM)
+ ? 'J'
+ : ' ',
+ (c_oil->oif_flags[oif_vif_index]
+ & PIM_OIF_FLAG_PROTO_SOURCE)
+ ? 'S'
+ : ' ',
+ (c_oil->oif_flags[oif_vif_index]
+ & PIM_OIF_FLAG_PROTO_STAR)
+ ? '*'
+ : ' ');
+ }
+ }
+
+ if (!uj)
+ vty_out(vty, "\n");
+ }
+
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ } else {
+ vty_out(vty, "\n");
+ }
}
static void pim_show_neighbors(struct vty *vty, u_char uj)
{
- struct listnode *node;
- struct listnode *neighnode;
- struct interface *ifp;
- struct pim_interface *pim_ifp;
- struct pim_neighbor *neigh;
- time_t now;
- char uptime[10];
- char expire[10];
- char neigh_src_str[INET_ADDRSTRLEN];
- json_object *json = NULL;
- json_object *json_ifp_rows = NULL;
- json_object *json_row = NULL;
-
- now = pim_time_monotonic_sec();
-
- if (uj) {
- json = json_object_new_object();
- } else {
- vty_out (vty, "Interface Neighbor Uptime Holdtime DR Pri\n");
- }
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
- pim_ifp = ifp->info;
-
- if (!pim_ifp)
- continue;
-
- if (pim_ifp->pim_sock_fd < 0)
- continue;
-
- if (uj)
- json_ifp_rows = json_object_new_object();
-
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
- pim_inet4_dump("<src?>", neigh->source_addr,
- neigh_src_str, sizeof(neigh_src_str));
- pim_time_uptime(uptime, sizeof(uptime), now - neigh->creation);
- pim_time_timer_to_hhmmss(expire, sizeof(expire), neigh->t_expire_timer);
-
- if (uj) {
- json_row = json_object_new_object();
- json_object_string_add(json_row, "interface", ifp->name);
- json_object_string_add(json_row, "neighbor", neigh_src_str);
- json_object_string_add(json_row, "upTime", uptime);
- json_object_string_add(json_row, "holdTime", expire);
- json_object_int_add(json_row, "holdTimeMax", neigh->holdtime);
- json_object_int_add(json_row, "drPriority", neigh->dr_priority);
- json_object_object_add(json_ifp_rows, neigh_src_str, json_row);
-
- } else {
- vty_out (vty, "%-9s %15s %8s %8s %6d\n",
- ifp->name,
- neigh_src_str,
- uptime,
- expire,
- neigh->dr_priority);
- }
- }
-
- if (uj) {
- json_object_object_add(json, ifp->name, json_ifp_rows);
- json_ifp_rows = NULL;
- }
- }
-
- if (uj) {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
+ struct listnode *node;
+ struct listnode *neighnode;
+ struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ struct pim_neighbor *neigh;
+ time_t now;
+ char uptime[10];
+ char expire[10];
+ char neigh_src_str[INET_ADDRSTRLEN];
+ json_object *json = NULL;
+ json_object *json_ifp_rows = NULL;
+ json_object *json_row = NULL;
+
+ now = pim_time_monotonic_sec();
+
+ if (uj) {
+ json = json_object_new_object();
+ } else {
+ vty_out(vty,
+ "Interface Neighbor Uptime Holdtime DR Pri\n");
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ if (pim_ifp->pim_sock_fd < 0)
+ continue;
+
+ if (uj)
+ json_ifp_rows = json_object_new_object();
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
+ neigh)) {
+ pim_inet4_dump("<src?>", neigh->source_addr,
+ neigh_src_str, sizeof(neigh_src_str));
+ pim_time_uptime(uptime, sizeof(uptime),
+ now - neigh->creation);
+ pim_time_timer_to_hhmmss(expire, sizeof(expire),
+ neigh->t_expire_timer);
+
+ if (uj) {
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "interface",
+ ifp->name);
+ json_object_string_add(json_row, "neighbor",
+ neigh_src_str);
+ json_object_string_add(json_row, "upTime",
+ uptime);
+ json_object_string_add(json_row, "holdTime",
+ expire);
+ json_object_int_add(json_row, "holdTimeMax",
+ neigh->holdtime);
+ json_object_int_add(json_row, "drPriority",
+ neigh->dr_priority);
+ json_object_object_add(json_ifp_rows,
+ neigh_src_str, json_row);
+
+ } else {
+ vty_out(vty, "%-9s %15s %8s %8s %6d\n",
+ ifp->name, neigh_src_str, uptime,
+ expire, neigh->dr_priority);
+ }
+ }
+
+ if (uj) {
+ json_object_object_add(json, ifp->name, json_ifp_rows);
+ json_ifp_rows = NULL;
+ }
+ }
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
}
static void pim_show_neighbors_secondary(struct vty *vty)
{
- struct listnode *node;
- struct interface *ifp;
+ struct listnode *node;
+ struct interface *ifp;
- vty_out (vty,
- "Interface Address Neighbor Secondary \n");
+ vty_out(vty,
+ "Interface Address Neighbor Secondary \n");
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
- struct pim_interface *pim_ifp;
- struct in_addr ifaddr;
- struct listnode *neighnode;
- struct pim_neighbor *neigh;
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ struct pim_interface *pim_ifp;
+ struct in_addr ifaddr;
+ struct listnode *neighnode;
+ struct pim_neighbor *neigh;
- pim_ifp = ifp->info;
-
- if (!pim_ifp)
- continue;
+ pim_ifp = ifp->info;
- if (pim_ifp->pim_sock_fd < 0)
- continue;
+ if (!pim_ifp)
+ continue;
- ifaddr = pim_ifp->primary_address;
+ if (pim_ifp->pim_sock_fd < 0)
+ continue;
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
- char neigh_src_str[INET_ADDRSTRLEN];
- struct listnode *prefix_node;
- struct prefix *p;
+ ifaddr = pim_ifp->primary_address;
- if (!neigh->prefix_list)
- continue;
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
+ neigh)) {
+ char neigh_src_str[INET_ADDRSTRLEN];
+ struct listnode *prefix_node;
+ struct prefix *p;
- pim_inet4_dump("<src?>", neigh->source_addr,
- neigh_src_str, sizeof(neigh_src_str));
+ if (!neigh->prefix_list)
+ continue;
- for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list, prefix_node, p)) {
- char neigh_sec_str[PREFIX2STR_BUFFER];
+ pim_inet4_dump("<src?>", neigh->source_addr,
+ neigh_src_str, sizeof(neigh_src_str));
- prefix2str(p, neigh_sec_str, sizeof(neigh_sec_str));
+ for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list,
+ prefix_node, p)) {
+ char neigh_sec_str[PREFIX2STR_BUFFER];
- vty_out (vty, "%-9s %-15s %-15s %-15s\n",
- ifp->name,
- inet_ntoa(ifaddr),
- neigh_src_str,
- neigh_sec_str);
- }
- }
- }
+ prefix2str(p, neigh_sec_str,
+ sizeof(neigh_sec_str));
+
+ vty_out(vty, "%-9s %-15s %-15s %-15s\n",
+ ifp->name, inet_ntoa(ifaddr),
+ neigh_src_str, neigh_sec_str);
+ }
+ }
+ }
}
-static void
-json_object_pim_upstream_add (json_object *json, struct pim_upstream *up)
+static void json_object_pim_upstream_add(json_object *json,
+ struct pim_upstream *up)
{
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
- json_object_boolean_true_add(json, "drJoinDesired");
-
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
- json_object_boolean_true_add(json, "drJoinDesiredUpdated");
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
+ json_object_boolean_true_add(json, "drJoinDesired");
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
- json_object_boolean_true_add(json, "firstHopRouter");
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
+ json_object_boolean_true_add(json, "drJoinDesiredUpdated");
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
- json_object_boolean_true_add(json, "sourceIgmp");
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
+ json_object_boolean_true_add(json, "firstHopRouter");
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_PIM)
- json_object_boolean_true_add(json, "sourcePim");
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
+ json_object_boolean_true_add(json, "sourceIgmp");
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_STREAM)
- json_object_boolean_true_add(json, "sourceStream");
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_PIM)
+ json_object_boolean_true_add(json, "sourcePim");
- /* XXX: need to print ths flag in the plain text display as well */
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_MSDP)
- json_object_boolean_true_add(json, "sourceMsdp");
-}
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_STREAM)
+ json_object_boolean_true_add(json, "sourceStream");
-static const char *
-pim_upstream_state2brief_str (enum pim_upstream_state join_state, char *state_str)
-{
- switch (join_state)
- {
- case PIM_UPSTREAM_NOTJOINED:
- strcpy (state_str, "NotJ");
- break;
- case PIM_UPSTREAM_JOINED:
- strcpy (state_str, "J");
- break;
- default:
- strcpy (state_str, "Unk");
- }
- return state_str;
+ /* XXX: need to print ths flag in the plain text display as well */
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_MSDP)
+ json_object_boolean_true_add(json, "sourceMsdp");
}
static const char *
-pim_reg_state2brief_str (enum pim_reg_state reg_state, char *state_str)
-{
- switch (reg_state)
- {
- case PIM_REG_NOINFO:
- strcpy (state_str, "RegNI");
- break;
- case PIM_REG_JOIN:
- strcpy (state_str, "RegJ");
- break;
- case PIM_REG_JOIN_PENDING:
- case PIM_REG_PRUNE:
- strcpy (state_str, "RegP");
- break;
- default:
- strcpy (state_str, "Unk");
- }
- return state_str;
+pim_upstream_state2brief_str(enum pim_upstream_state join_state,
+ char *state_str)
+{
+ switch (join_state) {
+ case PIM_UPSTREAM_NOTJOINED:
+ strcpy(state_str, "NotJ");
+ break;
+ case PIM_UPSTREAM_JOINED:
+ strcpy(state_str, "J");
+ break;
+ default:
+ strcpy(state_str, "Unk");
+ }
+ return state_str;
+}
+
+static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state,
+ char *state_str)
+{
+ switch (reg_state) {
+ case PIM_REG_NOINFO:
+ strcpy(state_str, "RegNI");
+ break;
+ case PIM_REG_JOIN:
+ strcpy(state_str, "RegJ");
+ break;
+ case PIM_REG_JOIN_PENDING:
+ case PIM_REG_PRUNE:
+ strcpy(state_str, "RegP");
+ break;
+ default:
+ strcpy(state_str, "Unk");
+ }
+ return state_str;
}
static void pim_show_upstream(struct vty *vty, u_char uj)
{
- struct listnode *upnode;
- struct pim_upstream *up;
- time_t now;
- json_object *json = NULL;
- json_object *json_group = NULL;
- json_object *json_row = NULL;
-
- now = pim_time_monotonic_sec();
-
- if (uj)
- json = json_object_new_object();
- else
- vty_out (vty,
- "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
-
- for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode, up)) {
- char src_str[INET_ADDRSTRLEN];
- char grp_str[INET_ADDRSTRLEN];
- char uptime[10];
- char join_timer[10];
- char rs_timer[10];
- char ka_timer[10];
- char msdp_reg_timer[10];
- char state_str[PIM_REG_STATE_STR_LEN];
-
- pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
- pim_time_uptime(uptime, sizeof(uptime), now - up->state_transition);
- pim_time_timer_to_hhmmss (join_timer, sizeof(join_timer), up->t_join_timer);
-
- /*
- * If we have a J/P timer for the neighbor display that
- */
- if (!up->t_join_timer)
- {
- struct pim_neighbor *nbr;
-
- nbr = pim_neighbor_find (up->rpf.source_nexthop.interface,
- up->rpf.rpf_addr.u.prefix4);
- if (nbr)
- pim_time_timer_to_hhmmss (join_timer, sizeof(join_timer), nbr->jp_timer);
- }
-
- pim_time_timer_to_hhmmss (rs_timer, sizeof (rs_timer), up->t_rs_timer);
- pim_time_timer_to_hhmmss (ka_timer, sizeof (ka_timer), up->t_ka_timer);
- pim_time_timer_to_hhmmss (msdp_reg_timer, sizeof (msdp_reg_timer), up->t_msdp_reg_timer);
-
- pim_upstream_state2brief_str (up->join_state, state_str);
- if (up->reg_state != PIM_REG_NOINFO) {
- char tmp_str[PIM_REG_STATE_STR_LEN];
-
- sprintf (state_str + strlen (state_str), ",%s",
- pim_reg_state2brief_str (up->reg_state, tmp_str));
- }
-
- if (uj) {
- json_object_object_get_ex(json, grp_str, &json_group);
-
- if (!json_group) {
- json_group = json_object_new_object();
- json_object_object_add(json, grp_str, json_group);
- }
-
- json_row = json_object_new_object();
- json_object_pim_upstream_add(json_row, up);
- json_object_string_add(json_row, "inboundInterface", up->rpf.source_nexthop.interface->name);
- json_object_string_add(json_row, "source", src_str);
- json_object_string_add(json_row, "group", grp_str);
- json_object_string_add(json_row, "state", state_str);
- json_object_string_add(json_row, "joinState", pim_upstream_state2str (up->join_state));
- json_object_string_add(json_row, "regState", pim_reg_state2str (up->reg_state, state_str));
- json_object_string_add(json_row, "upTime", uptime);
- json_object_string_add(json_row, "joinTimer", join_timer);
- json_object_string_add(json_row, "resetTimer", rs_timer);
- json_object_string_add(json_row, "keepaliveTimer", ka_timer);
- json_object_string_add(json_row, "msdpRegTimer", msdp_reg_timer);
- json_object_int_add(json_row, "refCount", up->ref_count);
- json_object_int_add(json_row, "sptBit", up->sptbit);
- json_object_object_add(json_group, src_str, json_row);
- } else {
- vty_out (vty, "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
- up->rpf.source_nexthop.interface->name,
- src_str,
- grp_str,
- state_str,
- uptime,
- join_timer,
- rs_timer,
- ka_timer,
- up->ref_count);
- }
- }
-
- if (uj) {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
+ struct listnode *upnode;
+ struct pim_upstream *up;
+ time_t now;
+ json_object *json = NULL;
+ json_object *json_group = NULL;
+ json_object *json_row = NULL;
+
+ now = pim_time_monotonic_sec();
+
+ if (uj)
+ json = json_object_new_object();
+ else
+ vty_out(vty,
+ "Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
+
+ for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode, up)) {
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ char uptime[10];
+ char join_timer[10];
+ char rs_timer[10];
+ char ka_timer[10];
+ char msdp_reg_timer[10];
+ char state_str[PIM_REG_STATE_STR_LEN];
+
+ pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
+ pim_time_uptime(uptime, sizeof(uptime),
+ now - up->state_transition);
+ pim_time_timer_to_hhmmss(join_timer, sizeof(join_timer),
+ up->t_join_timer);
+
+ /*
+ * If we have a J/P timer for the neighbor display that
+ */
+ if (!up->t_join_timer) {
+ struct pim_neighbor *nbr;
+
+ nbr = pim_neighbor_find(
+ up->rpf.source_nexthop.interface,
+ up->rpf.rpf_addr.u.prefix4);
+ if (nbr)
+ pim_time_timer_to_hhmmss(join_timer,
+ sizeof(join_timer),
+ nbr->jp_timer);
+ }
+
+ pim_time_timer_to_hhmmss(rs_timer, sizeof(rs_timer),
+ up->t_rs_timer);
+ pim_time_timer_to_hhmmss(ka_timer, sizeof(ka_timer),
+ up->t_ka_timer);
+ pim_time_timer_to_hhmmss(msdp_reg_timer, sizeof(msdp_reg_timer),
+ up->t_msdp_reg_timer);
+
+ pim_upstream_state2brief_str(up->join_state, state_str);
+ if (up->reg_state != PIM_REG_NOINFO) {
+ char tmp_str[PIM_REG_STATE_STR_LEN];
+
+ sprintf(state_str + strlen(state_str), ",%s",
+ pim_reg_state2brief_str(up->reg_state,
+ tmp_str));
+ }
+
+ if (uj) {
+ json_object_object_get_ex(json, grp_str, &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str,
+ json_group);
+ }
+
+ json_row = json_object_new_object();
+ json_object_pim_upstream_add(json_row, up);
+ json_object_string_add(
+ json_row, "inboundInterface",
+ up->rpf.source_nexthop.interface->name);
+ json_object_string_add(json_row, "source", src_str);
+ json_object_string_add(json_row, "group", grp_str);
+ json_object_string_add(json_row, "state", state_str);
+ json_object_string_add(
+ json_row, "joinState",
+ pim_upstream_state2str(up->join_state));
+ json_object_string_add(
+ json_row, "regState",
+ pim_reg_state2str(up->reg_state, state_str));
+ json_object_string_add(json_row, "upTime", uptime);
+ json_object_string_add(json_row, "joinTimer",
+ join_timer);
+ json_object_string_add(json_row, "resetTimer",
+ rs_timer);
+ json_object_string_add(json_row, "keepaliveTimer",
+ ka_timer);
+ json_object_string_add(json_row, "msdpRegTimer",
+ msdp_reg_timer);
+ json_object_int_add(json_row, "refCount",
+ up->ref_count);
+ json_object_int_add(json_row, "sptBit", up->sptbit);
+ json_object_object_add(json_group, src_str, json_row);
+ } else {
+ vty_out(vty,
+ "%-10s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
+ up->rpf.source_nexthop.interface->name, src_str,
+ grp_str, state_str, uptime, join_timer,
+ rs_timer, ka_timer, up->ref_count);
+ }
+ }
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
}
static void pim_show_join_desired(struct vty *vty, u_char uj)
{
- struct listnode *chnode;
- struct pim_interface *pim_ifp;
- struct pim_ifchannel *ch;
- char src_str[INET_ADDRSTRLEN];
- char grp_str[INET_ADDRSTRLEN];
- json_object *json = NULL;
- json_object *json_group = NULL;
- json_object *json_row = NULL;
-
- if (uj)
- json = json_object_new_object();
- else
- vty_out (vty,
- "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
-
- /* scan per-interface (S,G) state */
- for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, chnode, ch)) {
- /* scan all interfaces */
- pim_ifp = ch->interface->info;
- if (!pim_ifp)
- continue;
-
- struct pim_upstream *up = ch->upstream;
-
- pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
-
- if (uj) {
- json_object_object_get_ex(json, grp_str, &json_group);
-
- if (!json_group) {
- json_group = json_object_new_object();
- json_object_object_add(json, grp_str, json_group);
- }
-
- json_row = json_object_new_object();
- json_object_pim_upstream_add(json_row, up);
- json_object_string_add(json_row, "interface", ch->interface->name);
- json_object_string_add(json_row, "source", src_str);
- json_object_string_add(json_row, "group", grp_str);
-
- if (pim_macro_ch_lost_assert(ch))
- json_object_boolean_true_add(json_row, "lostAssert");
-
- if (pim_macro_chisin_joins(ch))
- json_object_boolean_true_add(json_row, "joins");
-
- if (pim_macro_chisin_pim_include(ch))
- json_object_boolean_true_add(json_row, "pimInclude");
-
- if (pim_upstream_evaluate_join_desired(up))
- json_object_boolean_true_add(json_row, "evaluateJoinDesired");
-
- json_object_object_add(json_group, src_str, json_row);
-
- } else {
- vty_out (vty, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
- ch->interface->name,
- src_str,
- grp_str,
- pim_macro_ch_lost_assert(ch) ? "yes" : "no",
- pim_macro_chisin_joins(ch) ? "yes" : "no",
- pim_macro_chisin_pim_include(ch) ? "yes" : "no",
- PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags) ? "yes" : "no",
- pim_upstream_evaluate_join_desired(up) ? "yes" : "no");
- }
- }
-
- if (uj) {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
+ struct listnode *chnode;
+ struct pim_interface *pim_ifp;
+ struct pim_ifchannel *ch;
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ json_object *json = NULL;
+ json_object *json_group = NULL;
+ json_object *json_row = NULL;
+
+ if (uj)
+ json = json_object_new_object();
+ else
+ vty_out(vty,
+ "Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
+
+ /* scan per-interface (S,G) state */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifchannel_list, chnode, ch)) {
+ /* scan all interfaces */
+ pim_ifp = ch->interface->info;
+ if (!pim_ifp)
+ continue;
+
+ struct pim_upstream *up = ch->upstream;
+
+ pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
+
+ if (uj) {
+ json_object_object_get_ex(json, grp_str, &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str,
+ json_group);
+ }
+
+ json_row = json_object_new_object();
+ json_object_pim_upstream_add(json_row, up);
+ json_object_string_add(json_row, "interface",
+ ch->interface->name);
+ json_object_string_add(json_row, "source", src_str);
+ json_object_string_add(json_row, "group", grp_str);
+
+ if (pim_macro_ch_lost_assert(ch))
+ json_object_boolean_true_add(json_row,
+ "lostAssert");
+
+ if (pim_macro_chisin_joins(ch))
+ json_object_boolean_true_add(json_row, "joins");
+
+ if (pim_macro_chisin_pim_include(ch))
+ json_object_boolean_true_add(json_row,
+ "pimInclude");
+
+ if (pim_upstream_evaluate_join_desired(up))
+ json_object_boolean_true_add(
+ json_row, "evaluateJoinDesired");
+
+ json_object_object_add(json_group, src_str, json_row);
+
+ } else {
+ vty_out(vty,
+ "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s\n",
+ ch->interface->name, src_str, grp_str,
+ pim_macro_ch_lost_assert(ch) ? "yes" : "no",
+ pim_macro_chisin_joins(ch) ? "yes" : "no",
+ pim_macro_chisin_pim_include(ch) ? "yes" : "no",
+ PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(
+ up->flags)
+ ? "yes"
+ : "no",
+ pim_upstream_evaluate_join_desired(up) ? "yes"
+ : "no");
+ }
+ }
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
}
static void pim_show_upstream_rpf(struct vty *vty, u_char uj)
{
- struct listnode *upnode;
- struct pim_upstream *up;
- json_object *json = NULL;
- json_object *json_group = NULL;
- json_object *json_row = NULL;
-
- if (uj)
- json = json_object_new_object();
- else
- vty_out (vty,
- "Source Group RpfIface RibNextHop RpfAddress \n");
-
- for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode, up)) {
- char src_str[INET_ADDRSTRLEN];
- char grp_str[INET_ADDRSTRLEN];
- char rpf_nexthop_str[PREFIX_STRLEN];
- char rpf_addr_str[PREFIX_STRLEN];
- struct pim_rpf *rpf;
- const char *rpf_ifname;
-
- rpf = &up->rpf;
-
- pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
- pim_addr_dump("<nexthop?>", &rpf->source_nexthop.mrib_nexthop_addr, rpf_nexthop_str, sizeof(rpf_nexthop_str));
- pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
-
- rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
-
- if (uj) {
- json_object_object_get_ex(json, grp_str, &json_group);
-
- if (!json_group) {
- json_group = json_object_new_object();
- json_object_object_add(json, grp_str, json_group);
- }
-
- json_row = json_object_new_object();
- json_object_pim_upstream_add(json_row, up);
- json_object_string_add(json_row, "source", src_str);
- json_object_string_add(json_row, "group", grp_str);
- json_object_string_add(json_row, "rpfInterface", rpf_ifname);
- json_object_string_add(json_row, "ribNexthop", rpf_nexthop_str);
- json_object_string_add(json_row, "rpfAddress", rpf_addr_str);
- json_object_object_add(json_group, src_str, json_row);
- } else {
- vty_out (vty, "%-15s %-15s %-8s %-15s %-15s\n",
- src_str,
- grp_str,
- rpf_ifname,
- rpf_nexthop_str,
- rpf_addr_str);
- }
- }
-
- if (uj) {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
-}
-
-static void show_rpf_refresh_stats(struct vty *vty, time_t now, json_object *json)
-{
- char refresh_uptime[10];
-
- pim_time_uptime_begin(refresh_uptime, sizeof(refresh_uptime), now, qpim_rpf_cache_refresh_last);
-
- if (json) {
- json_object_int_add(json, "rpfCacheRefreshDelayMsecs", qpim_rpf_cache_refresh_delay_msec);
- json_object_int_add(json, "rpfCacheRefreshTimer", pim_time_timer_remain_msec(qpim_rpf_cache_refresher));
- json_object_int_add(json, "rpfCacheRefreshRequests", qpim_rpf_cache_refresh_requests);
- json_object_int_add(json, "rpfCacheRefreshEvents", qpim_rpf_cache_refresh_events);
- json_object_string_add(json, "rpfCacheRefreshLast", refresh_uptime);
- json_object_int_add(json, "nexthopLookups", qpim_nexthop_lookups);
- json_object_int_add(json, "nexthopLookupsAvoided", nexthop_lookups_avoided);
- } else {
- vty_out (vty,
- "RPF Cache Refresh Delay: %ld msecs\n"
- "RPF Cache Refresh Timer: %ld msecs\n"
- "RPF Cache Refresh Requests: %lld\n"
- "RPF Cache Refresh Events: %lld\n"
- "RPF Cache Refresh Last: %s\n"
- "Nexthop Lookups: %lld\n"
- "Nexthop Lookups Avoided: %lld\n",
- qpim_rpf_cache_refresh_delay_msec,
- pim_time_timer_remain_msec(qpim_rpf_cache_refresher),
- (long long)qpim_rpf_cache_refresh_requests,
- (long long)qpim_rpf_cache_refresh_events,
- refresh_uptime,
- (long long) qpim_nexthop_lookups,
- (long long)nexthop_lookups_avoided);
- }
+ struct listnode *upnode;
+ struct pim_upstream *up;
+ json_object *json = NULL;
+ json_object *json_group = NULL;
+ json_object *json_row = NULL;
+
+ if (uj)
+ json = json_object_new_object();
+ else
+ vty_out(vty,
+ "Source Group RpfIface RibNextHop RpfAddress \n");
+
+ for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode, up)) {
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ char rpf_nexthop_str[PREFIX_STRLEN];
+ char rpf_addr_str[PREFIX_STRLEN];
+ struct pim_rpf *rpf;
+ const char *rpf_ifname;
+
+ rpf = &up->rpf;
+
+ pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
+ pim_addr_dump("<nexthop?>",
+ &rpf->source_nexthop.mrib_nexthop_addr,
+ rpf_nexthop_str, sizeof(rpf_nexthop_str));
+ pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str,
+ sizeof(rpf_addr_str));
+
+ rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
+
+ if (uj) {
+ json_object_object_get_ex(json, grp_str, &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str,
+ json_group);
+ }
+
+ json_row = json_object_new_object();
+ json_object_pim_upstream_add(json_row, up);
+ json_object_string_add(json_row, "source", src_str);
+ json_object_string_add(json_row, "group", grp_str);
+ json_object_string_add(json_row, "rpfInterface",
+ rpf_ifname);
+ json_object_string_add(json_row, "ribNexthop",
+ rpf_nexthop_str);
+ json_object_string_add(json_row, "rpfAddress",
+ rpf_addr_str);
+ json_object_object_add(json_group, src_str, json_row);
+ } else {
+ vty_out(vty, "%-15s %-15s %-8s %-15s %-15s\n", src_str,
+ grp_str, rpf_ifname, rpf_nexthop_str,
+ rpf_addr_str);
+ }
+ }
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
+}
+
+static void show_rpf_refresh_stats(struct vty *vty, time_t now,
+ json_object *json)
+{
+ char refresh_uptime[10];
+
+ pim_time_uptime_begin(refresh_uptime, sizeof(refresh_uptime), now,
+ qpim_rpf_cache_refresh_last);
+
+ if (json) {
+ json_object_int_add(json, "rpfCacheRefreshDelayMsecs",
+ qpim_rpf_cache_refresh_delay_msec);
+ json_object_int_add(
+ json, "rpfCacheRefreshTimer",
+ pim_time_timer_remain_msec(qpim_rpf_cache_refresher));
+ json_object_int_add(json, "rpfCacheRefreshRequests",
+ qpim_rpf_cache_refresh_requests);
+ json_object_int_add(json, "rpfCacheRefreshEvents",
+ qpim_rpf_cache_refresh_events);
+ json_object_string_add(json, "rpfCacheRefreshLast",
+ refresh_uptime);
+ json_object_int_add(json, "nexthopLookups",
+ qpim_nexthop_lookups);
+ json_object_int_add(json, "nexthopLookupsAvoided",
+ nexthop_lookups_avoided);
+ } else {
+ vty_out(vty,
+ "RPF Cache Refresh Delay: %ld msecs\n"
+ "RPF Cache Refresh Timer: %ld msecs\n"
+ "RPF Cache Refresh Requests: %lld\n"
+ "RPF Cache Refresh Events: %lld\n"
+ "RPF Cache Refresh Last: %s\n"
+ "Nexthop Lookups: %lld\n"
+ "Nexthop Lookups Avoided: %lld\n",
+ qpim_rpf_cache_refresh_delay_msec,
+ pim_time_timer_remain_msec(qpim_rpf_cache_refresher),
+ (long long)qpim_rpf_cache_refresh_requests,
+ (long long)qpim_rpf_cache_refresh_events,
+ refresh_uptime, (long long)qpim_nexthop_lookups,
+ (long long)nexthop_lookups_avoided);
+ }
}
static void show_scan_oil_stats(struct vty *vty, time_t now)
{
- char uptime_scan_oil[10];
- char uptime_mroute_add[10];
- char uptime_mroute_del[10];
+ char uptime_scan_oil[10];
+ char uptime_mroute_add[10];
+ char uptime_mroute_del[10];
- pim_time_uptime_begin(uptime_scan_oil, sizeof(uptime_scan_oil), now, qpim_scan_oil_last);
- pim_time_uptime_begin(uptime_mroute_add, sizeof(uptime_mroute_add), now, qpim_mroute_add_last);
- pim_time_uptime_begin(uptime_mroute_del, sizeof(uptime_mroute_del), now, qpim_mroute_del_last);
+ pim_time_uptime_begin(uptime_scan_oil, sizeof(uptime_scan_oil), now,
+ qpim_scan_oil_last);
+ pim_time_uptime_begin(uptime_mroute_add, sizeof(uptime_mroute_add), now,
+ qpim_mroute_add_last);
+ pim_time_uptime_begin(uptime_mroute_del, sizeof(uptime_mroute_del), now,
+ qpim_mroute_del_last);
- vty_out (vty,
- "Scan OIL - Last: %s Events: %lld\n"
- "MFC Add - Last: %s Events: %lld\n"
- "MFC Del - Last: %s Events: %lld\n",
- uptime_scan_oil, (long long) qpim_scan_oil_events,
- uptime_mroute_add, (long long) qpim_mroute_add_events,
- uptime_mroute_del, (long long)qpim_mroute_del_events);
+ vty_out(vty,
+ "Scan OIL - Last: %s Events: %lld\n"
+ "MFC Add - Last: %s Events: %lld\n"
+ "MFC Del - Last: %s Events: %lld\n",
+ uptime_scan_oil, (long long)qpim_scan_oil_events,
+ uptime_mroute_add, (long long)qpim_mroute_add_events,
+ uptime_mroute_del, (long long)qpim_mroute_del_events);
}
static void pim_show_rpf(struct vty *vty, u_char uj)
{
- struct listnode *up_node;
- struct pim_upstream *up;
- time_t now = pim_time_monotonic_sec();
- json_object *json = NULL;
- json_object *json_group = NULL;
- json_object *json_row = NULL;
-
- if (uj) {
- json = json_object_new_object();
- show_rpf_refresh_stats(vty, now, json);
- } else {
- show_rpf_refresh_stats(vty, now, json);
- vty_out (vty, "\n");
- vty_out (vty,
- "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
- }
-
- for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, up_node, up)) {
- char src_str[INET_ADDRSTRLEN];
- char grp_str[INET_ADDRSTRLEN];
- char rpf_addr_str[PREFIX_STRLEN];
- char rib_nexthop_str[PREFIX_STRLEN];
- const char *rpf_ifname;
- struct pim_rpf *rpf = &up->rpf;
-
- pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
- pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
- pim_addr_dump("<nexthop?>", &rpf->source_nexthop.mrib_nexthop_addr, rib_nexthop_str, sizeof(rib_nexthop_str));
-
- rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
-
- if (uj) {
- json_object_object_get_ex(json, grp_str, &json_group);
-
- if (!json_group) {
- json_group = json_object_new_object();
- json_object_object_add(json, grp_str, json_group);
- }
-
- json_row = json_object_new_object();
- json_object_string_add(json_row, "source", src_str);
- json_object_string_add(json_row, "group", grp_str);
- json_object_string_add(json_row, "rpfInterface", rpf_ifname);
- json_object_string_add(json_row, "rpfAddress", rpf_addr_str);
- json_object_string_add(json_row, "ribNexthop", rib_nexthop_str);
- json_object_int_add(json_row, "routeMetric", rpf->source_nexthop.mrib_route_metric);
- json_object_int_add(json_row, "routePreference", rpf->source_nexthop.mrib_metric_preference);
- json_object_object_add(json_group, src_str, json_row);
-
- } else {
- vty_out (vty, "%-15s %-15s %-8s %-15s %-15s %6d %4d\n",
- src_str,
- grp_str,
- rpf_ifname,
- rpf_addr_str,
- rib_nexthop_str,
- rpf->source_nexthop.mrib_route_metric,
- rpf->source_nexthop.mrib_metric_preference);
- }
- }
-
- if (uj) {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
-}
-
-static int
-pim_print_pnc_cache_walkcb (struct hash_backet *backet, void *arg)
-{
- struct pim_nexthop_cache *pnc = backet->data;
- struct vty *vty = arg;
- struct nexthop *nh_node = NULL;
- ifindex_t first_ifindex;
- struct interface *ifp = NULL;
-
- if (!pnc)
- return CMD_SUCCESS;
-
- for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next)
- {
- first_ifindex = nh_node->ifindex;
- ifp = if_lookup_by_index (first_ifindex, VRF_DEFAULT);
-
- vty_out (vty, "%-15s ", inet_ntoa (pnc->rpf.rpf_addr.u.prefix4));
- vty_out (vty, "%-14s ", ifp ? ifp->name : "NULL");
- vty_out (vty, "%s ", inet_ntoa (nh_node->gate.ipv4));
- vty_out (vty, "\n");
- }
- return CMD_SUCCESS;
-}
-
-static void
-pim_show_nexthop (struct vty *vty)
-{
-
- if (pimg && !pimg->rpf_hash)
- {
- vty_out (vty, "no nexthop cache \n");
- return;
- }
-
- vty_out (vty, "Number of registered addresses: %lu \n",
- pimg->rpf_hash->count);
- vty_out (vty, "Address Interface Nexthop\n");
- vty_out (vty, "-------------------------------------------\n");
-
- hash_walk (pimg->rpf_hash, pim_print_pnc_cache_walkcb, vty);
+ struct listnode *up_node;
+ struct pim_upstream *up;
+ time_t now = pim_time_monotonic_sec();
+ json_object *json = NULL;
+ json_object *json_group = NULL;
+ json_object *json_row = NULL;
+
+ if (uj) {
+ json = json_object_new_object();
+ show_rpf_refresh_stats(vty, now, json);
+ } else {
+ show_rpf_refresh_stats(vty, now, json);
+ vty_out(vty, "\n");
+ vty_out(vty,
+ "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
+ }
+ for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, up_node, up)) {
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ char rpf_addr_str[PREFIX_STRLEN];
+ char rib_nexthop_str[PREFIX_STRLEN];
+ const char *rpf_ifname;
+ struct pim_rpf *rpf = &up->rpf;
+
+ pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
+ pim_addr_dump("<rpf?>", &rpf->rpf_addr, rpf_addr_str,
+ sizeof(rpf_addr_str));
+ pim_addr_dump("<nexthop?>",
+ &rpf->source_nexthop.mrib_nexthop_addr,
+ rib_nexthop_str, sizeof(rib_nexthop_str));
+
+ rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
+
+ if (uj) {
+ json_object_object_get_ex(json, grp_str, &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str,
+ json_group);
+ }
+
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "source", src_str);
+ json_object_string_add(json_row, "group", grp_str);
+ json_object_string_add(json_row, "rpfInterface",
+ rpf_ifname);
+ json_object_string_add(json_row, "rpfAddress",
+ rpf_addr_str);
+ json_object_string_add(json_row, "ribNexthop",
+ rib_nexthop_str);
+ json_object_int_add(
+ json_row, "routeMetric",
+ rpf->source_nexthop.mrib_route_metric);
+ json_object_int_add(
+ json_row, "routePreference",
+ rpf->source_nexthop.mrib_metric_preference);
+ json_object_object_add(json_group, src_str, json_row);
+
+ } else {
+ vty_out(vty, "%-15s %-15s %-8s %-15s %-15s %6d %4d\n",
+ src_str, grp_str, rpf_ifname, rpf_addr_str,
+ rib_nexthop_str,
+ rpf->source_nexthop.mrib_route_metric,
+ rpf->source_nexthop.mrib_metric_preference);
+ }
+ }
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
}
-static void igmp_show_groups(struct vty *vty, u_char uj)
+static int pim_print_pnc_cache_walkcb(struct hash_backet *backet, void *arg)
{
- struct listnode *ifnode;
- struct interface *ifp;
- time_t now;
- json_object *json = NULL;
- json_object *json_iface = NULL;
- json_object *json_row = NULL;
-
- now = pim_time_monotonic_sec();
-
- if (uj)
- json = json_object_new_object();
- else
- vty_out (vty,
- "Interface Address Group Mode Timer Srcs V Uptime \n");
-
- /* scan interfaces */
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
- struct pim_interface *pim_ifp = ifp->info;
- struct listnode *sock_node;
- struct igmp_sock *igmp;
-
- if (!pim_ifp)
- continue;
-
- /* scan igmp sockets */
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
- char ifaddr_str[INET_ADDRSTRLEN];
- struct listnode *grpnode;
- struct igmp_group *grp;
-
- pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
-
- /* scan igmp groups */
- for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
- char group_str[INET_ADDRSTRLEN];
- char hhmmss[10];
- char uptime[10];
+ struct pim_nexthop_cache *pnc = backet->data;
+ struct vty *vty = arg;
+ struct nexthop *nh_node = NULL;
+ ifindex_t first_ifindex;
+ struct interface *ifp = NULL;
+
+ if (!pnc)
+ return CMD_SUCCESS;
+
+ for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next) {
+ first_ifindex = nh_node->ifindex;
+ ifp = if_lookup_by_index(first_ifindex, VRF_DEFAULT);
+
+ vty_out(vty, "%-15s ", inet_ntoa(pnc->rpf.rpf_addr.u.prefix4));
+ vty_out(vty, "%-14s ", ifp ? ifp->name : "NULL");
+ vty_out(vty, "%s ", inet_ntoa(nh_node->gate.ipv4));
+ vty_out(vty, "\n");
+ }
+ return CMD_SUCCESS;
+}
+
+static void pim_show_nexthop(struct vty *vty)
+{
+
+ if (pimg && !pimg->rpf_hash) {
+ vty_out(vty, "no nexthop cache \n");
+ return;
+ }
+
+ vty_out(vty, "Number of registered addresses: %lu \n",
+ pimg->rpf_hash->count);
+ vty_out(vty, "Address Interface Nexthop\n");
+ vty_out(vty, "-------------------------------------------\n");
- pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
- pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss), grp->t_group_timer);
- pim_time_uptime(uptime, sizeof(uptime), now - grp->group_creation);
-
- if (uj) {
- json_object_object_get_ex(json, ifp->name, &json_iface);
-
- if (!json_iface) {
- json_iface = json_object_new_object();
- json_object_pim_ifp_add(json_iface, ifp);
- json_object_object_add(json, ifp->name, json_iface);
- }
-
- json_row = json_object_new_object();
- json_object_string_add(json_row, "source", ifaddr_str);
- json_object_string_add(json_row, "group", group_str);
-
- if (grp->igmp_version == 3)
- json_object_string_add(json_row, "mode", grp->group_filtermode_isexcl ? "EXCLUDE" : "INCLUDE");
-
- json_object_string_add(json_row, "timer", hhmmss);
- json_object_int_add(json_row, "sourcesCount", grp->group_source_list ? listcount(grp->group_source_list) : 0);
- json_object_int_add(json_row, "version", grp->igmp_version);
- json_object_string_add(json_row, "uptime", uptime);
- json_object_object_add(json_iface, group_str, json_row);
-
- } else {
- vty_out (vty, "%-9s %-15s %-15s %4s %8s %4d %d %8s\n",
- ifp->name,
- ifaddr_str,
- group_str,
- grp->igmp_version == 3 ? (grp->group_filtermode_isexcl ? "EXCL" : "INCL") : "----",
- hhmmss,
- grp->group_source_list ? listcount(grp->group_source_list) : 0,
- grp->igmp_version,
- uptime);
- }
- } /* scan igmp groups */
- } /* scan igmp sockets */
- } /* scan interfaces */
-
- if (uj) {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
+ hash_walk(pimg->rpf_hash, pim_print_pnc_cache_walkcb, vty);
+}
+
+static void igmp_show_groups(struct vty *vty, u_char uj)
+{
+ struct listnode *ifnode;
+ struct interface *ifp;
+ time_t now;
+ json_object *json = NULL;
+ json_object *json_iface = NULL;
+ json_object *json_row = NULL;
+
+ now = pim_time_monotonic_sec();
+
+ if (uj)
+ json = json_object_new_object();
+ else
+ vty_out(vty,
+ "Interface Address Group Mode Timer Srcs V Uptime \n");
+
+ /* scan interfaces */
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), ifnode, ifp)) {
+ struct pim_interface *pim_ifp = ifp->info;
+ struct listnode *sock_node;
+ struct igmp_sock *igmp;
+
+ if (!pim_ifp)
+ continue;
+
+ /* scan igmp sockets */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
+ igmp)) {
+ char ifaddr_str[INET_ADDRSTRLEN];
+ struct listnode *grpnode;
+ struct igmp_group *grp;
+
+ pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
+ sizeof(ifaddr_str));
+
+ /* scan igmp groups */
+ for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
+ grpnode, grp)) {
+ char group_str[INET_ADDRSTRLEN];
+ char hhmmss[10];
+ char uptime[10];
+
+ pim_inet4_dump("<group?>", grp->group_addr,
+ group_str, sizeof(group_str));
+ pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss),
+ grp->t_group_timer);
+ pim_time_uptime(uptime, sizeof(uptime),
+ now - grp->group_creation);
+
+ if (uj) {
+ json_object_object_get_ex(
+ json, ifp->name, &json_iface);
+
+ if (!json_iface) {
+ json_iface =
+ json_object_new_object();
+ json_object_pim_ifp_add(
+ json_iface, ifp);
+ json_object_object_add(
+ json, ifp->name,
+ json_iface);
+ }
+
+ json_row = json_object_new_object();
+ json_object_string_add(
+ json_row, "source", ifaddr_str);
+ json_object_string_add(
+ json_row, "group", group_str);
+
+ if (grp->igmp_version == 3)
+ json_object_string_add(
+ json_row, "mode",
+ grp->group_filtermode_isexcl
+ ? "EXCLUDE"
+ : "INCLUDE");
+
+ json_object_string_add(json_row,
+ "timer", hhmmss);
+ json_object_int_add(
+ json_row, "sourcesCount",
+ grp->group_source_list
+ ? listcount(
+ grp->group_source_list)
+ : 0);
+ json_object_int_add(json_row, "version",
+ grp->igmp_version);
+ json_object_string_add(
+ json_row, "uptime", uptime);
+ json_object_object_add(json_iface,
+ group_str,
+ json_row);
+
+ } else {
+ vty_out(vty,
+ "%-9s %-15s %-15s %4s %8s %4d %d %8s\n",
+ ifp->name, ifaddr_str,
+ group_str,
+ grp->igmp_version == 3
+ ? (grp->group_filtermode_isexcl
+ ? "EXCL"
+ : "INCL")
+ : "----",
+ hhmmss,
+ grp->group_source_list
+ ? listcount(
+ grp->group_source_list)
+ : 0,
+ grp->igmp_version, uptime);
+ }
+ } /* scan igmp groups */
+ } /* scan igmp sockets */
+ } /* scan interfaces */
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
}
static void igmp_show_group_retransmission(struct vty *vty)
{
- struct listnode *ifnode;
- struct interface *ifp;
-
- vty_out (vty,
- "Interface Address Group RetTimer Counter RetSrcs\n");
-
- /* scan interfaces */
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
- struct pim_interface *pim_ifp = ifp->info;
- struct listnode *sock_node;
- struct igmp_sock *igmp;
-
- if (!pim_ifp)
- continue;
-
- /* scan igmp sockets */
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
- char ifaddr_str[INET_ADDRSTRLEN];
- struct listnode *grpnode;
- struct igmp_group *grp;
-
- pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
-
- /* scan igmp groups */
- for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
- char group_str[INET_ADDRSTRLEN];
- char grp_retr_mmss[10];
- struct listnode *src_node;
- struct igmp_source *src;
- int grp_retr_sources = 0;
-
- pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
- pim_time_timer_to_mmss(grp_retr_mmss, sizeof(grp_retr_mmss), grp->t_group_query_retransmit_timer);
-
-
- /* count group sources with retransmission state */
- for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
- if (src->source_query_retransmit_count > 0) {
- ++grp_retr_sources;
- }
- }
-
- vty_out (vty, "%-9s %-15s %-15s %-8s %7d %7d\n",
- ifp->name,
- ifaddr_str,
- group_str,
- grp_retr_mmss,
- grp->group_specific_query_retransmit_count,
- grp_retr_sources);
-
- } /* scan igmp groups */
- } /* scan igmp sockets */
- } /* scan interfaces */
+ struct listnode *ifnode;
+ struct interface *ifp;
+
+ vty_out(vty,
+ "Interface Address Group RetTimer Counter RetSrcs\n");
+
+ /* scan interfaces */
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), ifnode, ifp)) {
+ struct pim_interface *pim_ifp = ifp->info;
+ struct listnode *sock_node;
+ struct igmp_sock *igmp;
+
+ if (!pim_ifp)
+ continue;
+
+ /* scan igmp sockets */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
+ igmp)) {
+ char ifaddr_str[INET_ADDRSTRLEN];
+ struct listnode *grpnode;
+ struct igmp_group *grp;
+
+ pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
+ sizeof(ifaddr_str));
+
+ /* scan igmp groups */
+ for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
+ grpnode, grp)) {
+ char group_str[INET_ADDRSTRLEN];
+ char grp_retr_mmss[10];
+ struct listnode *src_node;
+ struct igmp_source *src;
+ int grp_retr_sources = 0;
+
+ pim_inet4_dump("<group?>", grp->group_addr,
+ group_str, sizeof(group_str));
+ pim_time_timer_to_mmss(
+ grp_retr_mmss, sizeof(grp_retr_mmss),
+ grp->t_group_query_retransmit_timer);
+
+
+ /* count group sources with retransmission state
+ */
+ for (ALL_LIST_ELEMENTS_RO(
+ grp->group_source_list, src_node,
+ src)) {
+ if (src->source_query_retransmit_count
+ > 0) {
+ ++grp_retr_sources;
+ }
+ }
+
+ vty_out(vty, "%-9s %-15s %-15s %-8s %7d %7d\n",
+ ifp->name, ifaddr_str, group_str,
+ grp_retr_mmss,
+ grp->group_specific_query_retransmit_count,
+ grp_retr_sources);
+
+ } /* scan igmp groups */
+ } /* scan igmp sockets */
+ } /* scan interfaces */
}
static void igmp_show_sources(struct vty *vty)
{
- struct listnode *ifnode;
- struct interface *ifp;
- time_t now;
-
- now = pim_time_monotonic_sec();
-
- vty_out (vty,
- "Interface Address Group Source Timer Fwd Uptime \n");
-
- /* scan interfaces */
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
- struct pim_interface *pim_ifp = ifp->info;
- struct listnode *sock_node;
- struct igmp_sock *igmp;
-
- if (!pim_ifp)
- continue;
-
- /* scan igmp sockets */
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
- char ifaddr_str[INET_ADDRSTRLEN];
- struct listnode *grpnode;
- struct igmp_group *grp;
-
- pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
-
- /* scan igmp groups */
- for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
- char group_str[INET_ADDRSTRLEN];
- struct listnode *srcnode;
- struct igmp_source *src;
-
- pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
-
- /* scan group sources */
- for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
- char source_str[INET_ADDRSTRLEN];
- char mmss[10];
- char uptime[10];
-
- pim_inet4_dump("<source?>", src->source_addr, source_str, sizeof(source_str));
-
- pim_time_timer_to_mmss(mmss, sizeof(mmss), src->t_source_timer);
-
- pim_time_uptime(uptime, sizeof(uptime), now - src->source_creation);
-
- vty_out (vty, "%-9s %-15s %-15s %-15s %5s %3s %8s\n",
- ifp->name,
- ifaddr_str,
- group_str,
- source_str,
- mmss,
- IGMP_SOURCE_TEST_FORWARDING(src->source_flags) ? "Y" : "N",
- uptime);
-
- } /* scan group sources */
- } /* scan igmp groups */
- } /* scan igmp sockets */
- } /* scan interfaces */
+ struct listnode *ifnode;
+ struct interface *ifp;
+ time_t now;
+
+ now = pim_time_monotonic_sec();
+
+ vty_out(vty,
+ "Interface Address Group Source Timer Fwd Uptime \n");
+
+ /* scan interfaces */
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), ifnode, ifp)) {
+ struct pim_interface *pim_ifp = ifp->info;
+ struct listnode *sock_node;
+ struct igmp_sock *igmp;
+
+ if (!pim_ifp)
+ continue;
+
+ /* scan igmp sockets */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
+ igmp)) {
+ char ifaddr_str[INET_ADDRSTRLEN];
+ struct listnode *grpnode;
+ struct igmp_group *grp;
+
+ pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
+ sizeof(ifaddr_str));
+
+ /* scan igmp groups */
+ for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
+ grpnode, grp)) {
+ char group_str[INET_ADDRSTRLEN];
+ struct listnode *srcnode;
+ struct igmp_source *src;
+
+ pim_inet4_dump("<group?>", grp->group_addr,
+ group_str, sizeof(group_str));
+
+ /* scan group sources */
+ for (ALL_LIST_ELEMENTS_RO(
+ grp->group_source_list, srcnode,
+ src)) {
+ char source_str[INET_ADDRSTRLEN];
+ char mmss[10];
+ char uptime[10];
+
+ pim_inet4_dump(
+ "<source?>", src->source_addr,
+ source_str, sizeof(source_str));
+
+ pim_time_timer_to_mmss(
+ mmss, sizeof(mmss),
+ src->t_source_timer);
+
+ pim_time_uptime(
+ uptime, sizeof(uptime),
+ now - src->source_creation);
+
+ vty_out(vty,
+ "%-9s %-15s %-15s %-15s %5s %3s %8s\n",
+ ifp->name, ifaddr_str,
+ group_str, source_str, mmss,
+ IGMP_SOURCE_TEST_FORWARDING(
+ src->source_flags)
+ ? "Y"
+ : "N",
+ uptime);
+
+ } /* scan group sources */
+ } /* scan igmp groups */
+ } /* scan igmp sockets */
+ } /* scan interfaces */
}
static void igmp_show_source_retransmission(struct vty *vty)
{
- struct listnode *ifnode;
- struct interface *ifp;
-
- vty_out (vty,
- "Interface Address Group Source Counter\n");
-
- /* scan interfaces */
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
- struct pim_interface *pim_ifp = ifp->info;
- struct listnode *sock_node;
- struct igmp_sock *igmp;
-
- if (!pim_ifp)
- continue;
-
- /* scan igmp sockets */
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
- char ifaddr_str[INET_ADDRSTRLEN];
- struct listnode *grpnode;
- struct igmp_group *grp;
-
- pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
-
- /* scan igmp groups */
- for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
- char group_str[INET_ADDRSTRLEN];
- struct listnode *srcnode;
- struct igmp_source *src;
-
- pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
-
- /* scan group sources */
- for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
- char source_str[INET_ADDRSTRLEN];
-
- pim_inet4_dump("<source?>", src->source_addr, source_str, sizeof(source_str));
-
- vty_out (vty, "%-9s %-15s %-15s %-15s %7d\n",
- ifp->name,
- ifaddr_str,
- group_str,
- source_str,
- src->source_query_retransmit_count);
-
- } /* scan group sources */
- } /* scan igmp groups */
- } /* scan igmp sockets */
- } /* scan interfaces */
+ struct listnode *ifnode;
+ struct interface *ifp;
+
+ vty_out(vty,
+ "Interface Address Group Source Counter\n");
+
+ /* scan interfaces */
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), ifnode, ifp)) {
+ struct pim_interface *pim_ifp = ifp->info;
+ struct listnode *sock_node;
+ struct igmp_sock *igmp;
+
+ if (!pim_ifp)
+ continue;
+
+ /* scan igmp sockets */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
+ igmp)) {
+ char ifaddr_str[INET_ADDRSTRLEN];
+ struct listnode *grpnode;
+ struct igmp_group *grp;
+
+ pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
+ sizeof(ifaddr_str));
+
+ /* scan igmp groups */
+ for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
+ grpnode, grp)) {
+ char group_str[INET_ADDRSTRLEN];
+ struct listnode *srcnode;
+ struct igmp_source *src;
+
+ pim_inet4_dump("<group?>", grp->group_addr,
+ group_str, sizeof(group_str));
+
+ /* scan group sources */
+ for (ALL_LIST_ELEMENTS_RO(
+ grp->group_source_list, srcnode,
+ src)) {
+ char source_str[INET_ADDRSTRLEN];
+
+ pim_inet4_dump(
+ "<source?>", src->source_addr,
+ source_str, sizeof(source_str));
+
+ vty_out(vty,
+ "%-9s %-15s %-15s %-15s %7d\n",
+ ifp->name, ifaddr_str,
+ group_str, source_str,
+ src->source_query_retransmit_count);
+
+ } /* scan group sources */
+ } /* scan igmp groups */
+ } /* scan igmp sockets */
+ } /* scan interfaces */
}
static void clear_igmp_interfaces()
{
- struct listnode *ifnode;
- struct listnode *ifnextnode;
- struct interface *ifp;
+ struct listnode *ifnode;
+ struct listnode *ifnextnode;
+ struct interface *ifp;
- for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
- pim_if_addr_del_all_igmp(ifp);
- }
+ for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), ifnode, ifnextnode,
+ ifp)) {
+ pim_if_addr_del_all_igmp(ifp);
+ }
- for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
- pim_if_addr_add_all(ifp);
- }
+ for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), ifnode, ifnextnode,
+ ifp)) {
+ pim_if_addr_add_all(ifp);
+ }
}
static void clear_pim_interfaces()
{
- struct listnode *ifnode;
- struct listnode *ifnextnode;
- struct interface *ifp;
+ struct listnode *ifnode;
+ struct listnode *ifnextnode;
+ struct interface *ifp;
- for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
- if (ifp->info) {
- pim_neighbor_delete_all(ifp, "interface cleared");
- }
- }
+ for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), ifnode, ifnextnode,
+ ifp)) {
+ if (ifp->info) {
+ pim_neighbor_delete_all(ifp, "interface cleared");
+ }
+ }
}
static void clear_interfaces()
{
- clear_igmp_interfaces();
- clear_pim_interfaces();
+ clear_igmp_interfaces();
+ clear_pim_interfaces();
}
DEFUN (clear_ip_interfaces,
@@ -2600,9 +3052,9 @@ DEFUN (clear_ip_interfaces,
IP_STR
"Reset interfaces\n")
{
- clear_interfaces();
+ clear_interfaces();
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (clear_ip_igmp_interfaces,
@@ -2613,47 +3065,51 @@ DEFUN (clear_ip_igmp_interfaces,
CLEAR_IP_IGMP_STR
"Reset IGMP interfaces\n")
{
- clear_igmp_interfaces();
+ clear_igmp_interfaces();
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
static void mroute_add_all()
{
- struct listnode *node;
- struct channel_oil *c_oil;
-
- for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
- if (pim_mroute_add(c_oil, __PRETTY_FUNCTION__)) {
- /* just log warning */
- char source_str[INET_ADDRSTRLEN];
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
- __FILE__, __PRETTY_FUNCTION__,
- source_str, group_str);
- }
- }
+ struct listnode *node;
+ struct channel_oil *c_oil;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
+ if (pim_mroute_add(c_oil, __PRETTY_FUNCTION__)) {
+ /* just log warning */
+ char source_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
+ source_str, sizeof(source_str));
+ pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
+ group_str, sizeof(group_str));
+ zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
+ __FILE__, __PRETTY_FUNCTION__, source_str,
+ group_str);
+ }
+ }
}
static void mroute_del_all()
{
- struct listnode *node;
- struct channel_oil *c_oil;
-
- for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
- if (pim_mroute_del(c_oil, __PRETTY_FUNCTION__)) {
- /* just log warning */
- char source_str[INET_ADDRSTRLEN];
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
- __FILE__, __PRETTY_FUNCTION__,
- source_str, group_str);
- }
- }
+ struct listnode *node;
+ struct channel_oil *c_oil;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
+ if (pim_mroute_del(c_oil, __PRETTY_FUNCTION__)) {
+ /* just log warning */
+ char source_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
+ source_str, sizeof(source_str));
+ pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
+ group_str, sizeof(group_str));
+ zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
+ __FILE__, __PRETTY_FUNCTION__, source_str,
+ group_str);
+ }
+ }
}
DEFUN (clear_ip_mroute,
@@ -2663,10 +3119,10 @@ DEFUN (clear_ip_mroute,
IP_STR
"Reset multicast routes\n")
{
- mroute_del_all();
- mroute_add_all();
+ mroute_del_all();
+ mroute_add_all();
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (clear_ip_pim_interfaces,
@@ -2677,9 +3133,9 @@ DEFUN (clear_ip_pim_interfaces,
CLEAR_IP_PIM_STR
"Reset PIM interfaces\n")
{
- clear_pim_interfaces();
+ clear_pim_interfaces();
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (clear_ip_pim_interface_traffic,
@@ -2691,34 +3147,33 @@ DEFUN (clear_ip_pim_interface_traffic,
"Reset PIM interfaces\n"
"Reset Protocol Packet counters\n")
{
- struct listnode *ifnode = NULL;
- struct listnode *ifnextnode = NULL;
- struct interface *ifp = NULL;
- struct pim_interface *pim_ifp = NULL;
-
- for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp))
- {
- pim_ifp = ifp->info;
-
- if (!pim_ifp)
- continue;
-
- pim_ifp->pim_ifstat_hello_recv = 0;
- pim_ifp->pim_ifstat_hello_sent = 0;
- pim_ifp->pim_ifstat_join_recv = 0;
- pim_ifp->pim_ifstat_join_send = 0;
- pim_ifp->pim_ifstat_prune_recv = 0;
- pim_ifp->pim_ifstat_prune_send = 0;
- pim_ifp->pim_ifstat_reg_recv = 0;
- pim_ifp->pim_ifstat_reg_send = 0;
- pim_ifp->pim_ifstat_reg_stop_recv = 0;
- pim_ifp->pim_ifstat_reg_stop_send = 0;
- pim_ifp->pim_ifstat_assert_recv = 0;
- pim_ifp->pim_ifstat_assert_send = 0;
-
- }
+ struct listnode *ifnode = NULL;
+ struct listnode *ifnextnode = NULL;
+ struct interface *ifp = NULL;
+ struct pim_interface *pim_ifp = NULL;
+
+ for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), ifnode, ifnextnode,
+ ifp)) {
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ pim_ifp->pim_ifstat_hello_recv = 0;
+ pim_ifp->pim_ifstat_hello_sent = 0;
+ pim_ifp->pim_ifstat_join_recv = 0;
+ pim_ifp->pim_ifstat_join_send = 0;
+ pim_ifp->pim_ifstat_prune_recv = 0;
+ pim_ifp->pim_ifstat_prune_send = 0;
+ pim_ifp->pim_ifstat_reg_recv = 0;
+ pim_ifp->pim_ifstat_reg_send = 0;
+ pim_ifp->pim_ifstat_reg_stop_recv = 0;
+ pim_ifp->pim_ifstat_reg_stop_send = 0;
+ pim_ifp->pim_ifstat_assert_recv = 0;
+ pim_ifp->pim_ifstat_assert_send = 0;
+ }
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (clear_ip_pim_oil,
@@ -2729,9 +3184,9 @@ DEFUN (clear_ip_pim_oil,
CLEAR_IP_PIM_STR
"Rescan PIM OIL (output interface list)\n")
{
- pim_scan_oil();
+ pim_scan_oil();
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_igmp_interface,
@@ -2745,16 +3200,16 @@ DEFUN (show_ip_igmp_interface,
"interface name\n"
"JavaScript Object Notation\n")
{
- u_char uj = use_json(argc, argv);
- int idx = 0;
+ u_char uj = use_json(argc, argv);
+ int idx = 0;
- if (argv_find(argv, argc, "detail", &idx) ||
- argv_find(argv, argc, "WORD", &idx))
- igmp_show_interfaces_single(vty, argv[idx]->arg, uj);
- else
- igmp_show_interfaces(vty, uj);
+ if (argv_find(argv, argc, "detail", &idx)
+ || argv_find(argv, argc, "WORD", &idx))
+ igmp_show_interfaces_single(vty, argv[idx]->arg, uj);
+ else
+ igmp_show_interfaces(vty, uj);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_igmp_join,
@@ -2765,9 +3220,9 @@ DEFUN (show_ip_igmp_join,
IGMP_STR
"IGMP static join information\n")
{
- igmp_show_interface_join(vty);
+ igmp_show_interface_join(vty);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_igmp_groups,
@@ -2779,10 +3234,10 @@ DEFUN (show_ip_igmp_groups,
IGMP_GROUP_STR
"JavaScript Object Notation\n")
{
- u_char uj = use_json(argc, argv);
- igmp_show_groups(vty, uj);
+ u_char uj = use_json(argc, argv);
+ igmp_show_groups(vty, uj);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_igmp_groups_retransmissions,
@@ -2794,9 +3249,9 @@ DEFUN (show_ip_igmp_groups_retransmissions,
IGMP_GROUP_STR
"IGMP group retransmissions\n")
{
- igmp_show_group_retransmission(vty);
+ igmp_show_group_retransmission(vty);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_igmp_sources,
@@ -2807,9 +3262,9 @@ DEFUN (show_ip_igmp_sources,
IGMP_STR
IGMP_SOURCE_STR)
{
- igmp_show_sources(vty);
+ igmp_show_sources(vty);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_igmp_sources_retransmissions,
@@ -2821,9 +3276,9 @@ DEFUN (show_ip_igmp_sources_retransmissions,
IGMP_SOURCE_STR
"IGMP source retransmissions\n")
{
- igmp_show_source_retransmission(vty);
+ igmp_show_source_retransmission(vty);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_pim_assert,
@@ -2834,9 +3289,9 @@ DEFUN (show_ip_pim_assert,
PIM_STR
"PIM interface assert\n")
{
- pim_show_assert(vty);
+ pim_show_assert(vty);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_pim_assert_internal,
@@ -2847,9 +3302,9 @@ DEFUN (show_ip_pim_assert_internal,
PIM_STR
"PIM interface internal assert state\n")
{
- pim_show_assert_internal(vty);
+ pim_show_assert_internal(vty);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_pim_assert_metric,
@@ -2860,9 +3315,9 @@ DEFUN (show_ip_pim_assert_metric,
PIM_STR
"PIM interface assert metric\n")
{
- pim_show_assert_metric(vty);
+ pim_show_assert_metric(vty);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_pim_assert_winner_metric,
@@ -2873,9 +3328,9 @@ DEFUN (show_ip_pim_assert_winner_metric,
PIM_STR
"PIM interface assert winner metric\n")
{
- pim_show_assert_winner_metric(vty);
+ pim_show_assert_winner_metric(vty);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_pim_interface,
@@ -2889,17 +3344,17 @@ DEFUN (show_ip_pim_interface,
"interface name\n"
"JavaScript Object Notation\n")
{
- u_char uj = use_json(argc, argv);
- int idx = 0;
+ u_char uj = use_json(argc, argv);
+ int idx = 0;
- if (argv_find(argv, argc, "WORD", &idx) ||
- argv_find(argv, argc, "detail", &idx))
- pim_show_interfaces_single(vty, argv[idx]->arg, uj);
+ if (argv_find(argv, argc, "WORD", &idx)
+ || argv_find(argv, argc, "detail", &idx))
+ pim_show_interfaces_single(vty, argv[idx]->arg, uj);
- else
- pim_show_interfaces(vty, uj);
+ else
+ pim_show_interfaces(vty, uj);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_pim_join,
@@ -2911,10 +3366,10 @@ DEFUN (show_ip_pim_join,
"PIM interface join information\n"
JSON_STR)
{
- u_char uj = use_json(argc, argv);
- pim_show_join(vty, uj);
+ u_char uj = use_json(argc, argv);
+ pim_show_join(vty, uj);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_pim_local_membership,
@@ -2926,10 +3381,10 @@ DEFUN (show_ip_pim_local_membership,
"PIM interface local-membership\n"
JSON_STR)
{
- u_char uj = use_json(argc, argv);
- pim_show_membership(vty, uj);
+ u_char uj = use_json(argc, argv);
+ pim_show_membership(vty, uj);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_pim_neighbor,
@@ -2943,16 +3398,16 @@ DEFUN (show_ip_pim_neighbor,
"Name of interface or neighbor\n"
"JavaScript Object Notation\n")
{
- u_char uj = use_json(argc, argv);
- int idx = 0;
+ u_char uj = use_json(argc, argv);
+ int idx = 0;
- if (argv_find(argv, argc, "detail", &idx) ||
- argv_find(argv, argc, "WORD", &idx))
- pim_show_neighbors_single(vty, argv[idx]->arg, uj);
- else
- pim_show_neighbors(vty, uj);
+ if (argv_find(argv, argc, "detail", &idx)
+ || argv_find(argv, argc, "WORD", &idx))
+ pim_show_neighbors_single(vty, argv[idx]->arg, uj);
+ else
+ pim_show_neighbors(vty, uj);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_pim_secondary,
@@ -2963,9 +3418,9 @@ DEFUN (show_ip_pim_secondary,
PIM_STR
"PIM neighbor addresses\n")
{
- pim_show_neighbors_secondary(vty);
+ pim_show_neighbors_secondary(vty);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_pim_state,
@@ -2979,23 +3434,21 @@ DEFUN (show_ip_pim_state,
"Multicast address\n"
"JavaScript Object Notation\n")
{
- const char *src_or_group = NULL;
- const char *group = NULL;
- u_char uj = use_json(argc, argv);
- if (uj)
- argc--;
+ const char *src_or_group = NULL;
+ const char *group = NULL;
+ u_char uj = use_json(argc, argv);
+ if (uj)
+ argc--;
- if (argc == 6)
- {
- src_or_group = argv[4]->arg;
- group = argv[5]->arg;
- }
- else if (argc == 5)
- src_or_group = argv[4]->arg;
+ if (argc == 6) {
+ src_or_group = argv[4]->arg;
+ group = argv[5]->arg;
+ } else if (argc == 5)
+ src_or_group = argv[4]->arg;
- pim_show_state(vty, src_or_group, group, uj);
+ pim_show_state(vty, src_or_group, group, uj);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_pim_upstream,
@@ -3007,10 +3460,10 @@ DEFUN (show_ip_pim_upstream,
"PIM upstream information\n"
"JavaScript Object Notation\n")
{
- u_char uj = use_json(argc, argv);
- pim_show_upstream(vty, uj);
+ u_char uj = use_json(argc, argv);
+ pim_show_upstream(vty, uj);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_pim_upstream_join_desired,
@@ -3022,10 +3475,10 @@ DEFUN (show_ip_pim_upstream_join_desired,
"PIM upstream join-desired\n"
"JavaScript Object Notation\n")
{
- u_char uj = use_json(argc, argv);
- pim_show_join_desired(vty, uj);
+ u_char uj = use_json(argc, argv);
+ pim_show_join_desired(vty, uj);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_pim_upstream_rpf,
@@ -3037,10 +3490,10 @@ DEFUN (show_ip_pim_upstream_rpf,
"PIM upstream source rpf\n"
"JavaScript Object Notation\n")
{
- u_char uj = use_json(argc, argv);
- pim_show_upstream_rpf(vty, uj);
+ u_char uj = use_json(argc, argv);
+ pim_show_upstream_rpf(vty, uj);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_pim_rp,
@@ -3052,10 +3505,10 @@ DEFUN (show_ip_pim_rp,
"PIM RP information\n"
"JavaScript Object Notation\n")
{
- u_char uj = use_json(argc, argv);
- pim_rp_show_information (vty, uj);
+ u_char uj = use_json(argc, argv);
+ pim_rp_show_information(vty, uj);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_pim_rpf,
@@ -3067,10 +3520,10 @@ DEFUN (show_ip_pim_rpf,
"PIM cached source rpf information\n"
"JavaScript Object Notation\n")
{
- u_char uj = use_json(argc, argv);
- pim_show_rpf(vty, uj);
+ u_char uj = use_json(argc, argv);
+ pim_show_rpf(vty, uj);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_pim_nexthop,
@@ -3081,9 +3534,9 @@ DEFUN (show_ip_pim_nexthop,
PIM_STR
"PIM cached nexthop rpf information\n")
{
- pim_show_nexthop (vty);
+ pim_show_nexthop(vty);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_pim_nexthop_lookup,
@@ -3096,75 +3549,70 @@ DEFUN (show_ip_pim_nexthop_lookup,
"Source/RP address\n"
"Multicast Group address\n")
{
- struct pim_nexthop_cache pnc;
- struct prefix nht_p;
- int result = 0;
- struct in_addr src_addr, grp_addr;
- struct in_addr vif_source;
- const char *addr_str, *addr_str1;
- struct prefix grp;
- struct pim_nexthop nexthop;
- char nexthop_addr_str[PREFIX_STRLEN];
- char grp_str[PREFIX_STRLEN];
-
- addr_str = argv[4]->arg;
- result = inet_pton (AF_INET, addr_str, &src_addr);
- if (result <= 0)
- {
- vty_out (vty, "Bad unicast address %s: errno=%d: %s\n",
- addr_str, errno, safe_strerror(errno));
- return CMD_WARNING;
- }
-
- if (pim_is_group_224_4 (src_addr))
- {
- vty_out (vty, "Invalid argument. Expected Valid Source Address.\n");
- return CMD_WARNING;
- }
-
- addr_str1 = argv[5]->arg;
- result = inet_pton (AF_INET, addr_str1, &grp_addr);
- if (result <= 0)
- {
- vty_out (vty, "Bad unicast address %s: errno=%d: %s\n",
- addr_str, errno, safe_strerror(errno));
- return CMD_WARNING;
- }
-
- if (!pim_is_group_224_4 (grp_addr))
- {
- vty_out (vty,
- "Invalid argument. Expected Valid Multicast Group Address.\n");
- return CMD_WARNING;
- }
-
- if (!pim_rp_set_upstream_addr (&vif_source, src_addr, grp_addr))
- return CMD_SUCCESS;
-
- memset (&pnc, 0, sizeof (struct pim_nexthop_cache));
- nht_p.family = AF_INET;
- nht_p.prefixlen = IPV4_MAX_BITLEN;
- nht_p.u.prefix4 = vif_source;
- grp.family = AF_INET;
- grp.prefixlen = IPV4_MAX_BITLEN;
- grp.u.prefix4 = grp_addr;
- memset (&nexthop, 0, sizeof (nexthop));
-
- if ((pim_find_or_track_nexthop (&nht_p, NULL, NULL, &pnc)) == 1)
- {
- //Compute PIM RPF using Cached nexthop
- pim_ecmp_nexthop_search (&pnc, &nexthop, &nht_p, &grp, 0);
- }
- else
- pim_ecmp_nexthop_lookup (&nexthop, vif_source, &nht_p, &grp, 0);
-
- pim_addr_dump ("<grp?>", &grp, grp_str, sizeof (grp_str));
- pim_addr_dump ("<nexthop?>", &nexthop.mrib_nexthop_addr,
- nexthop_addr_str, sizeof (nexthop_addr_str));
- vty_out (vty, "Group %s --- Nexthop %s Interface %s \n", grp_str,
- nexthop_addr_str, nexthop.interface->name);
-
- return CMD_SUCCESS;
+ struct pim_nexthop_cache pnc;
+ struct prefix nht_p;
+ int result = 0;
+ struct in_addr src_addr, grp_addr;
+ struct in_addr vif_source;
+ const char *addr_str, *addr_str1;
+ struct prefix grp;
+ struct pim_nexthop nexthop;
+ char nexthop_addr_str[PREFIX_STRLEN];
+ char grp_str[PREFIX_STRLEN];
+
+ addr_str = argv[4]->arg;
+ result = inet_pton(AF_INET, addr_str, &src_addr);
+ if (result <= 0) {
+ vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
+ errno, safe_strerror(errno));
+ return CMD_WARNING;
+ }
+
+ if (pim_is_group_224_4(src_addr)) {
+ vty_out(vty,
+ "Invalid argument. Expected Valid Source Address.\n");
+ return CMD_WARNING;
+ }
+
+ addr_str1 = argv[5]->arg;
+ result = inet_pton(AF_INET, addr_str1, &grp_addr);
+ if (result <= 0) {
+ vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
+ errno, safe_strerror(errno));
+ return CMD_WARNING;
+ }
+
+ if (!pim_is_group_224_4(grp_addr)) {
+ vty_out(vty,
+ "Invalid argument. Expected Valid Multicast Group Address.\n");
+ return CMD_WARNING;
+ }
+
+ if (!pim_rp_set_upstream_addr(&vif_source, src_addr, grp_addr))
+ return CMD_SUCCESS;
+
+ memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
+ nht_p.family = AF_INET;
+ nht_p.prefixlen = IPV4_MAX_BITLEN;
+ nht_p.u.prefix4 = vif_source;
+ grp.family = AF_INET;
+ grp.prefixlen = IPV4_MAX_BITLEN;
+ grp.u.prefix4 = grp_addr;
+ memset(&nexthop, 0, sizeof(nexthop));
+
+ if ((pim_find_or_track_nexthop(&nht_p, NULL, NULL, &pnc)) == 1) {
+ // Compute PIM RPF using Cached nexthop
+ pim_ecmp_nexthop_search(&pnc, &nexthop, &nht_p, &grp, 0);
+ } else
+ pim_ecmp_nexthop_lookup(&nexthop, vif_source, &nht_p, &grp, 0);
+
+ pim_addr_dump("<grp?>", &grp, grp_str, sizeof(grp_str));
+ pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
+ nexthop_addr_str, sizeof(nexthop_addr_str));
+ vty_out(vty, "Group %s --- Nexthop %s Interface %s \n", grp_str,
+ nexthop_addr_str, nexthop.interface->name);
+
+ return CMD_SUCCESS;
}
DEFUN (show_ip_pim_interface_traffic,
@@ -3178,61 +3626,56 @@ DEFUN (show_ip_pim_interface_traffic,
"Interface name\n"
"JavaScript Object Notation\n")
{
- u_char uj = use_json (argc, argv);
- int idx = 0;
+ u_char uj = use_json(argc, argv);
+ int idx = 0;
- if (argv_find(argv, argc, "WORD", &idx))
- pim_show_interface_traffic_single (vty, argv[idx]->arg, uj);
- else
- pim_show_interface_traffic (vty, uj);
+ if (argv_find(argv, argc, "WORD", &idx))
+ pim_show_interface_traffic_single(vty, argv[idx]->arg, uj);
+ else
+ pim_show_interface_traffic(vty, uj);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
static void show_multicast_interfaces(struct vty *vty)
{
- struct listnode *node;
- struct interface *ifp;
-
- vty_out (vty, "\n");
-
- vty_out (vty,
- "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
- struct pim_interface *pim_ifp;
- struct in_addr ifaddr;
- struct sioc_vif_req vreq;
-
- pim_ifp = ifp->info;
-
- if (!pim_ifp)
- continue;
-
- memset(&vreq, 0, sizeof(vreq));
- vreq.vifi = pim_ifp->mroute_vif_index;
-
- if (ioctl(qpim_mroute_socket_fd, SIOCGETVIFCNT, &vreq)) {
- zlog_warn("ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s\n",
- (unsigned long)SIOCGETVIFCNT,
- ifp->name,
- pim_ifp->mroute_vif_index,
- errno,
- safe_strerror(errno));
- }
-
- ifaddr = pim_ifp->primary_address;
-
- vty_out (vty, "%-9s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
- ifp->name,
- inet_ntoa(ifaddr),
- ifp->ifindex,
- pim_ifp->mroute_vif_index,
- (unsigned long) vreq.icount,
- (unsigned long) vreq.ocount,
- (unsigned long) vreq.ibytes,
- (unsigned long)vreq.obytes);
- }
+ struct listnode *node;
+ struct interface *ifp;
+
+ vty_out(vty, "\n");
+
+ vty_out(vty,
+ "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ struct pim_interface *pim_ifp;
+ struct in_addr ifaddr;
+ struct sioc_vif_req vreq;
+
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ memset(&vreq, 0, sizeof(vreq));
+ vreq.vifi = pim_ifp->mroute_vif_index;
+
+ if (ioctl(qpim_mroute_socket_fd, SIOCGETVIFCNT, &vreq)) {
+ zlog_warn(
+ "ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s\n",
+ (unsigned long)SIOCGETVIFCNT, ifp->name,
+ pim_ifp->mroute_vif_index, errno,
+ safe_strerror(errno));
+ }
+
+ ifaddr = pim_ifp->primary_address;
+
+ vty_out(vty, "%-9s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
+ ifp->name, inet_ntoa(ifaddr), ifp->ifindex,
+ pim_ifp->mroute_vif_index, (unsigned long)vreq.icount,
+ (unsigned long)vreq.ocount, (unsigned long)vreq.ibytes,
+ (unsigned long)vreq.obytes);
+ }
}
DEFUN (show_ip_multicast,
@@ -3242,327 +3685,364 @@ DEFUN (show_ip_multicast,
IP_STR
"Multicast global information\n")
{
- time_t now = pim_time_monotonic_sec();
+ time_t now = pim_time_monotonic_sec();
- char uptime[10];
+ char uptime[10];
+
+ vty_out(vty, "Mroute socket descriptor: %d\n", qpim_mroute_socket_fd);
- vty_out (vty, "Mroute socket descriptor: %d\n",
- qpim_mroute_socket_fd);
+ pim_time_uptime(uptime, sizeof(uptime),
+ now - qpim_mroute_socket_creation);
+ vty_out(vty, "Mroute socket uptime: %s\n", uptime);
- pim_time_uptime(uptime, sizeof(uptime), now - qpim_mroute_socket_creation);
- vty_out (vty, "Mroute socket uptime: %s\n",
- uptime);
+ vty_out(vty, "\n");
- vty_out (vty, "\n");
+ pim_zebra_zclient_update(vty);
+ pim_zlookup_show_ip_multicast(vty);
- pim_zebra_zclient_update (vty);
- pim_zlookup_show_ip_multicast (vty);
+ vty_out(vty, "\n");
+ vty_out(vty, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS);
- vty_out (vty, "\n");
- vty_out (vty, "Maximum highest VifIndex: %d\n",
- PIM_MAX_USABLE_VIFS);
+ vty_out(vty, "\n");
+ vty_out(vty, "Upstream Join Timer: %d secs\n", qpim_t_periodic);
+ vty_out(vty, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME);
+ vty_out(vty, "PIM ECMP: %s\n", qpim_ecmp_enable ? "Enable" : "Disable");
+ vty_out(vty, "PIM ECMP Rebalance: %s\n",
+ qpim_ecmp_rebalance_enable ? "Enable" : "Disable");
- vty_out (vty, "\n");
- vty_out (vty, "Upstream Join Timer: %d secs\n",
- qpim_t_periodic);
- vty_out (vty, "Join/Prune Holdtime: %d secs\n",
- PIM_JP_HOLDTIME);
- vty_out (vty, "PIM ECMP: %s\n",
- qpim_ecmp_enable ? "Enable" : "Disable");
- vty_out (vty, "PIM ECMP Rebalance: %s\n",
- qpim_ecmp_rebalance_enable ? "Enable" : "Disable");
+ vty_out(vty, "\n");
- vty_out (vty, "\n");
+ show_rpf_refresh_stats(vty, now, NULL);
- show_rpf_refresh_stats(vty, now, NULL);
+ vty_out(vty, "\n");
- vty_out (vty, "\n");
+ show_scan_oil_stats(vty, now);
- show_scan_oil_stats(vty, now);
+ show_multicast_interfaces(vty);
- show_multicast_interfaces(vty);
-
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
static void show_mroute(struct vty *vty, u_char uj)
{
- struct listnode *node;
- struct channel_oil *c_oil;
- struct static_route *s_route;
- time_t now;
- json_object *json = NULL;
- json_object *json_group = NULL;
- json_object *json_source = NULL;
- json_object *json_oil = NULL;
- json_object *json_ifp_out = NULL;
- int found_oif = 0;
- int first = 1;
- char grp_str[INET_ADDRSTRLEN];
- char src_str[INET_ADDRSTRLEN];
- char in_ifname[INTERFACE_NAMSIZ+1];
- char out_ifname[INTERFACE_NAMSIZ+1];
- int oif_vif_index;
- struct interface *ifp_in;
- char proto[100];
-
- if (uj) {
- json = json_object_new_object();
- } else {
- vty_out (vty,
- "Source Group Proto Input Output TTL Uptime\n");
- }
-
- now = pim_time_monotonic_sec();
-
- /* print list of PIM and IGMP routes */
- for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
- found_oif = 0;
- first = 1;
- if (!c_oil->installed && !uj)
- continue;
-
- pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str, sizeof(grp_str));
- pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str, sizeof(src_str));
- ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
-
- if (ifp_in)
- strcpy(in_ifname, ifp_in->name);
- else
- strcpy(in_ifname, "<iif?>");
-
- if (uj) {
-
- /* Find the group, create it if it doesn't exist */
- json_object_object_get_ex(json, grp_str, &json_group);
-
- if (!json_group) {
- json_group = json_object_new_object();
- json_object_object_add(json, grp_str, json_group);
- }
-
- /* Find the source nested under the group, create it if it doesn't exist */
- json_object_object_get_ex(json_group, src_str, &json_source);
-
- if (!json_source) {
- json_source = json_object_new_object();
- json_object_object_add(json_group, src_str, json_source);
- }
-
- /* Find the inbound interface nested under the source, create it if it doesn't exist */
- json_object_int_add(json_source, "installed", c_oil->installed);
- json_object_int_add(json_source, "refCount", c_oil->oil_ref_count);
- json_object_int_add(json_source, "oilSize", c_oil->oil_size);
- json_object_int_add(json_source, "OilInheritedRescan", c_oil->oil_inherited_rescan);
- json_object_string_add(json_source, "iif", in_ifname);
- json_oil = NULL;
- }
-
- for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
- struct interface *ifp_out;
- char oif_uptime[10];
- int ttl;
-
- ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
- if (ttl < 1)
- continue;
-
- ifp_out = pim_if_find_by_vif_index(oif_vif_index);
- pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - c_oil->oif_creation[oif_vif_index]);
- found_oif = 1;
-
- if (ifp_out)
- strcpy(out_ifname, ifp_out->name);
- else
- strcpy(out_ifname, "<oif?>");
-
- if (uj) {
- json_ifp_out = json_object_new_object();
- json_object_string_add(json_ifp_out, "source", src_str);
- json_object_string_add(json_ifp_out, "group", grp_str);
-
- if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM)
- json_object_boolean_true_add(json_ifp_out, "protocolPim");
-
- if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP)
- json_object_boolean_true_add(json_ifp_out, "protocolIgmp");
-
- if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE)
- json_object_boolean_true_add(json_ifp_out, "protocolSource");
-
- if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR)
- json_object_boolean_true_add(json_ifp_out, "protocolInherited");
-
- json_object_string_add(json_ifp_out, "inboundInterface", in_ifname);
- json_object_int_add(json_ifp_out, "iVifI", c_oil->oil.mfcc_parent);
- json_object_string_add(json_ifp_out, "outboundInterface", out_ifname);
- json_object_int_add(json_ifp_out, "oVifI", oif_vif_index);
- json_object_int_add(json_ifp_out, "ttl", ttl);
- json_object_string_add(json_ifp_out, "upTime", oif_uptime);
- if (!json_oil) {
- json_oil = json_object_new_object();
- json_object_object_add(json_source, "oil", json_oil);
- }
- json_object_object_add(json_oil, out_ifname, json_ifp_out);
- } else {
- if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) {
- strcpy(proto, "PIM");
- }
-
- if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) {
- strcpy(proto, "IGMP");
- }
-
- if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE) {
- strcpy(proto, "SRC");
- }
-
- if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR) {
- strcpy(proto, "STAR");
- }
-
- vty_out (vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
- src_str,
- grp_str,
- proto,
- in_ifname,
- out_ifname,
- ttl,
- oif_uptime);
-
- if (first)
- {
- src_str[0] = '\0';
- grp_str[0] = '\0';
- in_ifname[0] = '\0';
- first = 0;
- }
- }
- }
-
- if (!uj && !found_oif) {
- vty_out (vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
- src_str,
- grp_str,
- "none",
- in_ifname,
- "none",
- 0,
- "--:--:--");
- }
- }
-
- /* Print list of static routes */
- for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
- first = 1;
-
- if (!s_route->c_oil.installed)
- continue;
-
- pim_inet4_dump("<group?>", s_route->group, grp_str, sizeof(grp_str));
- pim_inet4_dump("<source?>", s_route->source, src_str, sizeof(src_str));
- ifp_in = pim_if_find_by_vif_index(s_route->iif);
- found_oif = 0;
-
- if (ifp_in)
- strcpy(in_ifname, ifp_in->name);
- else
- strcpy(in_ifname, "<iif?>");
-
- if (uj) {
-
- /* Find the group, create it if it doesn't exist */
- json_object_object_get_ex(json, grp_str, &json_group);
-
- if (!json_group) {
- json_group = json_object_new_object();
- json_object_object_add(json, grp_str, json_group);
- }
-
- /* Find the source nested under the group, create it if it doesn't exist */
- json_object_object_get_ex(json_group, src_str, &json_source);
-
- if (!json_source) {
- json_source = json_object_new_object();
- json_object_object_add(json_group, src_str, json_source);
- }
-
- json_object_string_add(json_source, "iif", in_ifname);
- json_oil = NULL;
- } else {
- strcpy(proto, "STATIC");
- }
-
- for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
- struct interface *ifp_out;
- char oif_uptime[10];
- int ttl;
-
- ttl = s_route->oif_ttls[oif_vif_index];
- if (ttl < 1)
- continue;
-
- ifp_out = pim_if_find_by_vif_index(oif_vif_index);
- pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - s_route->c_oil.oif_creation[oif_vif_index]);
- found_oif = 1;
-
- if (ifp_out)
- strcpy(out_ifname, ifp_out->name);
- else
- strcpy(out_ifname, "<oif?>");
-
- if (uj) {
- json_ifp_out = json_object_new_object();
- json_object_string_add(json_ifp_out, "source", src_str);
- json_object_string_add(json_ifp_out, "group", grp_str);
- json_object_boolean_true_add(json_ifp_out, "protocolStatic");
- json_object_string_add(json_ifp_out, "inboundInterface", in_ifname);
- json_object_int_add(json_ifp_out, "iVifI", s_route->c_oil.oil.mfcc_parent);
- json_object_string_add(json_ifp_out, "outboundInterface", out_ifname);
- json_object_int_add(json_ifp_out, "oVifI", oif_vif_index);
- json_object_int_add(json_ifp_out, "ttl", ttl);
- json_object_string_add(json_ifp_out, "upTime", oif_uptime);
- if (!json_oil) {
- json_oil = json_object_new_object();
- json_object_object_add(json_source, "oil", json_oil);
- }
- json_object_object_add(json_oil, out_ifname, json_ifp_out);
- } else {
- vty_out (vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
- src_str,
- grp_str,
- proto,
- in_ifname,
- out_ifname,
- ttl,
- oif_uptime);
- if (first)
- {
- src_str[0] = '\0';
- grp_str[0] = '\0';
- in_ifname[0] = '\0';
- first = 0;
- }
- }
- }
-
- if (!uj && !found_oif) {
- vty_out (vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
- src_str,
- grp_str,
- proto,
- in_ifname,
- "none",
- 0,
- "--:--:--");
- }
- }
-
- if (uj) {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
+ struct listnode *node;
+ struct channel_oil *c_oil;
+ struct static_route *s_route;
+ time_t now;
+ json_object *json = NULL;
+ json_object *json_group = NULL;
+ json_object *json_source = NULL;
+ json_object *json_oil = NULL;
+ json_object *json_ifp_out = NULL;
+ int found_oif = 0;
+ int first = 1;
+ char grp_str[INET_ADDRSTRLEN];
+ char src_str[INET_ADDRSTRLEN];
+ char in_ifname[INTERFACE_NAMSIZ + 1];
+ char out_ifname[INTERFACE_NAMSIZ + 1];
+ int oif_vif_index;
+ struct interface *ifp_in;
+ char proto[100];
+
+ if (uj) {
+ json = json_object_new_object();
+ } else {
+ vty_out(vty,
+ "Source Group Proto Input Output TTL Uptime\n");
+ }
+
+ now = pim_time_monotonic_sec();
+
+ /* print list of PIM and IGMP routes */
+ for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
+ found_oif = 0;
+ first = 1;
+ if (!c_oil->installed && !uj)
+ continue;
+
+ pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str,
+ sizeof(grp_str));
+ pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str,
+ sizeof(src_str));
+ ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
+
+ if (ifp_in)
+ strcpy(in_ifname, ifp_in->name);
+ else
+ strcpy(in_ifname, "<iif?>");
+
+ if (uj) {
+
+ /* Find the group, create it if it doesn't exist */
+ json_object_object_get_ex(json, grp_str, &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str,
+ json_group);
+ }
+
+ /* Find the source nested under the group, create it if
+ * it doesn't exist */
+ json_object_object_get_ex(json_group, src_str,
+ &json_source);
+
+ if (!json_source) {
+ json_source = json_object_new_object();
+ json_object_object_add(json_group, src_str,
+ json_source);
+ }
+
+ /* Find the inbound interface nested under the source,
+ * create it if it doesn't exist */
+ json_object_int_add(json_source, "installed",
+ c_oil->installed);
+ json_object_int_add(json_source, "refCount",
+ c_oil->oil_ref_count);
+ json_object_int_add(json_source, "oilSize",
+ c_oil->oil_size);
+ json_object_int_add(json_source, "OilInheritedRescan",
+ c_oil->oil_inherited_rescan);
+ json_object_string_add(json_source, "iif", in_ifname);
+ json_oil = NULL;
+ }
+
+ for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
+ ++oif_vif_index) {
+ struct interface *ifp_out;
+ char oif_uptime[10];
+ int ttl;
+
+ ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
+ if (ttl < 1)
+ continue;
+
+ ifp_out = pim_if_find_by_vif_index(oif_vif_index);
+ pim_time_uptime(
+ oif_uptime, sizeof(oif_uptime),
+ now - c_oil->oif_creation[oif_vif_index]);
+ found_oif = 1;
+
+ if (ifp_out)
+ strcpy(out_ifname, ifp_out->name);
+ else
+ strcpy(out_ifname, "<oif?>");
+
+ if (uj) {
+ json_ifp_out = json_object_new_object();
+ json_object_string_add(json_ifp_out, "source",
+ src_str);
+ json_object_string_add(json_ifp_out, "group",
+ grp_str);
+
+ if (c_oil->oif_flags[oif_vif_index]
+ & PIM_OIF_FLAG_PROTO_PIM)
+ json_object_boolean_true_add(
+ json_ifp_out, "protocolPim");
+
+ if (c_oil->oif_flags[oif_vif_index]
+ & PIM_OIF_FLAG_PROTO_IGMP)
+ json_object_boolean_true_add(
+ json_ifp_out, "protocolIgmp");
+
+ if (c_oil->oif_flags[oif_vif_index]
+ & PIM_OIF_FLAG_PROTO_SOURCE)
+ json_object_boolean_true_add(
+ json_ifp_out, "protocolSource");
+
+ if (c_oil->oif_flags[oif_vif_index]
+ & PIM_OIF_FLAG_PROTO_STAR)
+ json_object_boolean_true_add(
+ json_ifp_out,
+ "protocolInherited");
+
+ json_object_string_add(json_ifp_out,
+ "inboundInterface",
+ in_ifname);
+ json_object_int_add(json_ifp_out, "iVifI",
+ c_oil->oil.mfcc_parent);
+ json_object_string_add(json_ifp_out,
+ "outboundInterface",
+ out_ifname);
+ json_object_int_add(json_ifp_out, "oVifI",
+ oif_vif_index);
+ json_object_int_add(json_ifp_out, "ttl", ttl);
+ json_object_string_add(json_ifp_out, "upTime",
+ oif_uptime);
+ if (!json_oil) {
+ json_oil = json_object_new_object();
+ json_object_object_add(json_source,
+ "oil", json_oil);
+ }
+ json_object_object_add(json_oil, out_ifname,
+ json_ifp_out);
+ } else {
+ if (c_oil->oif_flags[oif_vif_index]
+ & PIM_OIF_FLAG_PROTO_PIM) {
+ strcpy(proto, "PIM");
+ }
+
+ if (c_oil->oif_flags[oif_vif_index]
+ & PIM_OIF_FLAG_PROTO_IGMP) {
+ strcpy(proto, "IGMP");
+ }
+
+ if (c_oil->oif_flags[oif_vif_index]
+ & PIM_OIF_FLAG_PROTO_SOURCE) {
+ strcpy(proto, "SRC");
+ }
+
+ if (c_oil->oif_flags[oif_vif_index]
+ & PIM_OIF_FLAG_PROTO_STAR) {
+ strcpy(proto, "STAR");
+ }
+
+ vty_out(vty,
+ "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
+ src_str, grp_str, proto, in_ifname,
+ out_ifname, ttl, oif_uptime);
+
+ if (first) {
+ src_str[0] = '\0';
+ grp_str[0] = '\0';
+ in_ifname[0] = '\0';
+ first = 0;
+ }
+ }
+ }
+
+ if (!uj && !found_oif) {
+ vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
+ src_str, grp_str, "none", in_ifname, "none", 0,
+ "--:--:--");
+ }
+ }
+
+ /* Print list of static routes */
+ for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
+ first = 1;
+
+ if (!s_route->c_oil.installed)
+ continue;
+
+ pim_inet4_dump("<group?>", s_route->group, grp_str,
+ sizeof(grp_str));
+ pim_inet4_dump("<source?>", s_route->source, src_str,
+ sizeof(src_str));
+ ifp_in = pim_if_find_by_vif_index(s_route->iif);
+ found_oif = 0;
+
+ if (ifp_in)
+ strcpy(in_ifname, ifp_in->name);
+ else
+ strcpy(in_ifname, "<iif?>");
+
+ if (uj) {
+
+ /* Find the group, create it if it doesn't exist */
+ json_object_object_get_ex(json, grp_str, &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str,
+ json_group);
+ }
+
+ /* Find the source nested under the group, create it if
+ * it doesn't exist */
+ json_object_object_get_ex(json_group, src_str,
+ &json_source);
+
+ if (!json_source) {
+ json_source = json_object_new_object();
+ json_object_object_add(json_group, src_str,
+ json_source);
+ }
+
+ json_object_string_add(json_source, "iif", in_ifname);
+ json_oil = NULL;
+ } else {
+ strcpy(proto, "STATIC");
+ }
+
+ for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
+ ++oif_vif_index) {
+ struct interface *ifp_out;
+ char oif_uptime[10];
+ int ttl;
+
+ ttl = s_route->oif_ttls[oif_vif_index];
+ if (ttl < 1)
+ continue;
+
+ ifp_out = pim_if_find_by_vif_index(oif_vif_index);
+ pim_time_uptime(
+ oif_uptime, sizeof(oif_uptime),
+ now
+ - s_route->c_oil
+ .oif_creation[oif_vif_index]);
+ found_oif = 1;
+
+ if (ifp_out)
+ strcpy(out_ifname, ifp_out->name);
+ else
+ strcpy(out_ifname, "<oif?>");
+
+ if (uj) {
+ json_ifp_out = json_object_new_object();
+ json_object_string_add(json_ifp_out, "source",
+ src_str);
+ json_object_string_add(json_ifp_out, "group",
+ grp_str);
+ json_object_boolean_true_add(json_ifp_out,
+ "protocolStatic");
+ json_object_string_add(json_ifp_out,
+ "inboundInterface",
+ in_ifname);
+ json_object_int_add(
+ json_ifp_out, "iVifI",
+ s_route->c_oil.oil.mfcc_parent);
+ json_object_string_add(json_ifp_out,
+ "outboundInterface",
+ out_ifname);
+ json_object_int_add(json_ifp_out, "oVifI",
+ oif_vif_index);
+ json_object_int_add(json_ifp_out, "ttl", ttl);
+ json_object_string_add(json_ifp_out, "upTime",
+ oif_uptime);
+ if (!json_oil) {
+ json_oil = json_object_new_object();
+ json_object_object_add(json_source,
+ "oil", json_oil);
+ }
+ json_object_object_add(json_oil, out_ifname,
+ json_ifp_out);
+ } else {
+ vty_out(vty,
+ "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
+ src_str, grp_str, proto, in_ifname,
+ out_ifname, ttl, oif_uptime);
+ if (first) {
+ src_str[0] = '\0';
+ grp_str[0] = '\0';
+ in_ifname[0] = '\0';
+ first = 0;
+ }
+ }
+ }
+
+ if (!uj && !found_oif) {
+ vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d %8s\n",
+ src_str, grp_str, proto, in_ifname, "none", 0,
+ "--:--:--");
+ }
+ }
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
}
DEFUN (show_ip_mroute,
@@ -3573,65 +4053,63 @@ DEFUN (show_ip_mroute,
MROUTE_STR
JSON_STR)
{
- u_char uj = use_json(argc, argv);
- show_mroute(vty, uj);
- return CMD_SUCCESS;
+ u_char uj = use_json(argc, argv);
+ show_mroute(vty, uj);
+ return CMD_SUCCESS;
}
static void show_mroute_count(struct vty *vty)
{
- struct listnode *node;
- struct channel_oil *c_oil;
- struct static_route *s_route;
+ struct listnode *node;
+ struct channel_oil *c_oil;
+ struct static_route *s_route;
- vty_out (vty, "\n");
-
- vty_out (vty,
- "Source Group LastUsed Packets Bytes WrongIf \n");
+ vty_out(vty, "\n");
- /* Print PIM and IGMP route counts */
- for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
+ vty_out(vty,
+ "Source Group LastUsed Packets Bytes WrongIf \n");
- if (!c_oil->installed)
- continue;
+ /* Print PIM and IGMP route counts */
+ for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
- pim_mroute_update_counters (c_oil);
+ if (!c_oil->installed)
+ continue;
- pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
+ pim_mroute_update_counters(c_oil);
- vty_out (vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
- source_str,
- group_str,
- c_oil->cc.lastused/100,
- c_oil->cc.pktcnt,
- c_oil->cc.bytecnt,
- c_oil->cc.wrong_if);
- }
+ pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str,
+ sizeof(group_str));
+ pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str,
+ sizeof(source_str));
- /* Print static route counts */
- for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
+ vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
+ source_str, group_str, c_oil->cc.lastused / 100,
+ c_oil->cc.pktcnt, c_oil->cc.bytecnt,
+ c_oil->cc.wrong_if);
+ }
+
+ /* Print static route counts */
+ for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
- if (!s_route->c_oil.installed)
- continue;
+ if (!s_route->c_oil.installed)
+ continue;
- pim_mroute_update_counters (&s_route->c_oil);
+ pim_mroute_update_counters(&s_route->c_oil);
- pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin, source_str, sizeof(source_str));
+ pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp,
+ group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin,
+ source_str, sizeof(source_str));
- vty_out (vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
- source_str,
- group_str,
- s_route->c_oil.cc.lastused,
- s_route->c_oil.cc.pktcnt,
- s_route->c_oil.cc.bytecnt,
- s_route->c_oil.cc.wrong_if);
- }
+ vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n",
+ source_str, group_str, s_route->c_oil.cc.lastused,
+ s_route->c_oil.cc.pktcnt, s_route->c_oil.cc.bytecnt,
+ s_route->c_oil.cc.wrong_if);
+ }
}
DEFUN (show_ip_mroute_count,
@@ -3642,8 +4120,8 @@ DEFUN (show_ip_mroute_count,
MROUTE_STR
"Route and packet count data\n")
{
- show_mroute_count(vty);
- return CMD_SUCCESS;
+ show_mroute_count(vty);
+ return CMD_SUCCESS;
}
DEFUN (show_ip_rib,
@@ -3654,83 +4132,82 @@ DEFUN (show_ip_rib,
RIB_STR
"Unicast address\n")
{
- int idx_ipv4 = 3;
- struct in_addr addr;
- const char *addr_str;
- struct pim_nexthop nexthop;
- char nexthop_addr_str[PREFIX_STRLEN];
- int result;
-
- memset (&nexthop, 0, sizeof (nexthop));
- addr_str = argv[idx_ipv4]->arg;
- result = inet_pton(AF_INET, addr_str, &addr);
- if (result <= 0) {
- vty_out (vty, "Bad unicast address %s: errno=%d: %s\n",
- addr_str, errno, safe_strerror(errno));
- return CMD_WARNING;
- }
+ int idx_ipv4 = 3;
+ struct in_addr addr;
+ const char *addr_str;
+ struct pim_nexthop nexthop;
+ char nexthop_addr_str[PREFIX_STRLEN];
+ int result;
+
+ memset(&nexthop, 0, sizeof(nexthop));
+ addr_str = argv[idx_ipv4]->arg;
+ result = inet_pton(AF_INET, addr_str, &addr);
+ if (result <= 0) {
+ vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
+ errno, safe_strerror(errno));
+ return CMD_WARNING;
+ }
- if (pim_nexthop_lookup(&nexthop, addr, 0)) {
- vty_out (vty, "Failure querying RIB nexthop for unicast address %s\n",
- addr_str);
- return CMD_WARNING;
- }
+ if (pim_nexthop_lookup(&nexthop, addr, 0)) {
+ vty_out(vty,
+ "Failure querying RIB nexthop for unicast address %s\n",
+ addr_str);
+ return CMD_WARNING;
+ }
- vty_out (vty,
- "Address NextHop Interface Metric Preference\n");
+ vty_out(vty,
+ "Address NextHop Interface Metric Preference\n");
- pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
- nexthop_addr_str, sizeof(nexthop_addr_str));
+ pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr,
+ nexthop_addr_str, sizeof(nexthop_addr_str));
- vty_out (vty, "%-15s %-15s %-9s %6d %10d\n",
- addr_str,
- nexthop_addr_str,
- nexthop.interface ? nexthop.interface->name : "<ifname?>",
- nexthop.mrib_route_metric,
- nexthop.mrib_metric_preference);
+ vty_out(vty, "%-15s %-15s %-9s %6d %10d\n", addr_str, nexthop_addr_str,
+ nexthop.interface ? nexthop.interface->name : "<ifname?>",
+ nexthop.mrib_route_metric, nexthop.mrib_metric_preference);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
static void show_ssmpingd(struct vty *vty)
{
- struct listnode *node;
- struct ssmpingd_sock *ss;
- time_t now;
+ struct listnode *node;
+ struct ssmpingd_sock *ss;
+ time_t now;
- vty_out (vty,
- "Source Socket Address Port Uptime Requests\n");
+ vty_out(vty,
+ "Source Socket Address Port Uptime Requests\n");
- if (!qpim_ssmpingd_list)
- return;
+ if (!qpim_ssmpingd_list)
+ return;
- now = pim_time_monotonic_sec();
+ now = pim_time_monotonic_sec();
- for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list, node, ss)) {
- char source_str[INET_ADDRSTRLEN];
- char ss_uptime[10];
- struct sockaddr_in bind_addr;
- socklen_t len = sizeof(bind_addr);
- char bind_addr_str[INET_ADDRSTRLEN];
+ for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list, node, ss)) {
+ char source_str[INET_ADDRSTRLEN];
+ char ss_uptime[10];
+ struct sockaddr_in bind_addr;
+ socklen_t len = sizeof(bind_addr);
+ char bind_addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str));
+ pim_inet4_dump("<src?>", ss->source_addr, source_str,
+ sizeof(source_str));
- if (pim_socket_getsockname(ss->sock_fd, (struct sockaddr *) &bind_addr, &len)) {
- vty_out (vty, "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
- source_str, ss->sock_fd);
- }
+ if (pim_socket_getsockname(
+ ss->sock_fd, (struct sockaddr *)&bind_addr, &len)) {
+ vty_out(vty,
+ "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
+ source_str, ss->sock_fd);
+ }
- pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str, sizeof(bind_addr_str));
- pim_time_uptime(ss_uptime, sizeof(ss_uptime), now - ss->creation);
+ pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str,
+ sizeof(bind_addr_str));
+ pim_time_uptime(ss_uptime, sizeof(ss_uptime),
+ now - ss->creation);
- vty_out (vty, "%-15s %6d %-15s %5d %8s %8lld\n",
- source_str,
- ss->sock_fd,
- bind_addr_str,
- ntohs(bind_addr.sin_port),
- ss_uptime,
- (long long)ss->requests);
- }
+ vty_out(vty, "%-15s %6d %-15s %5d %8s %8lld\n", source_str,
+ ss->sock_fd, bind_addr_str, ntohs(bind_addr.sin_port),
+ ss_uptime, (long long)ss->requests);
+ }
}
DEFUN (show_ip_ssmpingd,
@@ -3740,89 +4217,82 @@ DEFUN (show_ip_ssmpingd,
IP_STR
SHOW_SSMPINGD_STR)
{
- show_ssmpingd(vty);
- return CMD_SUCCESS;
+ show_ssmpingd(vty);
+ return CMD_SUCCESS;
}
-static int
-pim_rp_cmd_worker (struct vty *vty, const char *rp, const char *group, const char *plist)
+static int pim_rp_cmd_worker(struct vty *vty, const char *rp, const char *group,
+ const char *plist)
{
- int result;
+ int result;
- result = pim_rp_new (rp, group, plist);
+ result = pim_rp_new(rp, group, plist);
- if (result == PIM_MALLOC_FAIL)
- {
- vty_out (vty, "%% Out of memory\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (result == PIM_MALLOC_FAIL) {
+ vty_out(vty, "%% Out of memory\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- if (result == PIM_GROUP_BAD_ADDRESS)
- {
- vty_out (vty, "%% Bad group address specified: %s\n", group);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (result == PIM_GROUP_BAD_ADDRESS) {
+ vty_out(vty, "%% Bad group address specified: %s\n", group);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- if (result == PIM_RP_BAD_ADDRESS)
- {
- vty_out (vty, "%% Bad RP address specified: %s\n", rp);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (result == PIM_RP_BAD_ADDRESS) {
+ vty_out(vty, "%% Bad RP address specified: %s\n", rp);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- if (result == PIM_RP_NO_PATH)
- {
- vty_out (vty, "%% No Path to RP address specified: %s\n", rp);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (result == PIM_RP_NO_PATH) {
+ vty_out(vty, "%% No Path to RP address specified: %s\n", rp);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- if (result == PIM_GROUP_OVERLAP)
- {
- vty_out (vty, "%% Group range specified cannot overlap\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (result == PIM_GROUP_OVERLAP) {
+ vty_out(vty, "%% Group range specified cannot overlap\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- if (result == PIM_GROUP_PFXLIST_OVERLAP)
- {
- vty_out (vty,
- "%% This group is already covered by a RP prefix-list\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (result == PIM_GROUP_PFXLIST_OVERLAP) {
+ vty_out(vty,
+ "%% This group is already covered by a RP prefix-list\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- if (result == PIM_RP_PFXLIST_IN_USE)
- {
- vty_out (vty,
- "%% The same prefix-list cannot be applied to multiple RPs\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (result == PIM_RP_PFXLIST_IN_USE) {
+ vty_out(vty,
+ "%% The same prefix-list cannot be applied to multiple RPs\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
-static int
-pim_cmd_spt_switchover (enum pim_spt_switchover spt, const char *plist)
+static int pim_cmd_spt_switchover(enum pim_spt_switchover spt,
+ const char *plist)
{
- pimg->spt.switchover = spt;
+ pimg->spt.switchover = spt;
- switch (pimg->spt.switchover)
- {
- case PIM_SPT_IMMEDIATE:
- if (pimg->spt.plist)
- XFREE (MTYPE_PIM_SPT_PLIST_NAME, pimg->spt.plist);
+ switch (pimg->spt.switchover) {
+ case PIM_SPT_IMMEDIATE:
+ if (pimg->spt.plist)
+ XFREE(MTYPE_PIM_SPT_PLIST_NAME, pimg->spt.plist);
- pim_upstream_add_lhr_star_pimreg ();
- break;
- case PIM_SPT_INFINITY:
- pim_upstream_remove_lhr_star_pimreg (plist);
+ pim_upstream_add_lhr_star_pimreg();
+ break;
+ case PIM_SPT_INFINITY:
+ pim_upstream_remove_lhr_star_pimreg(plist);
- if (pimg->spt.plist)
- XFREE (MTYPE_PIM_SPT_PLIST_NAME, pimg->spt.plist);
+ if (pimg->spt.plist)
+ XFREE(MTYPE_PIM_SPT_PLIST_NAME, pimg->spt.plist);
- if (plist)
- pimg->spt.plist = XSTRDUP (MTYPE_PIM_SPT_PLIST_NAME, plist);
- break;
- }
+ if (plist)
+ pimg->spt.plist =
+ XSTRDUP(MTYPE_PIM_SPT_PLIST_NAME, plist);
+ break;
+ }
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (ip_pim_spt_switchover_infinity,
@@ -3833,7 +4303,7 @@ DEFUN (ip_pim_spt_switchover_infinity,
"SPT-Switchover\n"
"Never switch to SPT Tree\n")
{
- return pim_cmd_spt_switchover (PIM_SPT_INFINITY, NULL);
+ return pim_cmd_spt_switchover(PIM_SPT_INFINITY, NULL);
}
DEFUN (ip_pim_spt_switchover_infinity_plist,
@@ -3846,7 +4316,7 @@ DEFUN (ip_pim_spt_switchover_infinity_plist,
"Prefix-List to control which groups to switch\n"
"Prefix-List name\n")
{
- return pim_cmd_spt_switchover (PIM_SPT_INFINITY, argv[5]->arg);
+ return pim_cmd_spt_switchover(PIM_SPT_INFINITY, argv[5]->arg);
}
DEFUN (no_ip_pim_spt_switchover_infinity,
@@ -3858,7 +4328,7 @@ DEFUN (no_ip_pim_spt_switchover_infinity,
"SPT_Switchover\n"
"Never switch to SPT Tree\n")
{
- return pim_cmd_spt_switchover (PIM_SPT_IMMEDIATE, NULL);
+ return pim_cmd_spt_switchover(PIM_SPT_IMMEDIATE, NULL);
}
DEFUN (no_ip_pim_spt_switchover_infinity_plist,
@@ -3872,7 +4342,7 @@ DEFUN (no_ip_pim_spt_switchover_infinity_plist,
"Prefix-List to control which groups to switch\n"
"Prefix-List name\n")
{
- return pim_cmd_spt_switchover (PIM_SPT_IMMEDIATE, NULL);
+ return pim_cmd_spt_switchover(PIM_SPT_IMMEDIATE, NULL);
}
DEFUN (ip_pim_joinprune_time,
@@ -3883,8 +4353,8 @@ DEFUN (ip_pim_joinprune_time,
"Join Prune Send Interval\n"
"Seconds\n")
{
- qpim_t_periodic = atoi(argv[3]->arg);
- return CMD_SUCCESS;
+ qpim_t_periodic = atoi(argv[3]->arg);
+ return CMD_SUCCESS;
}
DEFUN (no_ip_pim_joinprune_time,
@@ -3896,8 +4366,8 @@ DEFUN (no_ip_pim_joinprune_time,
"Join Prune Send Interval\n"
"Seconds\n")
{
- qpim_t_periodic = PIM_DEFAULT_T_PERIODIC;
- return CMD_SUCCESS;
+ qpim_t_periodic = PIM_DEFAULT_T_PERIODIC;
+ return CMD_SUCCESS;
}
DEFUN (ip_pim_register_suppress,
@@ -3908,8 +4378,8 @@ DEFUN (ip_pim_register_suppress,
"Register Suppress Timer\n"
"Seconds\n")
{
- qpim_register_suppress_time = atoi (argv[3]->arg);
- return CMD_SUCCESS;
+ qpim_register_suppress_time = atoi(argv[3]->arg);
+ return CMD_SUCCESS;
}
DEFUN (no_ip_pim_register_suppress,
@@ -3921,8 +4391,8 @@ DEFUN (no_ip_pim_register_suppress,
"Register Suppress Timer\n"
"Seconds\n")
{
- qpim_register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT;
- return CMD_SUCCESS;
+ qpim_register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT;
+ return CMD_SUCCESS;
}
DEFUN (ip_pim_keep_alive,
@@ -3933,8 +4403,8 @@ DEFUN (ip_pim_keep_alive,
"Keep alive Timer\n"
"Seconds\n")
{
- qpim_keep_alive_time = atoi (argv[3]->arg);
- return CMD_SUCCESS;
+ qpim_keep_alive_time = atoi(argv[3]->arg);
+ return CMD_SUCCESS;
}
DEFUN (no_ip_pim_keep_alive,
@@ -3946,8 +4416,8 @@ DEFUN (no_ip_pim_keep_alive,
"Keep alive Timer\n"
"Seconds\n")
{
- qpim_keep_alive_time = PIM_KEEPALIVE_PERIOD;
- return CMD_SUCCESS;
+ qpim_keep_alive_time = PIM_KEEPALIVE_PERIOD;
+ return CMD_SUCCESS;
}
DEFUN (ip_pim_packets,
@@ -3958,8 +4428,8 @@ DEFUN (ip_pim_packets,
"packets to process at one time per fd\n"
"Number of packets\n")
{
- qpim_packet_process = atoi (argv[3]->arg);
- return CMD_SUCCESS;
+ qpim_packet_process = atoi(argv[3]->arg);
+ return CMD_SUCCESS;
}
DEFUN (no_ip_pim_packets,
@@ -3971,8 +4441,8 @@ DEFUN (no_ip_pim_packets,
"packets to process at one time per fd\n"
"Number of packets\n")
{
- qpim_packet_process = PIM_DEFAULT_PACKET_PROCESS;
- return CMD_SUCCESS;
+ qpim_packet_process = PIM_DEFAULT_PACKET_PROCESS;
+ return CMD_SUCCESS;
}
DEFUN (ip_pim_v6_secondary,
@@ -3982,9 +4452,9 @@ DEFUN (ip_pim_v6_secondary,
"pim multicast routing\n"
"Send v6 secondary addresses\n")
{
- pimg->send_v6_secondary = 1;
+ pimg->send_v6_secondary = 1;
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (no_ip_pim_v6_secondary,
@@ -3995,9 +4465,9 @@ DEFUN (no_ip_pim_v6_secondary,
"pim multicast routing\n"
"Send v6 secondary addresses\n")
{
- pimg->send_v6_secondary = 0;
+ pimg->send_v6_secondary = 0;
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (ip_pim_rp,
@@ -4009,13 +4479,13 @@ DEFUN (ip_pim_rp,
"ip address of RP\n"
"Group Address range to cover\n")
{
- int idx_ipv4 = 3;
-
- if (argc == (idx_ipv4 + 1))
- return pim_rp_cmd_worker (vty, argv[idx_ipv4]->arg, NULL, NULL);
- else
- return pim_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg, NULL);
+ int idx_ipv4 = 3;
+ if (argc == (idx_ipv4 + 1))
+ return pim_rp_cmd_worker(vty, argv[idx_ipv4]->arg, NULL, NULL);
+ else
+ return pim_rp_cmd_worker(vty, argv[idx_ipv4]->arg,
+ argv[idx_ipv4 + 1]->arg, NULL);
}
DEFUN (ip_pim_rp_prefix_list,
@@ -4028,34 +4498,30 @@ DEFUN (ip_pim_rp_prefix_list,
"group prefix-list filter\n"
"Name of a prefix-list\n")
{
- return pim_rp_cmd_worker (vty, argv[3]->arg, NULL, argv[5]->arg);
+ return pim_rp_cmd_worker(vty, argv[3]->arg, NULL, argv[5]->arg);
}
-static int
-pim_no_rp_cmd_worker (struct vty *vty, const char *rp, const char *group,
- const char *plist)
+static int pim_no_rp_cmd_worker(struct vty *vty, const char *rp,
+ const char *group, const char *plist)
{
- int result = pim_rp_del (rp, group, plist);
+ int result = pim_rp_del(rp, group, plist);
- if (result == PIM_GROUP_BAD_ADDRESS)
- {
- vty_out (vty, "%% Bad group address specified: %s\n", group);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (result == PIM_GROUP_BAD_ADDRESS) {
+ vty_out(vty, "%% Bad group address specified: %s\n", group);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- if (result == PIM_RP_BAD_ADDRESS)
- {
- vty_out (vty, "%% Bad RP address specified: %s\n", rp);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (result == PIM_RP_BAD_ADDRESS) {
+ vty_out(vty, "%% Bad RP address specified: %s\n", rp);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- if (result == PIM_RP_NOT_FOUND)
- {
- vty_out (vty, "%% Unable to find specified RP\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (result == PIM_RP_NOT_FOUND) {
+ vty_out(vty, "%% Unable to find specified RP\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (no_ip_pim_rp,
@@ -4068,12 +4534,14 @@ DEFUN (no_ip_pim_rp,
"ip address of RP\n"
"Group Address range to cover\n")
{
- int idx_ipv4 = 4, idx_group = 0;
+ int idx_ipv4 = 4, idx_group = 0;
- if (argv_find (argv, argc, "A.B.C.D/M", &idx_group))
- return pim_no_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_group]->arg, NULL);
- else
- return pim_no_rp_cmd_worker (vty, argv[idx_ipv4]->arg, NULL, NULL);
+ if (argv_find(argv, argc, "A.B.C.D/M", &idx_group))
+ return pim_no_rp_cmd_worker(vty, argv[idx_ipv4]->arg,
+ argv[idx_group]->arg, NULL);
+ else
+ return pim_no_rp_cmd_worker(vty, argv[idx_ipv4]->arg, NULL,
+ NULL);
}
DEFUN (no_ip_pim_rp_prefix_list,
@@ -4087,30 +4555,28 @@ DEFUN (no_ip_pim_rp_prefix_list,
"group prefix-list filter\n"
"Name of a prefix-list\n")
{
- return pim_no_rp_cmd_worker (vty, argv[4]->arg, NULL, argv[6]->arg);
+ return pim_no_rp_cmd_worker(vty, argv[4]->arg, NULL, argv[6]->arg);
}
-static int
-pim_ssm_cmd_worker (struct vty *vty, const char *plist)
+static int pim_ssm_cmd_worker(struct vty *vty, const char *plist)
{
- int result = pim_ssm_range_set (VRF_DEFAULT, plist);
+ int result = pim_ssm_range_set(VRF_DEFAULT, plist);
- if (result == PIM_SSM_ERR_NONE)
- return CMD_SUCCESS;
+ if (result == PIM_SSM_ERR_NONE)
+ return CMD_SUCCESS;
- switch (result)
- {
- case PIM_SSM_ERR_NO_VRF:
- vty_out (vty, "%% VRF doesn't exist\n");
- break;
- case PIM_SSM_ERR_DUP:
- vty_out (vty, "%% duplicate config\n");
- break;
- default:
- vty_out (vty, "%% ssm range config failed\n");
- }
+ switch (result) {
+ case PIM_SSM_ERR_NO_VRF:
+ vty_out(vty, "%% VRF doesn't exist\n");
+ break;
+ case PIM_SSM_ERR_DUP:
+ vty_out(vty, "%% duplicate config\n");
+ break;
+ default:
+ vty_out(vty, "%% ssm range config failed\n");
+ }
- return CMD_WARNING_CONFIG_FAILED;
+ return CMD_WARNING_CONFIG_FAILED;
}
DEFUN (ip_pim_ssm_prefix_list,
@@ -4122,7 +4588,7 @@ DEFUN (ip_pim_ssm_prefix_list,
"group range prefix-list filter\n"
"Name of a prefix-list\n")
{
- return pim_ssm_cmd_worker (vty, argv[0]->arg);
+ return pim_ssm_cmd_worker(vty, argv[0]->arg);
}
DEFUN (no_ip_pim_ssm_prefix_list,
@@ -4134,7 +4600,7 @@ DEFUN (no_ip_pim_ssm_prefix_list,
"Source Specific Multicast\n"
"group range prefix-list filter\n")
{
- return pim_ssm_cmd_worker (vty, NULL);
+ return pim_ssm_cmd_worker(vty, NULL);
}
DEFUN (no_ip_pim_ssm_prefix_list_name,
@@ -4147,34 +4613,31 @@ DEFUN (no_ip_pim_ssm_prefix_list_name,
"group range prefix-list filter\n"
"Name of a prefix-list\n")
{
- struct pim_ssm *ssm = pimg->ssm_info;
+ struct pim_ssm *ssm = pimg->ssm_info;
- if (ssm->plist_name && !strcmp(ssm->plist_name, argv[0]->arg))
- return pim_ssm_cmd_worker (vty, NULL);
+ if (ssm->plist_name && !strcmp(ssm->plist_name, argv[0]->arg))
+ return pim_ssm_cmd_worker(vty, NULL);
- vty_out (vty, "%% pim ssm prefix-list %s doesn't exist\n",
- argv[0]->arg);
+ vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", argv[0]->arg);
- return CMD_WARNING_CONFIG_FAILED;
+ return CMD_WARNING_CONFIG_FAILED;
}
-static void
-ip_pim_ssm_show_group_range(struct vty *vty, u_char uj)
+static void ip_pim_ssm_show_group_range(struct vty *vty, u_char uj)
{
- struct pim_ssm *ssm = pimg->ssm_info;
- const char *range_str = ssm->plist_name?ssm->plist_name:PIM_SSM_STANDARD_RANGE;
+ struct pim_ssm *ssm = pimg->ssm_info;
+ const char *range_str =
+ ssm->plist_name ? ssm->plist_name : PIM_SSM_STANDARD_RANGE;
- if (uj)
- {
- json_object *json;
- json = json_object_new_object();
- json_object_string_add(json, "ssmGroups", range_str);
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
- else
- vty_out (vty, "SSM group range : %s\n", range_str);
+ if (uj) {
+ json_object *json;
+ json = json_object_new_object();
+ json_object_string_add(json, "ssmGroups", range_str);
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ } else
+ vty_out(vty, "SSM group range : %s\n", range_str);
}
DEFUN (show_ip_pim_ssm_range,
@@ -4186,41 +4649,38 @@ DEFUN (show_ip_pim_ssm_range,
"PIM group type\n"
"JavaScript Object Notation\n")
{
- u_char uj = use_json(argc, argv);
- ip_pim_ssm_show_group_range(vty, uj);
+ u_char uj = use_json(argc, argv);
+ ip_pim_ssm_show_group_range(vty, uj);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
-static void
-ip_pim_ssm_show_group_type(struct vty *vty, u_char uj, const char *group)
+static void ip_pim_ssm_show_group_type(struct vty *vty, u_char uj,
+ const char *group)
{
- struct in_addr group_addr;
- const char *type_str;
- int result;
+ struct in_addr group_addr;
+ const char *type_str;
+ int result;
- result = inet_pton(AF_INET, group, &group_addr);
- if (result <= 0)
- type_str = "invalid";
- else
- {
- if (pim_is_group_224_4 (group_addr))
- type_str = pim_is_grp_ssm (group_addr)?"SSM":"ASM";
- else
- type_str = "not-multicast";
- }
+ result = inet_pton(AF_INET, group, &group_addr);
+ if (result <= 0)
+ type_str = "invalid";
+ else {
+ if (pim_is_group_224_4(group_addr))
+ type_str = pim_is_grp_ssm(group_addr) ? "SSM" : "ASM";
+ else
+ type_str = "not-multicast";
+ }
- if (uj)
- {
- json_object *json;
- json = json_object_new_object();
- json_object_string_add(json, "groupType", type_str);
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
- else
- vty_out (vty, "Group type : %s\n", type_str);
+ if (uj) {
+ json_object *json;
+ json = json_object_new_object();
+ json_object_string_add(json, "groupType", type_str);
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ } else
+ vty_out(vty, "Group type : %s\n", type_str);
}
DEFUN (show_ip_pim_group_type,
@@ -4233,10 +4693,10 @@ DEFUN (show_ip_pim_group_type,
"group address\n"
"JavaScript Object Notation\n")
{
- u_char uj = use_json(argc, argv);
- ip_pim_ssm_show_group_type(vty, uj, argv[0]->arg);
+ u_char uj = use_json(argc, argv);
+ ip_pim_ssm_show_group_type(vty, uj, argv[0]->arg);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN_HIDDEN (ip_multicast_routing,
@@ -4245,7 +4705,7 @@ DEFUN_HIDDEN (ip_multicast_routing,
IP_STR
"Enable IP multicast forwarding\n")
{
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN_HIDDEN (no_ip_multicast_routing,
@@ -4255,9 +4715,9 @@ DEFUN_HIDDEN (no_ip_multicast_routing,
IP_STR
"Enable IP multicast forwarding\n")
{
- vty_out (vty,
- "Command is Disabled and will be removed in a future version\n");
- return CMD_SUCCESS;
+ vty_out(vty,
+ "Command is Disabled and will be removed in a future version\n");
+ return CMD_SUCCESS;
}
DEFUN (ip_ssmpingd,
@@ -4267,26 +4727,26 @@ DEFUN (ip_ssmpingd,
CONF_SSMPINGD_STR
"Source address\n")
{
- int idx_ipv4 = 2;
- int result;
- struct in_addr source_addr;
- const char *source_str = (argc == 3) ? argv[idx_ipv4]->arg : "0.0.0.0";
+ int idx_ipv4 = 2;
+ int result;
+ struct in_addr source_addr;
+ const char *source_str = (argc == 3) ? argv[idx_ipv4]->arg : "0.0.0.0";
- result = inet_pton(AF_INET, source_str, &source_addr);
- if (result <= 0) {
- vty_out (vty, "%% Bad source address %s: errno=%d: %s\n",
- source_str, errno, safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
+ result = inet_pton(AF_INET, source_str, &source_addr);
+ if (result <= 0) {
+ vty_out(vty, "%% Bad source address %s: errno=%d: %s\n",
+ source_str, errno, safe_strerror(errno));
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- result = pim_ssmpingd_start(source_addr);
- if (result) {
- vty_out (vty, "%% Failure starting ssmpingd for source %s: %d\n",
- source_str, result);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ result = pim_ssmpingd_start(source_addr);
+ if (result) {
+ vty_out(vty, "%% Failure starting ssmpingd for source %s: %d\n",
+ source_str, result);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (no_ip_ssmpingd,
@@ -4297,26 +4757,26 @@ DEFUN (no_ip_ssmpingd,
CONF_SSMPINGD_STR
"Source address\n")
{
- int idx_ipv4 = 3;
- int result;
- struct in_addr source_addr;
- const char *source_str = (argc == 4) ? argv[idx_ipv4]->arg : "0.0.0.0";
+ int idx_ipv4 = 3;
+ int result;
+ struct in_addr source_addr;
+ const char *source_str = (argc == 4) ? argv[idx_ipv4]->arg : "0.0.0.0";
- result = inet_pton(AF_INET, source_str, &source_addr);
- if (result <= 0) {
- vty_out (vty, "%% Bad source address %s: errno=%d: %s\n",
- source_str, errno, safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
+ result = inet_pton(AF_INET, source_str, &source_addr);
+ if (result <= 0) {
+ vty_out(vty, "%% Bad source address %s: errno=%d: %s\n",
+ source_str, errno, safe_strerror(errno));
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- result = pim_ssmpingd_stop(source_addr);
- if (result) {
- vty_out (vty, "%% Failure stopping ssmpingd for source %s: %d\n",
- source_str, result);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ result = pim_ssmpingd_stop(source_addr);
+ if (result) {
+ vty_out(vty, "%% Failure stopping ssmpingd for source %s: %d\n",
+ source_str, result);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (ip_pim_ecmp,
@@ -4326,9 +4786,9 @@ DEFUN (ip_pim_ecmp,
"pim multicast routing\n"
"Enable PIM ECMP \n")
{
- qpim_ecmp_enable = 1;
+ qpim_ecmp_enable = 1;
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (no_ip_pim_ecmp,
@@ -4339,9 +4799,9 @@ DEFUN (no_ip_pim_ecmp,
"pim multicast routing\n"
"Disable PIM ECMP \n")
{
- qpim_ecmp_enable = 0;
+ qpim_ecmp_enable = 0;
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (ip_pim_ecmp_rebalance,
@@ -4352,10 +4812,10 @@ DEFUN (ip_pim_ecmp_rebalance,
"Enable PIM ECMP \n"
"Enable PIM ECMP Rebalance\n")
{
- qpim_ecmp_enable = 1;
- qpim_ecmp_rebalance_enable = 1;
+ qpim_ecmp_enable = 1;
+ qpim_ecmp_rebalance_enable = 1;
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (no_ip_pim_ecmp_rebalance,
@@ -4367,48 +4827,41 @@ DEFUN (no_ip_pim_ecmp_rebalance,
"Disable PIM ECMP \n"
"Disable PIM ECMP Rebalance\n")
{
- qpim_ecmp_rebalance_enable = 0;
+ qpim_ecmp_rebalance_enable = 0;
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
-static int
-pim_cmd_igmp_start (struct vty *vty, struct interface *ifp)
+static int pim_cmd_igmp_start(struct vty *vty, struct interface *ifp)
{
- struct pim_interface *pim_ifp;
- uint8_t need_startup = 0;
+ struct pim_interface *pim_ifp;
+ uint8_t need_startup = 0;
- pim_ifp = ifp->info;
+ pim_ifp = ifp->info;
- if (!pim_ifp)
- {
- pim_ifp = pim_if_new(ifp, 1 /* igmp=true */, 0 /* pim=false */);
- if (!pim_ifp)
- {
- vty_out (vty, "Could not enable IGMP on interface %s\n",
- ifp->name);
- return CMD_WARNING_CONFIG_FAILED;
- }
- need_startup = 1;
- }
- else
- {
- if (!PIM_IF_TEST_IGMP(pim_ifp->options))
- {
- PIM_IF_DO_IGMP(pim_ifp->options);
- need_startup = 1;
- }
- }
+ if (!pim_ifp) {
+ pim_ifp = pim_if_new(ifp, 1 /* igmp=true */, 0 /* pim=false */);
+ if (!pim_ifp) {
+ vty_out(vty, "Could not enable IGMP on interface %s\n",
+ ifp->name);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ need_startup = 1;
+ } else {
+ if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
+ PIM_IF_DO_IGMP(pim_ifp->options);
+ need_startup = 1;
+ }
+ }
- /* 'ip igmp' executed multiple times, with need_startup
- avoid multiple if add all and membership refresh */
- if (need_startup)
- {
- pim_if_addr_add_all(ifp);
- pim_if_membership_refresh(ifp);
- }
+ /* 'ip igmp' executed multiple times, with need_startup
+ avoid multiple if add all and membership refresh */
+ if (need_startup) {
+ pim_if_addr_add_all(ifp);
+ pim_if_membership_refresh(ifp);
+ }
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (interface_ip_igmp,
@@ -4417,9 +4870,9 @@ DEFUN (interface_ip_igmp,
IP_STR
IFACE_IGMP_STR)
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
+ VTY_DECLVAR_CONTEXT(interface, ifp);
- return pim_cmd_igmp_start(vty, ifp);
+ return pim_cmd_igmp_start(vty, ifp);
}
DEFUN (interface_no_ip_igmp,
@@ -4429,23 +4882,23 @@ DEFUN (interface_no_ip_igmp,
IP_STR
IFACE_IGMP_STR)
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct pim_interface *pim_ifp = ifp->info;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp = ifp->info;
- if (!pim_ifp)
- return CMD_SUCCESS;
+ if (!pim_ifp)
+ return CMD_SUCCESS;
- PIM_IF_DONT_IGMP(pim_ifp->options);
+ PIM_IF_DONT_IGMP(pim_ifp->options);
- pim_if_membership_clear(ifp);
+ pim_if_membership_clear(ifp);
- pim_if_addr_del_all_igmp(ifp);
+ pim_if_addr_del_all_igmp(ifp);
- if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
- pim_if_delete(ifp);
- }
+ if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
+ pim_if_delete(ifp);
+ }
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (interface_ip_igmp_join,
@@ -4457,41 +4910,42 @@ DEFUN (interface_ip_igmp_join,
"Multicast group address\n"
"Source address\n")
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- int idx_ipv4 = 3;
- int idx_ipv4_2 = 4;
- const char *group_str;
- const char *source_str;
- struct in_addr group_addr;
- struct in_addr source_addr;
- int result;
-
- /* Group address */
- group_str = argv[idx_ipv4]->arg;
- result = inet_pton(AF_INET, group_str, &group_addr);
- if (result <= 0) {
- vty_out (vty, "Bad group address %s: errno=%d: %s\n",
- group_str, errno, safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- /* Source address */
- source_str = argv[idx_ipv4_2]->arg;
- result = inet_pton(AF_INET, source_str, &source_addr);
- if (result <= 0) {
- vty_out (vty, "Bad source address %s: errno=%d: %s\n",
- source_str, errno, safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- result = pim_if_igmp_join_add(ifp, group_addr, source_addr);
- if (result) {
- vty_out (vty, "%% Failure joining IGMP group %s source %s on interface %s: %d\n",
- group_str, source_str, ifp->name, result);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_ipv4 = 3;
+ int idx_ipv4_2 = 4;
+ const char *group_str;
+ const char *source_str;
+ struct in_addr group_addr;
+ struct in_addr source_addr;
+ int result;
+
+ /* Group address */
+ group_str = argv[idx_ipv4]->arg;
+ result = inet_pton(AF_INET, group_str, &group_addr);
+ if (result <= 0) {
+ vty_out(vty, "Bad group address %s: errno=%d: %s\n", group_str,
+ errno, safe_strerror(errno));
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ /* Source address */
+ source_str = argv[idx_ipv4_2]->arg;
+ result = inet_pton(AF_INET, source_str, &source_addr);
+ if (result <= 0) {
+ vty_out(vty, "Bad source address %s: errno=%d: %s\n",
+ source_str, errno, safe_strerror(errno));
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ result = pim_if_igmp_join_add(ifp, group_addr, source_addr);
+ if (result) {
+ vty_out(vty,
+ "%% Failure joining IGMP group %s source %s on interface %s: %d\n",
+ group_str, source_str, ifp->name, result);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return CMD_SUCCESS;
}
DEFUN (interface_no_ip_igmp_join,
@@ -4504,41 +4958,42 @@ DEFUN (interface_no_ip_igmp_join,
"Multicast group address\n"
"Source address\n")
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- int idx_ipv4 = 4;
- int idx_ipv4_2 = 5;
- const char *group_str;
- const char *source_str;
- struct in_addr group_addr;
- struct in_addr source_addr;
- int result;
-
- /* Group address */
- group_str = argv[idx_ipv4]->arg;
- result = inet_pton(AF_INET, group_str, &group_addr);
- if (result <= 0) {
- vty_out (vty, "Bad group address %s: errno=%d: %s\n",
- group_str, errno, safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- /* Source address */
- source_str = argv[idx_ipv4_2]->arg;
- result = inet_pton(AF_INET, source_str, &source_addr);
- if (result <= 0) {
- vty_out (vty, "Bad source address %s: errno=%d: %s\n",
- source_str, errno, safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- result = pim_if_igmp_join_del(ifp, group_addr, source_addr);
- if (result) {
- vty_out (vty, "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
- group_str, source_str, ifp->name, result);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_ipv4 = 4;
+ int idx_ipv4_2 = 5;
+ const char *group_str;
+ const char *source_str;
+ struct in_addr group_addr;
+ struct in_addr source_addr;
+ int result;
+
+ /* Group address */
+ group_str = argv[idx_ipv4]->arg;
+ result = inet_pton(AF_INET, group_str, &group_addr);
+ if (result <= 0) {
+ vty_out(vty, "Bad group address %s: errno=%d: %s\n", group_str,
+ errno, safe_strerror(errno));
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ /* Source address */
+ source_str = argv[idx_ipv4_2]->arg;
+ result = inet_pton(AF_INET, source_str, &source_addr);
+ if (result <= 0) {
+ vty_out(vty, "Bad source address %s: errno=%d: %s\n",
+ source_str, errno, safe_strerror(errno));
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ result = pim_if_igmp_join_del(ifp, group_addr, source_addr);
+ if (result) {
+ vty_out(vty,
+ "%% Failure leaving IGMP group %s source %s on interface %s: %d\n",
+ group_str, source_str, ifp->name, result);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return CMD_SUCCESS;
}
/*
@@ -4548,125 +5003,127 @@ DEFUN (interface_no_ip_igmp_join,
*/
static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
{
- struct interface *ifp;
- struct pim_interface *pim_ifp;
+ struct interface *ifp;
+ struct pim_interface *pim_ifp;
- zassert(igmp);
+ zassert(igmp);
- /* other querier present? */
+ /* other querier present? */
- if (igmp->t_other_querier_timer)
- return;
+ if (igmp->t_other_querier_timer)
+ return;
- /* this is the querier */
+ /* this is the querier */
- zassert(igmp->interface);
- zassert(igmp->interface->info);
+ zassert(igmp->interface);
+ zassert(igmp->interface->info);
- ifp = igmp->interface;
- pim_ifp = ifp->info;
+ ifp = igmp->interface;
+ pim_ifp = ifp->info;
- if (PIM_DEBUG_IGMP_TRACE) {
- char ifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
- zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
- __PRETTY_FUNCTION__,
- ifaddr_str,
- ifp->name,
- pim_ifp->igmp_default_query_interval);
- }
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char ifaddr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
+ sizeof(ifaddr_str));
+ zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
+ __PRETTY_FUNCTION__, ifaddr_str, ifp->name,
+ pim_ifp->igmp_default_query_interval);
+ }
- /*
- igmp_startup_mode_on() will reset QQI:
+ /*
+ igmp_startup_mode_on() will reset QQI:
- igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
- */
- igmp_startup_mode_on(igmp);
+ igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
+ */
+ igmp_startup_mode_on(igmp);
}
static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
{
- if (igmp->t_igmp_query_timer) {
- /* other querier present */
- zassert(igmp->t_igmp_query_timer);
- zassert(!igmp->t_other_querier_timer);
+ if (igmp->t_igmp_query_timer) {
+ /* other querier present */
+ zassert(igmp->t_igmp_query_timer);
+ zassert(!igmp->t_other_querier_timer);
- pim_igmp_general_query_off(igmp);
- pim_igmp_general_query_on(igmp);
+ pim_igmp_general_query_off(igmp);
+ pim_igmp_general_query_on(igmp);
- zassert(igmp->t_igmp_query_timer);
- zassert(!igmp->t_other_querier_timer);
- }
- else {
- /* this is the querier */
+ zassert(igmp->t_igmp_query_timer);
+ zassert(!igmp->t_other_querier_timer);
+ } else {
+ /* this is the querier */
- zassert(!igmp->t_igmp_query_timer);
- zassert(igmp->t_other_querier_timer);
+ zassert(!igmp->t_igmp_query_timer);
+ zassert(igmp->t_other_querier_timer);
- pim_igmp_other_querier_timer_off(igmp);
- pim_igmp_other_querier_timer_on(igmp);
+ pim_igmp_other_querier_timer_off(igmp);
+ pim_igmp_other_querier_timer_on(igmp);
- zassert(!igmp->t_igmp_query_timer);
- zassert(igmp->t_other_querier_timer);
- }
+ zassert(!igmp->t_igmp_query_timer);
+ zassert(igmp->t_other_querier_timer);
+ }
}
static void change_query_interval(struct pim_interface *pim_ifp,
int query_interval)
{
- struct listnode *sock_node;
- struct igmp_sock *igmp;
+ struct listnode *sock_node;
+ struct igmp_sock *igmp;
- pim_ifp->igmp_default_query_interval = query_interval;
+ pim_ifp->igmp_default_query_interval = query_interval;
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
- igmp_sock_query_interval_reconfig(igmp);
- igmp_sock_query_reschedule(igmp);
- }
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
+ igmp_sock_query_interval_reconfig(igmp);
+ igmp_sock_query_reschedule(igmp);
+ }
}
static void change_query_max_response_time(struct pim_interface *pim_ifp,
int query_max_response_time_dsec)
{
- struct listnode *sock_node;
- struct igmp_sock *igmp;
-
- pim_ifp->igmp_query_max_response_time_dsec = query_max_response_time_dsec;
-
- /*
- Below we modify socket/group/source timers in order to quickly
- reflect the change. Otherwise, those timers would eventually catch
- up.
- */
-
- /* scan all sockets */
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
- struct listnode *grp_node;
- struct igmp_group *grp;
-
- /* reschedule socket general query */
- igmp_sock_query_reschedule(igmp);
-
- /* scan socket groups */
- for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node, grp)) {
- struct listnode *src_node;
- struct igmp_source *src;
-
- /* reset group timers for groups in EXCLUDE mode */
- if (grp->group_filtermode_isexcl) {
- igmp_group_reset_gmi(grp);
- }
-
- /* scan group sources */
- for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
-
- /* reset source timers for sources with running timers */
- if (src->t_source_timer) {
- igmp_source_reset_gmi(igmp, grp, src);
+ struct listnode *sock_node;
+ struct igmp_sock *igmp;
+
+ pim_ifp->igmp_query_max_response_time_dsec =
+ query_max_response_time_dsec;
+
+ /*
+ Below we modify socket/group/source timers in order to quickly
+ reflect the change. Otherwise, those timers would eventually catch
+ up.
+ */
+
+ /* scan all sockets */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
+ struct listnode *grp_node;
+ struct igmp_group *grp;
+
+ /* reschedule socket general query */
+ igmp_sock_query_reschedule(igmp);
+
+ /* scan socket groups */
+ for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node,
+ grp)) {
+ struct listnode *src_node;
+ struct igmp_source *src;
+
+ /* reset group timers for groups in EXCLUDE mode */
+ if (grp->group_filtermode_isexcl) {
+ igmp_group_reset_gmi(grp);
+ }
+
+ /* scan group sources */
+ for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
+ src_node, src)) {
+
+ /* reset source timers for sources with running
+ * timers */
+ if (src->t_source_timer) {
+ igmp_source_reset_gmi(igmp, grp, src);
+ }
+ }
+ }
}
- }
- }
- }
}
#define IGMP_QUERY_INTERVAL_MIN (1)
@@ -4680,49 +5137,50 @@ DEFUN (interface_ip_igmp_query_interval,
IFACE_IGMP_QUERY_INTERVAL_STR
"Query interval in seconds\n")
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct pim_interface *pim_ifp = ifp->info;
- int query_interval;
- int query_interval_dsec;
- int ret;
-
- if (!pim_ifp) {
- ret = pim_cmd_igmp_start(vty, ifp);
- if (ret != CMD_SUCCESS)
- return ret;
- pim_ifp = ifp->info;
- }
-
- query_interval = atoi(argv[3]->arg);
- query_interval_dsec = 10 * query_interval;
-
- /*
- It seems we don't need to check bounds since command.c does it
- already, but we verify them anyway for extra safety.
- */
- if (query_interval < IGMP_QUERY_INTERVAL_MIN) {
- vty_out (vty, "General query interval %d lower than minimum %d\n",
- query_interval,
- IGMP_QUERY_INTERVAL_MIN);
- return CMD_WARNING_CONFIG_FAILED;
- }
- if (query_interval > IGMP_QUERY_INTERVAL_MAX) {
- vty_out (vty, "General query interval %d higher than maximum %d\n",
- query_interval,
- IGMP_QUERY_INTERVAL_MAX);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
- vty_out (vty,
- "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
- query_interval_dsec,pim_ifp->igmp_query_max_response_time_dsec);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- change_query_interval(pim_ifp, query_interval);
-
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp = ifp->info;
+ int query_interval;
+ int query_interval_dsec;
+ int ret;
+
+ if (!pim_ifp) {
+ ret = pim_cmd_igmp_start(vty, ifp);
+ if (ret != CMD_SUCCESS)
+ return ret;
+ pim_ifp = ifp->info;
+ }
+
+ query_interval = atoi(argv[3]->arg);
+ query_interval_dsec = 10 * query_interval;
+
+ /*
+ It seems we don't need to check bounds since command.c does it
+ already, but we verify them anyway for extra safety.
+ */
+ if (query_interval < IGMP_QUERY_INTERVAL_MIN) {
+ vty_out(vty,
+ "General query interval %d lower than minimum %d\n",
+ query_interval, IGMP_QUERY_INTERVAL_MIN);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ if (query_interval > IGMP_QUERY_INTERVAL_MAX) {
+ vty_out(vty,
+ "General query interval %d higher than maximum %d\n",
+ query_interval, IGMP_QUERY_INTERVAL_MAX);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ if (query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
+ vty_out(vty,
+ "Can't set general query interval %d dsec <= query max response time %d dsec.\n",
+ query_interval_dsec,
+ pim_ifp->igmp_query_max_response_time_dsec);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ change_query_interval(pim_ifp, query_interval);
+
+ return CMD_SUCCESS;
}
DEFUN (interface_no_ip_igmp_query_interval,
@@ -4733,26 +5191,27 @@ DEFUN (interface_no_ip_igmp_query_interval,
IFACE_IGMP_STR
IFACE_IGMP_QUERY_INTERVAL_STR)
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct pim_interface *pim_ifp = ifp->info;
- int default_query_interval_dsec;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp = ifp->info;
+ int default_query_interval_dsec;
- if (!pim_ifp)
- return CMD_SUCCESS;
+ if (!pim_ifp)
+ return CMD_SUCCESS;
- default_query_interval_dsec = IGMP_GENERAL_QUERY_INTERVAL * 10;
+ default_query_interval_dsec = IGMP_GENERAL_QUERY_INTERVAL * 10;
- if (default_query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
- vty_out (vty,
- "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
- default_query_interval_dsec,
- pim_ifp->igmp_query_max_response_time_dsec);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (default_query_interval_dsec
+ <= pim_ifp->igmp_query_max_response_time_dsec) {
+ vty_out(vty,
+ "Can't set default general query interval %d dsec <= query max response time %d dsec.\n",
+ default_query_interval_dsec,
+ pim_ifp->igmp_query_max_response_time_dsec);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- change_query_interval(pim_ifp, IGMP_GENERAL_QUERY_INTERVAL);
+ change_query_interval(pim_ifp, IGMP_GENERAL_QUERY_INTERVAL);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (interface_ip_igmp_version,
@@ -4763,37 +5222,36 @@ DEFUN (interface_ip_igmp_version,
"IGMP version\n"
"IGMP version number\n")
{
- VTY_DECLVAR_CONTEXT(interface,ifp);
- struct pim_interface *pim_ifp = ifp->info;
- int igmp_version, old_version = 0;
- int ret;
-
- if (!pim_ifp)
- {
- ret = pim_cmd_igmp_start(vty, ifp);
- if (ret != CMD_SUCCESS)
- return ret;
- pim_ifp = ifp->info;
- }
-
- igmp_version = atoi(argv[3]->arg);
- old_version = pim_ifp->igmp_version;
- pim_ifp->igmp_version = igmp_version;
-
- //Check if IGMP is Enabled otherwise, enable on interface
- if (!PIM_IF_TEST_IGMP (pim_ifp->options))
- {
- PIM_IF_DO_IGMP(pim_ifp->options);
- pim_if_addr_add_all(ifp);
- pim_if_membership_refresh(ifp);
- old_version = igmp_version; //avoid refreshing membership again.
- }
- /* Current and new version is different refresh existing
- membership. Going from 3 -> 2 or 2 -> 3. */
- if (old_version != igmp_version)
- pim_if_membership_refresh(ifp);
-
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp = ifp->info;
+ int igmp_version, old_version = 0;
+ int ret;
+
+ if (!pim_ifp) {
+ ret = pim_cmd_igmp_start(vty, ifp);
+ if (ret != CMD_SUCCESS)
+ return ret;
+ pim_ifp = ifp->info;
+ }
+
+ igmp_version = atoi(argv[3]->arg);
+ old_version = pim_ifp->igmp_version;
+ pim_ifp->igmp_version = igmp_version;
+
+ // Check if IGMP is Enabled otherwise, enable on interface
+ if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
+ PIM_IF_DO_IGMP(pim_ifp->options);
+ pim_if_addr_add_all(ifp);
+ pim_if_membership_refresh(ifp);
+ old_version = igmp_version; // avoid refreshing membership
+ // again.
+ }
+ /* Current and new version is different refresh existing
+ membership. Going from 3 -> 2 or 2 -> 3. */
+ if (old_version != igmp_version)
+ pim_if_membership_refresh(ifp);
+
+ return CMD_SUCCESS;
}
DEFUN (interface_no_ip_igmp_version,
@@ -4805,15 +5263,15 @@ DEFUN (interface_no_ip_igmp_version,
"IGMP version\n"
"IGMP version number\n")
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct pim_interface *pim_ifp = ifp->info;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp = ifp->info;
- if (!pim_ifp)
- return CMD_SUCCESS;
+ if (!pim_ifp)
+ return CMD_SUCCESS;
- pim_ifp->igmp_version = IGMP_DEFAULT_VERSION;
+ pim_ifp->igmp_version = IGMP_DEFAULT_VERSION;
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
@@ -4827,30 +5285,32 @@ DEFUN (interface_ip_igmp_query_max_response_time,
IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
"Query response value in deci-seconds\n")
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct pim_interface *pim_ifp = ifp->info;
- int query_max_response_time;
- int ret;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp = ifp->info;
+ int query_max_response_time;
+ int ret;
- if (!pim_ifp) {
- ret = pim_cmd_igmp_start(vty, ifp);
- if (ret != CMD_SUCCESS)
- return ret;
- pim_ifp = ifp->info;
- }
+ if (!pim_ifp) {
+ ret = pim_cmd_igmp_start(vty, ifp);
+ if (ret != CMD_SUCCESS)
+ return ret;
+ pim_ifp = ifp->info;
+ }
- query_max_response_time = atoi(argv[3]->arg);
+ query_max_response_time = atoi(argv[3]->arg);
- if (query_max_response_time >= pim_ifp->igmp_default_query_interval * 10) {
- vty_out (vty,
- "Can't set query max response time %d sec >= general query interval %d sec\n",
- query_max_response_time,pim_ifp->igmp_default_query_interval);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (query_max_response_time
+ >= pim_ifp->igmp_default_query_interval * 10) {
+ vty_out(vty,
+ "Can't set query max response time %d sec >= general query interval %d sec\n",
+ query_max_response_time,
+ pim_ifp->igmp_default_query_interval);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- change_query_max_response_time(pim_ifp, query_max_response_time);
+ change_query_max_response_time(pim_ifp, query_max_response_time);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (interface_no_ip_igmp_query_max_response_time,
@@ -4862,15 +5322,16 @@ DEFUN (interface_no_ip_igmp_query_max_response_time,
IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
"Time for response in deci-seconds\n")
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct pim_interface *pim_ifp = ifp->info;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp = ifp->info;
- if (!pim_ifp)
- return CMD_SUCCESS;
+ if (!pim_ifp)
+ return CMD_SUCCESS;
- change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
+ change_query_max_response_time(pim_ifp,
+ IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
#define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
@@ -4884,33 +5345,34 @@ DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
"Query response value in deciseconds\n")
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct pim_interface *pim_ifp = ifp->info;
- int query_max_response_time_dsec;
- int default_query_interval_dsec;
- int ret;
-
- if (!pim_ifp) {
- ret = pim_cmd_igmp_start(vty, ifp);
- if (ret != CMD_SUCCESS)
- return ret;
- pim_ifp = ifp->info;
- }
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp = ifp->info;
+ int query_max_response_time_dsec;
+ int default_query_interval_dsec;
+ int ret;
+
+ if (!pim_ifp) {
+ ret = pim_cmd_igmp_start(vty, ifp);
+ if (ret != CMD_SUCCESS)
+ return ret;
+ pim_ifp = ifp->info;
+ }
- query_max_response_time_dsec = atoi(argv[4]->arg);
+ query_max_response_time_dsec = atoi(argv[4]->arg);
- default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
+ default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
- if (query_max_response_time_dsec >= default_query_interval_dsec) {
- vty_out (vty,
- "Can't set query max response time %d dsec >= general query interval %d dsec\n",
- query_max_response_time_dsec,default_query_interval_dsec);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (query_max_response_time_dsec >= default_query_interval_dsec) {
+ vty_out(vty,
+ "Can't set query max response time %d dsec >= general query interval %d dsec\n",
+ query_max_response_time_dsec,
+ default_query_interval_dsec);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- change_query_max_response_time(pim_ifp, query_max_response_time_dsec);
+ change_query_max_response_time(pim_ifp, query_max_response_time_dsec);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec,
@@ -4921,15 +5383,16 @@ DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec,
IFACE_IGMP_STR
IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct pim_interface *pim_ifp = ifp->info;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp = ifp->info;
- if (!pim_ifp)
- return CMD_SUCCESS;
+ if (!pim_ifp)
+ return CMD_SUCCESS;
- change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
+ change_query_max_response_time(pim_ifp,
+ IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (interface_ip_pim_drprio,
@@ -4940,26 +5403,26 @@ DEFUN (interface_ip_pim_drprio,
"Set the Designated Router Election Priority\n"
"Value of the new DR Priority\n")
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- int idx_number = 3;
- struct pim_interface *pim_ifp = ifp->info;
- uint32_t old_dr_prio;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_number = 3;
+ struct pim_interface *pim_ifp = ifp->info;
+ uint32_t old_dr_prio;
- if (!pim_ifp) {
- vty_out (vty, "Please enable PIM on interface, first\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (!pim_ifp) {
+ vty_out(vty, "Please enable PIM on interface, first\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- old_dr_prio = pim_ifp->pim_dr_priority;
+ old_dr_prio = pim_ifp->pim_dr_priority;
- pim_ifp->pim_dr_priority = strtol(argv[idx_number]->arg, NULL, 10);
+ pim_ifp->pim_dr_priority = strtol(argv[idx_number]->arg, NULL, 10);
- if (old_dr_prio != pim_ifp->pim_dr_priority) {
- if (pim_if_dr_election(ifp))
- pim_hello_restart_now(ifp);
- }
+ if (old_dr_prio != pim_ifp->pim_dr_priority) {
+ if (pim_if_dr_election(ifp))
+ pim_hello_restart_now(ifp);
+ }
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (interface_no_ip_pim_drprio,
@@ -4971,41 +5434,39 @@ DEFUN (interface_no_ip_pim_drprio,
"Revert the Designated Router Priority to default\n"
"Old Value of the Priority\n")
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct pim_interface *pim_ifp = ifp->info;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp = ifp->info;
- if (!pim_ifp) {
- vty_out (vty, "Pim not enabled on this interface\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (!pim_ifp) {
+ vty_out(vty, "Pim not enabled on this interface\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
- pim_ifp->pim_dr_priority = PIM_DEFAULT_DR_PRIORITY;
- if (pim_if_dr_election(ifp))
- pim_hello_restart_now(ifp);
- }
+ if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
+ pim_ifp->pim_dr_priority = PIM_DEFAULT_DR_PRIORITY;
+ if (pim_if_dr_election(ifp))
+ pim_hello_restart_now(ifp);
+ }
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
-static int
-pim_cmd_interface_add (struct interface *ifp)
+static int pim_cmd_interface_add(struct interface *ifp)
{
- struct pim_interface *pim_ifp = ifp->info;
+ struct pim_interface *pim_ifp = ifp->info;
- if (!pim_ifp) {
- pim_ifp = pim_if_new(ifp, 0 /* igmp=false */, 1 /* pim=true */);
- if (!pim_ifp) {
- return 0;
- }
- }
- else {
- PIM_IF_DO_PIM(pim_ifp->options);
- }
+ if (!pim_ifp) {
+ pim_ifp = pim_if_new(ifp, 0 /* igmp=false */, 1 /* pim=true */);
+ if (!pim_ifp) {
+ return 0;
+ }
+ } else {
+ PIM_IF_DO_PIM(pim_ifp->options);
+ }
- pim_if_addr_add_all(ifp);
- pim_if_membership_refresh(ifp);
- return 1;
+ pim_if_addr_add_all(ifp);
+ pim_if_membership_refresh(ifp);
+ return 1;
}
DEFUN_HIDDEN (interface_ip_pim_ssm,
@@ -5015,16 +5476,17 @@ DEFUN_HIDDEN (interface_ip_pim_ssm,
PIM_STR
IFACE_PIM_STR)
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
+ VTY_DECLVAR_CONTEXT(interface, ifp);
- if (!pim_cmd_interface_add(ifp)) {
- vty_out (vty, "Could not enable PIM SM on interface\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (!pim_cmd_interface_add(ifp)) {
+ vty_out(vty, "Could not enable PIM SM on interface\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- vty_out(vty, "WARN: Enabled PIM SM on interface; configure PIM SSM "
- "range if needed\n");
- return CMD_SUCCESS;
+ vty_out(vty,
+ "WARN: Enabled PIM SM on interface; configure PIM SSM "
+ "range if needed\n");
+ return CMD_SUCCESS;
}
DEFUN (interface_ip_pim_sm,
@@ -5034,41 +5496,40 @@ DEFUN (interface_ip_pim_sm,
PIM_STR
IFACE_PIM_SM_STR)
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- if (!pim_cmd_interface_add(ifp)) {
- vty_out (vty, "Could not enable PIM SM on interface\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ if (!pim_cmd_interface_add(ifp)) {
+ vty_out(vty, "Could not enable PIM SM on interface\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- pim_if_create_pimreg();
+ pim_if_create_pimreg();
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
-static int
-pim_cmd_interface_delete (struct interface *ifp)
+static int pim_cmd_interface_delete(struct interface *ifp)
{
- struct pim_interface *pim_ifp = ifp->info;
+ struct pim_interface *pim_ifp = ifp->info;
- if (!pim_ifp)
- return 1;
+ if (!pim_ifp)
+ return 1;
- PIM_IF_DONT_PIM(pim_ifp->options);
+ PIM_IF_DONT_PIM(pim_ifp->options);
- pim_if_membership_clear(ifp);
+ pim_if_membership_clear(ifp);
- /*
- pim_sock_delete() removes all neighbors from
- pim_ifp->pim_neighbor_list.
- */
- pim_sock_delete(ifp, "pim unconfigured on interface");
+ /*
+ pim_sock_delete() removes all neighbors from
+ pim_ifp->pim_neighbor_list.
+ */
+ pim_sock_delete(ifp, "pim unconfigured on interface");
- if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
- pim_if_addr_del_all(ifp);
- pim_if_delete(ifp);
- }
+ if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
+ pim_if_addr_del_all(ifp);
+ pim_if_delete(ifp);
+ }
- return 1;
+ return 1;
}
DEFUN_HIDDEN (interface_no_ip_pim_ssm,
@@ -5079,13 +5540,13 @@ DEFUN_HIDDEN (interface_no_ip_pim_ssm,
PIM_STR
IFACE_PIM_STR)
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- if (!pim_cmd_interface_delete(ifp)) {
- vty_out (vty, "Unable to delete interface information\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ if (!pim_cmd_interface_delete(ifp)) {
+ vty_out(vty, "Unable to delete interface information\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (interface_no_ip_pim_sm,
@@ -5096,13 +5557,13 @@ DEFUN (interface_no_ip_pim_sm,
PIM_STR
IFACE_PIM_SM_STR)
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- if (!pim_cmd_interface_delete(ifp)) {
- vty_out (vty, "Unable to delete interface information\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ if (!pim_cmd_interface_delete(ifp)) {
+ vty_out(vty, "Unable to delete interface information\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (interface_ip_mroute,
@@ -5113,40 +5574,39 @@ DEFUN (interface_ip_mroute,
"Outgoing interface name\n"
"Group address\n")
{
- VTY_DECLVAR_CONTEXT(interface, iif);
- int idx_interface = 2;
- int idx_ipv4 = 3;
- struct interface *oif;
- const char *oifname;
- const char *grp_str;
- struct in_addr grp_addr;
- struct in_addr src_addr;
- int result;
-
- oifname = argv[idx_interface]->arg;
- oif = if_lookup_by_name(oifname, VRF_DEFAULT);
- if (!oif) {
- vty_out (vty, "No such interface name %s\n",
- oifname);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- grp_str = argv[idx_ipv4]->arg;
- result = inet_pton(AF_INET, grp_str, &grp_addr);
- if (result <= 0) {
- vty_out (vty, "Bad group address %s: errno=%d: %s\n",
- grp_str, errno, safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- src_addr.s_addr = INADDR_ANY;
-
- if (pim_static_add(iif, oif, grp_addr, src_addr)) {
- vty_out (vty, "Failed to add route\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(interface, iif);
+ int idx_interface = 2;
+ int idx_ipv4 = 3;
+ struct interface *oif;
+ const char *oifname;
+ const char *grp_str;
+ struct in_addr grp_addr;
+ struct in_addr src_addr;
+ int result;
+
+ oifname = argv[idx_interface]->arg;
+ oif = if_lookup_by_name(oifname, VRF_DEFAULT);
+ if (!oif) {
+ vty_out(vty, "No such interface name %s\n", oifname);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ grp_str = argv[idx_ipv4]->arg;
+ result = inet_pton(AF_INET, grp_str, &grp_addr);
+ if (result <= 0) {
+ vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
+ errno, safe_strerror(errno));
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ src_addr.s_addr = INADDR_ANY;
+
+ if (pim_static_add(iif, oif, grp_addr, src_addr)) {
+ vty_out(vty, "Failed to add route\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return CMD_SUCCESS;
}
DEFUN (interface_ip_mroute_source,
@@ -5158,48 +5618,47 @@ DEFUN (interface_ip_mroute_source,
"Group address\n"
"Source address\n")
{
- VTY_DECLVAR_CONTEXT(interface, iif);
- int idx_interface = 2;
- int idx_ipv4 = 3;
- int idx_ipv4_2 = 4;
- struct interface *oif;
- const char *oifname;
- const char *grp_str;
- struct in_addr grp_addr;
- const char *src_str;
- struct in_addr src_addr;
- int result;
-
- oifname = argv[idx_interface]->arg;
- oif = if_lookup_by_name(oifname, VRF_DEFAULT);
- if (!oif) {
- vty_out (vty, "No such interface name %s\n",
- oifname);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- grp_str = argv[idx_ipv4]->arg;
- result = inet_pton(AF_INET, grp_str, &grp_addr);
- if (result <= 0) {
- vty_out (vty, "Bad group address %s: errno=%d: %s\n",
- grp_str, errno, safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- src_str = argv[idx_ipv4_2]->arg;
- result = inet_pton(AF_INET, src_str, &src_addr);
- if (result <= 0) {
- vty_out (vty, "Bad source address %s: errno=%d: %s\n",
- src_str, errno, safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (pim_static_add(iif, oif, grp_addr, src_addr)) {
- vty_out (vty, "Failed to add route\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(interface, iif);
+ int idx_interface = 2;
+ int idx_ipv4 = 3;
+ int idx_ipv4_2 = 4;
+ struct interface *oif;
+ const char *oifname;
+ const char *grp_str;
+ struct in_addr grp_addr;
+ const char *src_str;
+ struct in_addr src_addr;
+ int result;
+
+ oifname = argv[idx_interface]->arg;
+ oif = if_lookup_by_name(oifname, VRF_DEFAULT);
+ if (!oif) {
+ vty_out(vty, "No such interface name %s\n", oifname);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ grp_str = argv[idx_ipv4]->arg;
+ result = inet_pton(AF_INET, grp_str, &grp_addr);
+ if (result <= 0) {
+ vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
+ errno, safe_strerror(errno));
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ src_str = argv[idx_ipv4_2]->arg;
+ result = inet_pton(AF_INET, src_str, &src_addr);
+ if (result <= 0) {
+ vty_out(vty, "Bad source address %s: errno=%d: %s\n", src_str,
+ errno, safe_strerror(errno));
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ if (pim_static_add(iif, oif, grp_addr, src_addr)) {
+ vty_out(vty, "Failed to add route\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return CMD_SUCCESS;
}
DEFUN (interface_no_ip_mroute,
@@ -5211,40 +5670,39 @@ DEFUN (interface_no_ip_mroute,
"Outgoing interface name\n"
"Group Address\n")
{
- VTY_DECLVAR_CONTEXT(interface, iif);
- int idx_interface = 3;
- int idx_ipv4 = 4;
- struct interface *oif;
- const char *oifname;
- const char *grp_str;
- struct in_addr grp_addr;
- struct in_addr src_addr;
- int result;
-
- oifname = argv[idx_interface]->arg;
- oif = if_lookup_by_name(oifname, VRF_DEFAULT);
- if (!oif) {
- vty_out (vty, "No such interface name %s\n",
- oifname);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- grp_str = argv[idx_ipv4]->arg;
- result = inet_pton(AF_INET, grp_str, &grp_addr);
- if (result <= 0) {
- vty_out (vty, "Bad group address %s: errno=%d: %s\n",
- grp_str, errno, safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- src_addr.s_addr = INADDR_ANY;
-
- if (pim_static_del(iif, oif, grp_addr, src_addr)) {
- vty_out (vty, "Failed to remove route\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(interface, iif);
+ int idx_interface = 3;
+ int idx_ipv4 = 4;
+ struct interface *oif;
+ const char *oifname;
+ const char *grp_str;
+ struct in_addr grp_addr;
+ struct in_addr src_addr;
+ int result;
+
+ oifname = argv[idx_interface]->arg;
+ oif = if_lookup_by_name(oifname, VRF_DEFAULT);
+ if (!oif) {
+ vty_out(vty, "No such interface name %s\n", oifname);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ grp_str = argv[idx_ipv4]->arg;
+ result = inet_pton(AF_INET, grp_str, &grp_addr);
+ if (result <= 0) {
+ vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
+ errno, safe_strerror(errno));
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ src_addr.s_addr = INADDR_ANY;
+
+ if (pim_static_del(iif, oif, grp_addr, src_addr)) {
+ vty_out(vty, "Failed to remove route\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return CMD_SUCCESS;
}
DEFUN (interface_no_ip_mroute_source,
@@ -5257,48 +5715,47 @@ DEFUN (interface_no_ip_mroute_source,
"Group Address\n"
"Source Address\n")
{
- VTY_DECLVAR_CONTEXT(interface, iif);
- int idx_interface = 3;
- int idx_ipv4 = 4;
- int idx_ipv4_2 = 5;
- struct interface *oif;
- const char *oifname;
- const char *grp_str;
- struct in_addr grp_addr;
- const char *src_str;
- struct in_addr src_addr;
- int result;
-
- oifname = argv[idx_interface]->arg;
- oif = if_lookup_by_name(oifname, VRF_DEFAULT);
- if (!oif) {
- vty_out (vty, "No such interface name %s\n",
- oifname);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- grp_str = argv[idx_ipv4]->arg;
- result = inet_pton(AF_INET, grp_str, &grp_addr);
- if (result <= 0) {
- vty_out (vty, "Bad group address %s: errno=%d: %s\n",
- grp_str, errno, safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- src_str = argv[idx_ipv4_2]->arg;
- result = inet_pton(AF_INET, src_str, &src_addr);
- if (result <= 0) {
- vty_out (vty, "Bad source address %s: errno=%d: %s\n",
- src_str, errno, safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (pim_static_del(iif, oif, grp_addr, src_addr)) {
- vty_out (vty, "Failed to remove route\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(interface, iif);
+ int idx_interface = 3;
+ int idx_ipv4 = 4;
+ int idx_ipv4_2 = 5;
+ struct interface *oif;
+ const char *oifname;
+ const char *grp_str;
+ struct in_addr grp_addr;
+ const char *src_str;
+ struct in_addr src_addr;
+ int result;
+
+ oifname = argv[idx_interface]->arg;
+ oif = if_lookup_by_name(oifname, VRF_DEFAULT);
+ if (!oif) {
+ vty_out(vty, "No such interface name %s\n", oifname);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ grp_str = argv[idx_ipv4]->arg;
+ result = inet_pton(AF_INET, grp_str, &grp_addr);
+ if (result <= 0) {
+ vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
+ errno, safe_strerror(errno));
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ src_str = argv[idx_ipv4_2]->arg;
+ result = inet_pton(AF_INET, src_str, &src_addr);
+ if (result <= 0) {
+ vty_out(vty, "Bad source address %s: errno=%d: %s\n", src_str,
+ errno, safe_strerror(errno));
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ if (pim_static_del(iif, oif, grp_addr, src_addr)) {
+ vty_out(vty, "Failed to remove route\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return CMD_SUCCESS;
}
DEFUN (interface_ip_pim_hello,
@@ -5310,31 +5767,29 @@ DEFUN (interface_ip_pim_hello,
IFACE_PIM_HELLO_TIME_STR
IFACE_PIM_HELLO_HOLD_STR)
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- int idx_time = 3;
- int idx_hold = 4;
- struct pim_interface *pim_ifp = ifp->info;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_time = 3;
+ int idx_hold = 4;
+ struct pim_interface *pim_ifp = ifp->info;
- if (!pim_ifp)
- {
- if (!pim_cmd_interface_add(ifp))
- {
- vty_out (vty, "Could not enable PIM SM on interface\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- }
+ if (!pim_ifp) {
+ if (!pim_cmd_interface_add(ifp)) {
+ vty_out(vty, "Could not enable PIM SM on interface\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ }
- pim_ifp = ifp->info;
- pim_ifp->pim_hello_period = strtol(argv[idx_time]->arg, NULL, 10);
+ pim_ifp = ifp->info;
+ pim_ifp->pim_hello_period = strtol(argv[idx_time]->arg, NULL, 10);
- if (argc == idx_hold + 1)
- pim_ifp->pim_default_holdtime = strtol(argv[idx_hold]->arg, NULL, 10);
+ if (argc == idx_hold + 1)
+ pim_ifp->pim_default_holdtime =
+ strtol(argv[idx_hold]->arg, NULL, 10);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
-
DEFUN (interface_no_ip_pim_hello,
interface_no_ip_pim_hello_cmd,
"no ip pim hello [(1-180) (1-180)]",
@@ -5345,18 +5800,18 @@ DEFUN (interface_no_ip_pim_hello,
IFACE_PIM_HELLO_TIME_STR
IFACE_PIM_HELLO_HOLD_STR)
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct pim_interface *pim_ifp = ifp->info;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp = ifp->info;
- if (!pim_ifp) {
- vty_out (vty, "Pim not enabled on this interface\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (!pim_ifp) {
+ vty_out(vty, "Pim not enabled on this interface\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- pim_ifp->pim_hello_period = PIM_DEFAULT_HELLO_PERIOD;
- pim_ifp->pim_default_holdtime = -1;
+ pim_ifp->pim_hello_period = PIM_DEFAULT_HELLO_PERIOD;
+ pim_ifp->pim_default_holdtime = -1;
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (debug_igmp,
@@ -5365,10 +5820,10 @@ DEFUN (debug_igmp,
DEBUG_STR
DEBUG_IGMP_STR)
{
- PIM_DO_DEBUG_IGMP_EVENTS;
- PIM_DO_DEBUG_IGMP_PACKETS;
- PIM_DO_DEBUG_IGMP_TRACE;
- return CMD_SUCCESS;
+ PIM_DO_DEBUG_IGMP_EVENTS;
+ PIM_DO_DEBUG_IGMP_PACKETS;
+ PIM_DO_DEBUG_IGMP_TRACE;
+ return CMD_SUCCESS;
}
DEFUN (no_debug_igmp,
@@ -5378,10 +5833,10 @@ DEFUN (no_debug_igmp,
DEBUG_STR
DEBUG_IGMP_STR)
{
- PIM_DONT_DEBUG_IGMP_EVENTS;
- PIM_DONT_DEBUG_IGMP_PACKETS;
- PIM_DONT_DEBUG_IGMP_TRACE;
- return CMD_SUCCESS;
+ PIM_DONT_DEBUG_IGMP_EVENTS;
+ PIM_DONT_DEBUG_IGMP_PACKETS;
+ PIM_DONT_DEBUG_IGMP_TRACE;
+ return CMD_SUCCESS;
}
@@ -5392,8 +5847,8 @@ DEFUN (debug_igmp_events,
DEBUG_IGMP_STR
DEBUG_IGMP_EVENTS_STR)
{
- PIM_DO_DEBUG_IGMP_EVENTS;
- return CMD_SUCCESS;
+ PIM_DO_DEBUG_IGMP_EVENTS;
+ return CMD_SUCCESS;
}
DEFUN (no_debug_igmp_events,
@@ -5404,8 +5859,8 @@ DEFUN (no_debug_igmp_events,
DEBUG_IGMP_STR
DEBUG_IGMP_EVENTS_STR)
{
- PIM_DONT_DEBUG_IGMP_EVENTS;
- return CMD_SUCCESS;
+ PIM_DONT_DEBUG_IGMP_EVENTS;
+ return CMD_SUCCESS;
}
@@ -5416,8 +5871,8 @@ DEFUN (debug_igmp_packets,
DEBUG_IGMP_STR
DEBUG_IGMP_PACKETS_STR)
{
- PIM_DO_DEBUG_IGMP_PACKETS;
- return CMD_SUCCESS;
+ PIM_DO_DEBUG_IGMP_PACKETS;
+ return CMD_SUCCESS;
}
DEFUN (no_debug_igmp_packets,
@@ -5428,8 +5883,8 @@ DEFUN (no_debug_igmp_packets,
DEBUG_IGMP_STR
DEBUG_IGMP_PACKETS_STR)
{
- PIM_DONT_DEBUG_IGMP_PACKETS;
- return CMD_SUCCESS;
+ PIM_DONT_DEBUG_IGMP_PACKETS;
+ return CMD_SUCCESS;
}
@@ -5440,8 +5895,8 @@ DEFUN (debug_igmp_trace,
DEBUG_IGMP_STR
DEBUG_IGMP_TRACE_STR)
{
- PIM_DO_DEBUG_IGMP_TRACE;
- return CMD_SUCCESS;
+ PIM_DO_DEBUG_IGMP_TRACE;
+ return CMD_SUCCESS;
}
DEFUN (no_debug_igmp_trace,
@@ -5452,8 +5907,8 @@ DEFUN (no_debug_igmp_trace,
DEBUG_IGMP_STR
DEBUG_IGMP_TRACE_STR)
{
- PIM_DONT_DEBUG_IGMP_TRACE;
- return CMD_SUCCESS;
+ PIM_DONT_DEBUG_IGMP_TRACE;
+ return CMD_SUCCESS;
}
@@ -5463,8 +5918,8 @@ DEFUN (debug_mroute,
DEBUG_STR
DEBUG_MROUTE_STR)
{
- PIM_DO_DEBUG_MROUTE;
- return CMD_SUCCESS;
+ PIM_DO_DEBUG_MROUTE;
+ return CMD_SUCCESS;
}
DEFUN (debug_mroute_detail,
@@ -5474,8 +5929,8 @@ DEFUN (debug_mroute_detail,
DEBUG_MROUTE_STR
"detailed\n")
{
- PIM_DO_DEBUG_MROUTE_DETAIL;
- return CMD_SUCCESS;
+ PIM_DO_DEBUG_MROUTE_DETAIL;
+ return CMD_SUCCESS;
}
DEFUN (no_debug_mroute,
@@ -5485,8 +5940,8 @@ DEFUN (no_debug_mroute,
DEBUG_STR
DEBUG_MROUTE_STR)
{
- PIM_DONT_DEBUG_MROUTE;
- return CMD_SUCCESS;
+ PIM_DONT_DEBUG_MROUTE;
+ return CMD_SUCCESS;
}
DEFUN (no_debug_mroute_detail,
@@ -5497,8 +5952,8 @@ DEFUN (no_debug_mroute_detail,
DEBUG_MROUTE_STR
"detailed\n")
{
- PIM_DONT_DEBUG_MROUTE_DETAIL;
- return CMD_SUCCESS;
+ PIM_DONT_DEBUG_MROUTE_DETAIL;
+ return CMD_SUCCESS;
}
DEFUN (debug_static,
@@ -5507,8 +5962,8 @@ DEFUN (debug_static,
DEBUG_STR
DEBUG_STATIC_STR)
{
- PIM_DO_DEBUG_STATIC;
- return CMD_SUCCESS;
+ PIM_DO_DEBUG_STATIC;
+ return CMD_SUCCESS;
}
DEFUN (no_debug_static,
@@ -5518,8 +5973,8 @@ DEFUN (no_debug_static,
DEBUG_STR
DEBUG_STATIC_STR)
{
- PIM_DONT_DEBUG_STATIC;
- return CMD_SUCCESS;
+ PIM_DONT_DEBUG_STATIC;
+ return CMD_SUCCESS;
}
@@ -5529,12 +5984,12 @@ DEFUN (debug_pim,
DEBUG_STR
DEBUG_PIM_STR)
{
- PIM_DO_DEBUG_PIM_EVENTS;
- PIM_DO_DEBUG_PIM_PACKETS;
- PIM_DO_DEBUG_PIM_TRACE;
- PIM_DO_DEBUG_MSDP_EVENTS;
- PIM_DO_DEBUG_MSDP_PACKETS;
- return CMD_SUCCESS;
+ PIM_DO_DEBUG_PIM_EVENTS;
+ PIM_DO_DEBUG_PIM_PACKETS;
+ PIM_DO_DEBUG_PIM_TRACE;
+ PIM_DO_DEBUG_MSDP_EVENTS;
+ PIM_DO_DEBUG_MSDP_PACKETS;
+ return CMD_SUCCESS;
}
DEFUN (no_debug_pim,
@@ -5544,16 +5999,16 @@ DEFUN (no_debug_pim,
DEBUG_STR
DEBUG_PIM_STR)
{
- PIM_DONT_DEBUG_PIM_EVENTS;
- PIM_DONT_DEBUG_PIM_PACKETS;
- PIM_DONT_DEBUG_PIM_TRACE;
- PIM_DONT_DEBUG_MSDP_EVENTS;
- PIM_DONT_DEBUG_MSDP_PACKETS;
+ PIM_DONT_DEBUG_PIM_EVENTS;
+ PIM_DONT_DEBUG_PIM_PACKETS;
+ PIM_DONT_DEBUG_PIM_TRACE;
+ PIM_DONT_DEBUG_MSDP_EVENTS;
+ PIM_DONT_DEBUG_MSDP_PACKETS;
- PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
- PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
+ PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
+ PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
@@ -5564,8 +6019,8 @@ DEFUN (debug_pim_events,
DEBUG_PIM_STR
DEBUG_PIM_EVENTS_STR)
{
- PIM_DO_DEBUG_PIM_EVENTS;
- return CMD_SUCCESS;
+ PIM_DO_DEBUG_PIM_EVENTS;
+ return CMD_SUCCESS;
}
DEFUN (no_debug_pim_events,
@@ -5576,8 +6031,8 @@ DEFUN (no_debug_pim_events,
DEBUG_PIM_STR
DEBUG_PIM_EVENTS_STR)
{
- PIM_DONT_DEBUG_PIM_EVENTS;
- return CMD_SUCCESS;
+ PIM_DONT_DEBUG_PIM_EVENTS;
+ return CMD_SUCCESS;
}
DEFUN (debug_pim_packets,
@@ -5590,28 +6045,21 @@ DEFUN (debug_pim_packets,
DEBUG_PIM_J_P_PACKETS_STR
DEBUG_PIM_PIM_REG_PACKETS_STR)
{
- int idx = 0;
- if (argv_find (argv, argc, "hello", &idx))
- {
- PIM_DO_DEBUG_PIM_HELLO;
- vty_out (vty, "PIM Hello debugging is on\n");
- }
- else if (argv_find (argv, argc ,"joins", &idx))
- {
- PIM_DO_DEBUG_PIM_J_P;
- vty_out (vty, "PIM Join/Prune debugging is on\n");
- }
- else if (argv_find (argv, argc, "register", &idx))
- {
- PIM_DO_DEBUG_PIM_REG;
- vty_out (vty, "PIM Register debugging is on\n");
- }
- else
- {
- PIM_DO_DEBUG_PIM_PACKETS;
- vty_out (vty, "PIM Packet debugging is on \n");
- }
- return CMD_SUCCESS;
+ int idx = 0;
+ if (argv_find(argv, argc, "hello", &idx)) {
+ PIM_DO_DEBUG_PIM_HELLO;
+ vty_out(vty, "PIM Hello debugging is on\n");
+ } else if (argv_find(argv, argc, "joins", &idx)) {
+ PIM_DO_DEBUG_PIM_J_P;
+ vty_out(vty, "PIM Join/Prune debugging is on\n");
+ } else if (argv_find(argv, argc, "register", &idx)) {
+ PIM_DO_DEBUG_PIM_REG;
+ vty_out(vty, "PIM Register debugging is on\n");
+ } else {
+ PIM_DO_DEBUG_PIM_PACKETS;
+ vty_out(vty, "PIM Packet debugging is on \n");
+ }
+ return CMD_SUCCESS;
}
DEFUN (no_debug_pim_packets,
@@ -5625,26 +6073,20 @@ DEFUN (no_debug_pim_packets,
DEBUG_PIM_J_P_PACKETS_STR
DEBUG_PIM_PIM_REG_PACKETS_STR)
{
- int idx = 0;
- if (argv_find (argv, argc,"hello",&idx))
- {
- PIM_DONT_DEBUG_PIM_HELLO;
- vty_out (vty, "PIM Hello debugging is off \n");
- }
- else if (argv_find (argv, argc, "joins", &idx))
- {
- PIM_DONT_DEBUG_PIM_J_P;
- vty_out (vty, "PIM Join/Prune debugging is off \n");
- }
- else if (argv_find (argv, argc, "register", &idx))
- {
- PIM_DONT_DEBUG_PIM_REG;
- vty_out (vty, "PIM Register debugging is off\n");
- }
- else
- PIM_DONT_DEBUG_PIM_PACKETS;
-
- return CMD_SUCCESS;
+ int idx = 0;
+ if (argv_find(argv, argc, "hello", &idx)) {
+ PIM_DONT_DEBUG_PIM_HELLO;
+ vty_out(vty, "PIM Hello debugging is off \n");
+ } else if (argv_find(argv, argc, "joins", &idx)) {
+ PIM_DONT_DEBUG_PIM_J_P;
+ vty_out(vty, "PIM Join/Prune debugging is off \n");
+ } else if (argv_find(argv, argc, "register", &idx)) {
+ PIM_DONT_DEBUG_PIM_REG;
+ vty_out(vty, "PIM Register debugging is off\n");
+ } else
+ PIM_DONT_DEBUG_PIM_PACKETS;
+
+ return CMD_SUCCESS;
}
@@ -5656,8 +6098,8 @@ DEFUN (debug_pim_packetdump_send,
DEBUG_PIM_PACKETDUMP_STR
DEBUG_PIM_PACKETDUMP_SEND_STR)
{
- PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
- return CMD_SUCCESS;
+ PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
+ return CMD_SUCCESS;
}
DEFUN (no_debug_pim_packetdump_send,
@@ -5669,8 +6111,8 @@ DEFUN (no_debug_pim_packetdump_send,
DEBUG_PIM_PACKETDUMP_STR
DEBUG_PIM_PACKETDUMP_SEND_STR)
{
- PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
- return CMD_SUCCESS;
+ PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
+ return CMD_SUCCESS;
}
@@ -5682,8 +6124,8 @@ DEFUN (debug_pim_packetdump_recv,
DEBUG_PIM_PACKETDUMP_STR
DEBUG_PIM_PACKETDUMP_RECV_STR)
{
- PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
- return CMD_SUCCESS;
+ PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
+ return CMD_SUCCESS;
}
DEFUN (no_debug_pim_packetdump_recv,
@@ -5695,8 +6137,8 @@ DEFUN (no_debug_pim_packetdump_recv,
DEBUG_PIM_PACKETDUMP_STR
DEBUG_PIM_PACKETDUMP_RECV_STR)
{
- PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
- return CMD_SUCCESS;
+ PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
+ return CMD_SUCCESS;
}
@@ -5707,8 +6149,8 @@ DEFUN (debug_pim_trace,
DEBUG_PIM_STR
DEBUG_PIM_TRACE_STR)
{
- PIM_DO_DEBUG_PIM_TRACE;
- return CMD_SUCCESS;
+ PIM_DO_DEBUG_PIM_TRACE;
+ return CMD_SUCCESS;
}
DEFUN (no_debug_pim_trace,
@@ -5719,8 +6161,8 @@ DEFUN (no_debug_pim_trace,
DEBUG_PIM_STR
DEBUG_PIM_TRACE_STR)
{
- PIM_DONT_DEBUG_PIM_TRACE;
- return CMD_SUCCESS;
+ PIM_DONT_DEBUG_PIM_TRACE;
+ return CMD_SUCCESS;
}
@@ -5730,8 +6172,8 @@ DEFUN (debug_ssmpingd,
DEBUG_STR
DEBUG_SSMPINGD_STR)
{
- PIM_DO_DEBUG_SSMPINGD;
- return CMD_SUCCESS;
+ PIM_DO_DEBUG_SSMPINGD;
+ return CMD_SUCCESS;
}
DEFUN (no_debug_ssmpingd,
@@ -5741,8 +6183,8 @@ DEFUN (no_debug_ssmpingd,
DEBUG_STR
DEBUG_SSMPINGD_STR)
{
- PIM_DONT_DEBUG_SSMPINGD;
- return CMD_SUCCESS;
+ PIM_DONT_DEBUG_SSMPINGD;
+ return CMD_SUCCESS;
}
@@ -5753,8 +6195,8 @@ DEFUN (debug_pim_zebra,
DEBUG_PIM_STR
DEBUG_PIM_ZEBRA_STR)
{
- PIM_DO_DEBUG_ZEBRA;
- return CMD_SUCCESS;
+ PIM_DO_DEBUG_ZEBRA;
+ return CMD_SUCCESS;
}
DEFUN (no_debug_pim_zebra,
@@ -5765,8 +6207,8 @@ DEFUN (no_debug_pim_zebra,
DEBUG_PIM_STR
DEBUG_PIM_ZEBRA_STR)
{
- PIM_DONT_DEBUG_ZEBRA;
- return CMD_SUCCESS;
+ PIM_DONT_DEBUG_ZEBRA;
+ return CMD_SUCCESS;
}
@@ -5776,9 +6218,9 @@ DEFUN (debug_msdp,
DEBUG_STR
DEBUG_MSDP_STR)
{
- PIM_DO_DEBUG_MSDP_EVENTS;
- PIM_DO_DEBUG_MSDP_PACKETS;
- return CMD_SUCCESS;
+ PIM_DO_DEBUG_MSDP_EVENTS;
+ PIM_DO_DEBUG_MSDP_PACKETS;
+ return CMD_SUCCESS;
}
DEFUN (no_debug_msdp,
@@ -5788,16 +6230,13 @@ DEFUN (no_debug_msdp,
DEBUG_STR
DEBUG_MSDP_STR)
{
- PIM_DONT_DEBUG_MSDP_EVENTS;
- PIM_DONT_DEBUG_MSDP_PACKETS;
- return CMD_SUCCESS;
+ PIM_DONT_DEBUG_MSDP_EVENTS;
+ PIM_DONT_DEBUG_MSDP_PACKETS;
+ return CMD_SUCCESS;
}
-ALIAS (no_debug_msdp,
- undebug_msdp_cmd,
- "undebug msdp",
- UNDEBUG_STR
- DEBUG_MSDP_STR)
+ALIAS(no_debug_msdp, undebug_msdp_cmd, "undebug msdp",
+ UNDEBUG_STR DEBUG_MSDP_STR)
DEFUN (debug_msdp_events,
debug_msdp_events_cmd,
@@ -5806,8 +6245,8 @@ DEFUN (debug_msdp_events,
DEBUG_MSDP_STR
DEBUG_MSDP_EVENTS_STR)
{
- PIM_DO_DEBUG_MSDP_EVENTS;
- return CMD_SUCCESS;
+ PIM_DO_DEBUG_MSDP_EVENTS;
+ return CMD_SUCCESS;
}
DEFUN (no_debug_msdp_events,
@@ -5818,16 +6257,12 @@ DEFUN (no_debug_msdp_events,
DEBUG_MSDP_STR
DEBUG_MSDP_EVENTS_STR)
{
- PIM_DONT_DEBUG_MSDP_EVENTS;
- return CMD_SUCCESS;
+ PIM_DONT_DEBUG_MSDP_EVENTS;
+ return CMD_SUCCESS;
}
-ALIAS (no_debug_msdp_events,
- undebug_msdp_events_cmd,
- "undebug msdp events",
- UNDEBUG_STR
- DEBUG_MSDP_STR
- DEBUG_MSDP_EVENTS_STR)
+ALIAS(no_debug_msdp_events, undebug_msdp_events_cmd, "undebug msdp events",
+ UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_EVENTS_STR)
DEFUN (debug_msdp_packets,
debug_msdp_packets_cmd,
@@ -5836,8 +6271,8 @@ DEFUN (debug_msdp_packets,
DEBUG_MSDP_STR
DEBUG_MSDP_PACKETS_STR)
{
- PIM_DO_DEBUG_MSDP_PACKETS;
- return CMD_SUCCESS;
+ PIM_DO_DEBUG_MSDP_PACKETS;
+ return CMD_SUCCESS;
}
DEFUN (no_debug_msdp_packets,
@@ -5848,16 +6283,12 @@ DEFUN (no_debug_msdp_packets,
DEBUG_MSDP_STR
DEBUG_MSDP_PACKETS_STR)
{
- PIM_DONT_DEBUG_MSDP_PACKETS;
- return CMD_SUCCESS;
+ PIM_DONT_DEBUG_MSDP_PACKETS;
+ return CMD_SUCCESS;
}
-ALIAS (no_debug_msdp_packets,
- undebug_msdp_packets_cmd,
- "undebug msdp packets",
- UNDEBUG_STR
- DEBUG_MSDP_STR
- DEBUG_MSDP_PACKETS_STR)
+ALIAS(no_debug_msdp_packets, undebug_msdp_packets_cmd, "undebug msdp packets",
+ UNDEBUG_STR DEBUG_MSDP_STR DEBUG_MSDP_PACKETS_STR)
DEFUN (show_debugging_pim,
show_debugging_pim_cmd,
@@ -5866,39 +6297,38 @@ DEFUN (show_debugging_pim,
DEBUG_STR
PIM_STR)
{
- pim_debug_config_write(vty);
- return CMD_SUCCESS;
+ pim_debug_config_write(vty);
+ return CMD_SUCCESS;
}
-static int
-interface_pim_use_src_cmd_worker(struct vty *vty, const char *source)
+static int interface_pim_use_src_cmd_worker(struct vty *vty, const char *source)
{
- int result;
- struct in_addr source_addr;
- VTY_DECLVAR_CONTEXT(interface, ifp);
+ int result;
+ struct in_addr source_addr;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
- result = inet_pton(AF_INET, source, &source_addr);
- if (result <= 0) {
- vty_out (vty, "%% Bad source address %s: errno=%d: %s\n",
- source, errno, safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
+ result = inet_pton(AF_INET, source, &source_addr);
+ if (result <= 0) {
+ vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", source,
+ errno, safe_strerror(errno));
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- result = pim_update_source_set(ifp, source_addr);
- switch (result) {
- case PIM_SUCCESS:
- break;
- case PIM_IFACE_NOT_FOUND:
- vty_out (vty, "Pim not enabled on this interface\n");
- break;
- case PIM_UPDATE_SOURCE_DUP:
- vty_out (vty, "%% Source already set to %s\n", source);
- break;
- default:
- vty_out (vty, "%% Source set failed\n");
- }
+ result = pim_update_source_set(ifp, source_addr);
+ switch (result) {
+ case PIM_SUCCESS:
+ break;
+ case PIM_IFACE_NOT_FOUND:
+ vty_out(vty, "Pim not enabled on this interface\n");
+ break;
+ case PIM_UPDATE_SOURCE_DUP:
+ vty_out(vty, "%% Source already set to %s\n", source);
+ break;
+ default:
+ vty_out(vty, "%% Source set failed\n");
+ }
- return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
+ return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
}
DEFUN (interface_pim_use_source,
@@ -5909,7 +6339,7 @@ DEFUN (interface_pim_use_source,
"Configure primary IP address\n"
"source ip address\n")
{
- return interface_pim_use_src_cmd_worker (vty, argv[3]->arg);
+ return interface_pim_use_src_cmd_worker(vty, argv[3]->arg);
}
DEFUN (interface_no_pim_use_source,
@@ -5920,7 +6350,7 @@ DEFUN (interface_no_pim_use_source,
"pim multicast routing\n"
"Delete source IP address\n")
{
- return interface_pim_use_src_cmd_worker (vty, "0.0.0.0");
+ return interface_pim_use_src_cmd_worker(vty, "0.0.0.0");
}
DEFUN (ip_pim_bfd,
@@ -5930,19 +6360,19 @@ DEFUN (ip_pim_bfd,
PIM_STR
"Enables BFD support\n")
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct pim_interface *pim_ifp = ifp->info;
- struct bfd_info *bfd_info = NULL;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp = ifp->info;
+ struct bfd_info *bfd_info = NULL;
- if (!pim_ifp)
- return CMD_SUCCESS;
- bfd_info = pim_ifp->bfd_info;
+ if (!pim_ifp)
+ return CMD_SUCCESS;
+ bfd_info = pim_ifp->bfd_info;
- if (!bfd_info || !CHECK_FLAG (bfd_info->flags, BFD_FLAG_PARAM_CFG))
- pim_bfd_if_param_set (ifp, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
- BFD_DEF_DETECT_MULT, 1);
+ if (!bfd_info || !CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG))
+ pim_bfd_if_param_set(ifp, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
+ BFD_DEF_DETECT_MULT, 1);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (no_ip_pim_bfd,
@@ -5953,19 +6383,18 @@ DEFUN (no_ip_pim_bfd,
PIM_STR
"Disables BFD support\n")
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct pim_interface *pim_ifp = ifp->info;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct pim_interface *pim_ifp = ifp->info;
- if (!pim_ifp)
- return CMD_SUCCESS;
+ if (!pim_ifp)
+ return CMD_SUCCESS;
- if (pim_ifp->bfd_info)
- {
- pim_bfd_reg_dereg_all_nbr (ifp, ZEBRA_BFD_DEST_DEREGISTER);
- bfd_info_free (&(pim_ifp->bfd_info));
- }
+ if (pim_ifp->bfd_info) {
+ pim_bfd_reg_dereg_all_nbr(ifp, ZEBRA_BFD_DEST_DEREGISTER);
+ bfd_info_free(&(pim_ifp->bfd_info));
+ }
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (ip_pim_bfd_param,
@@ -5978,77 +6407,74 @@ DEFUN (ip_pim_bfd_param,
"Required min receive interval\n"
"Desired min transmit interval\n")
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- int idx_number = 3;
- int idx_number_2 = 4;
- int idx_number_3 = 5;
- u_int32_t rx_val;
- u_int32_t tx_val;
- u_int8_t dm_val;
- int ret;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int idx_number = 3;
+ int idx_number_2 = 4;
+ int idx_number_3 = 5;
+ u_int32_t rx_val;
+ u_int32_t tx_val;
+ u_int8_t dm_val;
+ int ret;
- if ((ret = bfd_validate_param (vty, argv[idx_number]->arg,
- argv[idx_number_2]->arg,
- argv[idx_number_3]->arg,
- &dm_val, &rx_val, &tx_val)) != CMD_SUCCESS)
- return ret;
+ if ((ret = bfd_validate_param(
+ vty, argv[idx_number]->arg, argv[idx_number_2]->arg,
+ argv[idx_number_3]->arg, &dm_val, &rx_val, &tx_val))
+ != CMD_SUCCESS)
+ return ret;
- pim_bfd_if_param_set (ifp, rx_val, tx_val, dm_val, 0);
+ pim_bfd_if_param_set(ifp, rx_val, tx_val, dm_val, 0);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
-ALIAS (no_ip_pim_bfd,
- no_ip_pim_bfd_param_cmd,
- "no ip pim bfd (2-255) (50-60000) (50-60000)",
- NO_STR
- IP_STR
- PIM_STR
- "Enables BFD support\n"
- "Detect Multiplier\n"
- "Required min receive interval\n"
- "Desired min transmit interval\n")
+ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd,
+ "no ip pim bfd (2-255) (50-60000) (50-60000)", NO_STR IP_STR PIM_STR
+ "Enables BFD support\n"
+ "Detect Multiplier\n"
+ "Required min receive interval\n"
+ "Desired min transmit interval\n")
+
+static int ip_msdp_peer_cmd_worker(struct vty *vty, const char *peer,
+ const char *local)
+{
+ enum pim_msdp_err result;
+ struct in_addr peer_addr;
+ struct in_addr local_addr;
+
+ result = inet_pton(AF_INET, peer, &peer_addr);
+ if (result <= 0) {
+ vty_out(vty, "%% Bad peer address %s: errno=%d: %s\n", peer,
+ errno, safe_strerror(errno));
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ result = inet_pton(AF_INET, local, &local_addr);
+ if (result <= 0) {
+ vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", local,
+ errno, safe_strerror(errno));
+ return CMD_WARNING_CONFIG_FAILED;
+ }
-static int
-ip_msdp_peer_cmd_worker (struct vty *vty, const char *peer, const char *local)
-{
- enum pim_msdp_err result;
- struct in_addr peer_addr;
- struct in_addr local_addr;
-
- result = inet_pton(AF_INET, peer, &peer_addr);
- if (result <= 0) {
- vty_out (vty, "%% Bad peer address %s: errno=%d: %s\n",
- peer, errno, safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- result = inet_pton(AF_INET, local, &local_addr);
- if (result <= 0) {
- vty_out (vty, "%% Bad source address %s: errno=%d: %s\n",
- local, errno, safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- result = pim_msdp_peer_add(peer_addr, local_addr, "default", NULL/* mp_p */);
- switch (result) {
- case PIM_MSDP_ERR_NONE:
- break;
- case PIM_MSDP_ERR_OOM:
- vty_out (vty, "%% Out of memory\n");
- break;
- case PIM_MSDP_ERR_PEER_EXISTS:
- vty_out (vty, "%% Peer exists\n");
- break;
- case PIM_MSDP_ERR_MAX_MESH_GROUPS:
- vty_out (vty, "%% Only one mesh-group allowed currently\n");
- break;
- default:
- vty_out (vty, "%% peer add failed\n");
- }
-
- return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
+ result = pim_msdp_peer_add(peer_addr, local_addr, "default",
+ NULL /* mp_p */);
+ switch (result) {
+ case PIM_MSDP_ERR_NONE:
+ break;
+ case PIM_MSDP_ERR_OOM:
+ vty_out(vty, "%% Out of memory\n");
+ break;
+ case PIM_MSDP_ERR_PEER_EXISTS:
+ vty_out(vty, "%% Peer exists\n");
+ break;
+ case PIM_MSDP_ERR_MAX_MESH_GROUPS:
+ vty_out(vty, "%% Only one mesh-group allowed currently\n");
+ break;
+ default:
+ vty_out(vty, "%% peer add failed\n");
+ }
+
+ return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
}
DEFUN_HIDDEN (ip_msdp_peer,
@@ -6061,34 +6487,33 @@ DEFUN_HIDDEN (ip_msdp_peer,
"Source address for TCP connection\n"
"local ip address\n")
{
- return ip_msdp_peer_cmd_worker (vty, argv[3]->arg, argv[5]->arg);
+ return ip_msdp_peer_cmd_worker(vty, argv[3]->arg, argv[5]->arg);
}
-static int
-ip_no_msdp_peer_cmd_worker (struct vty *vty, const char *peer)
+static int ip_no_msdp_peer_cmd_worker(struct vty *vty, const char *peer)
{
- enum pim_msdp_err result;
- struct in_addr peer_addr;
+ enum pim_msdp_err result;
+ struct in_addr peer_addr;
- result = inet_pton(AF_INET, peer, &peer_addr);
- if (result <= 0) {
- vty_out (vty, "%% Bad peer address %s: errno=%d: %s\n",
- peer, errno, safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
+ result = inet_pton(AF_INET, peer, &peer_addr);
+ if (result <= 0) {
+ vty_out(vty, "%% Bad peer address %s: errno=%d: %s\n", peer,
+ errno, safe_strerror(errno));
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- result = pim_msdp_peer_del(peer_addr);
- switch (result) {
- case PIM_MSDP_ERR_NONE:
- break;
- case PIM_MSDP_ERR_NO_PEER:
- vty_out (vty, "%% Peer does not exist\n");
- break;
- default:
- vty_out (vty, "%% peer del failed\n");
- }
+ result = pim_msdp_peer_del(peer_addr);
+ switch (result) {
+ case PIM_MSDP_ERR_NONE:
+ break;
+ case PIM_MSDP_ERR_NO_PEER:
+ vty_out(vty, "%% Peer does not exist\n");
+ break;
+ default:
+ vty_out(vty, "%% peer del failed\n");
+ }
- return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
+ return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
}
DEFUN_HIDDEN (no_ip_msdp_peer,
@@ -6100,40 +6525,40 @@ DEFUN_HIDDEN (no_ip_msdp_peer,
"Delete MSDP peer\n"
"peer ip address\n")
{
- return ip_no_msdp_peer_cmd_worker (vty, argv[4]->arg);
+ return ip_no_msdp_peer_cmd_worker(vty, argv[4]->arg);
}
-static int
-ip_msdp_mesh_group_member_cmd_worker(struct vty *vty, const char *mg, const char *mbr)
+static int ip_msdp_mesh_group_member_cmd_worker(struct vty *vty, const char *mg,
+ const char *mbr)
{
- enum pim_msdp_err result;
- struct in_addr mbr_ip;
+ enum pim_msdp_err result;
+ struct in_addr mbr_ip;
- result = inet_pton(AF_INET, mbr, &mbr_ip);
- if (result <= 0) {
- vty_out (vty, "%% Bad member address %s: errno=%d: %s\n",
- mbr, errno, safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
+ result = inet_pton(AF_INET, mbr, &mbr_ip);
+ if (result <= 0) {
+ vty_out(vty, "%% Bad member address %s: errno=%d: %s\n", mbr,
+ errno, safe_strerror(errno));
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- result = pim_msdp_mg_mbr_add(mg, mbr_ip);
- switch (result) {
- case PIM_MSDP_ERR_NONE:
- break;
- case PIM_MSDP_ERR_OOM:
- vty_out (vty, "%% Out of memory\n");
- break;
- case PIM_MSDP_ERR_MG_MBR_EXISTS:
- vty_out (vty, "%% mesh-group member exists\n");
- break;
- case PIM_MSDP_ERR_MAX_MESH_GROUPS:
- vty_out (vty, "%% Only one mesh-group allowed currently\n");
- break;
- default:
- vty_out (vty, "%% member add failed\n");
- }
+ result = pim_msdp_mg_mbr_add(mg, mbr_ip);
+ switch (result) {
+ case PIM_MSDP_ERR_NONE:
+ break;
+ case PIM_MSDP_ERR_OOM:
+ vty_out(vty, "%% Out of memory\n");
+ break;
+ case PIM_MSDP_ERR_MG_MBR_EXISTS:
+ vty_out(vty, "%% mesh-group member exists\n");
+ break;
+ case PIM_MSDP_ERR_MAX_MESH_GROUPS:
+ vty_out(vty, "%% Only one mesh-group allowed currently\n");
+ break;
+ default:
+ vty_out(vty, "%% member add failed\n");
+ }
- return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
+ return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
}
DEFUN (ip_msdp_mesh_group_member,
@@ -6146,37 +6571,39 @@ DEFUN (ip_msdp_mesh_group_member,
"mesh group member\n"
"peer ip address\n")
{
- return ip_msdp_mesh_group_member_cmd_worker(vty, argv[3]->arg, argv[5]->arg);
+ return ip_msdp_mesh_group_member_cmd_worker(vty, argv[3]->arg,
+ argv[5]->arg);
}
-static int
-ip_no_msdp_mesh_group_member_cmd_worker(struct vty *vty, const char *mg, const char *mbr)
+static int ip_no_msdp_mesh_group_member_cmd_worker(struct vty *vty,
+ const char *mg,
+ const char *mbr)
{
- enum pim_msdp_err result;
- struct in_addr mbr_ip;
+ enum pim_msdp_err result;
+ struct in_addr mbr_ip;
- result = inet_pton(AF_INET, mbr, &mbr_ip);
- if (result <= 0) {
- vty_out (vty, "%% Bad member address %s: errno=%d: %s\n",
- mbr, errno, safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
+ result = inet_pton(AF_INET, mbr, &mbr_ip);
+ if (result <= 0) {
+ vty_out(vty, "%% Bad member address %s: errno=%d: %s\n", mbr,
+ errno, safe_strerror(errno));
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- result = pim_msdp_mg_mbr_del(mg, mbr_ip);
- switch (result) {
- case PIM_MSDP_ERR_NONE:
- break;
- case PIM_MSDP_ERR_NO_MG:
- vty_out (vty, "%% mesh-group does not exist\n");
- break;
- case PIM_MSDP_ERR_NO_MG_MBR:
- vty_out (vty, "%% mesh-group member does not exist\n");
- break;
- default:
- vty_out (vty, "%% mesh-group member del failed\n");
- }
+ result = pim_msdp_mg_mbr_del(mg, mbr_ip);
+ switch (result) {
+ case PIM_MSDP_ERR_NONE:
+ break;
+ case PIM_MSDP_ERR_NO_MG:
+ vty_out(vty, "%% mesh-group does not exist\n");
+ break;
+ case PIM_MSDP_ERR_NO_MG_MBR:
+ vty_out(vty, "%% mesh-group member does not exist\n");
+ break;
+ default:
+ vty_out(vty, "%% mesh-group member del failed\n");
+ }
- return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
+ return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
}
DEFUN (no_ip_msdp_mesh_group_member,
no_ip_msdp_mesh_group_member_cmd,
@@ -6189,37 +6616,38 @@ DEFUN (no_ip_msdp_mesh_group_member,
"mesh group member\n"
"peer ip address\n")
{
- return ip_no_msdp_mesh_group_member_cmd_worker(vty, argv[4]->arg, argv[6]->arg);
+ return ip_no_msdp_mesh_group_member_cmd_worker(vty, argv[4]->arg,
+ argv[6]->arg);
}
-static int
-ip_msdp_mesh_group_source_cmd_worker(struct vty *vty, const char *mg, const char *src)
+static int ip_msdp_mesh_group_source_cmd_worker(struct vty *vty, const char *mg,
+ const char *src)
{
- enum pim_msdp_err result;
- struct in_addr src_ip;
+ enum pim_msdp_err result;
+ struct in_addr src_ip;
- result = inet_pton(AF_INET, src, &src_ip);
- if (result <= 0) {
- vty_out (vty, "%% Bad source address %s: errno=%d: %s\n",
- src, errno, safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
+ result = inet_pton(AF_INET, src, &src_ip);
+ if (result <= 0) {
+ vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", src,
+ errno, safe_strerror(errno));
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- result = pim_msdp_mg_src_add(mg, src_ip);
- switch (result) {
- case PIM_MSDP_ERR_NONE:
- break;
- case PIM_MSDP_ERR_OOM:
- vty_out (vty, "%% Out of memory\n");
- break;
- case PIM_MSDP_ERR_MAX_MESH_GROUPS:
- vty_out (vty, "%% Only one mesh-group allowed currently\n");
- break;
- default:
- vty_out (vty, "%% source add failed\n");
- }
+ result = pim_msdp_mg_src_add(mg, src_ip);
+ switch (result) {
+ case PIM_MSDP_ERR_NONE:
+ break;
+ case PIM_MSDP_ERR_OOM:
+ vty_out(vty, "%% Out of memory\n");
+ break;
+ case PIM_MSDP_ERR_MAX_MESH_GROUPS:
+ vty_out(vty, "%% Only one mesh-group allowed currently\n");
+ break;
+ default:
+ vty_out(vty, "%% source add failed\n");
+ }
- return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
+ return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
}
@@ -6233,45 +6661,45 @@ DEFUN (ip_msdp_mesh_group_source,
"mesh group local address\n"
"source ip address for the TCP connection\n")
{
- return ip_msdp_mesh_group_source_cmd_worker(vty, argv[3]->arg, argv[5]->arg);
+ return ip_msdp_mesh_group_source_cmd_worker(vty, argv[3]->arg,
+ argv[5]->arg);
}
-static int
-ip_no_msdp_mesh_group_source_cmd_worker(struct vty *vty, const char *mg)
+static int ip_no_msdp_mesh_group_source_cmd_worker(struct vty *vty,
+ const char *mg)
{
- enum pim_msdp_err result;
+ enum pim_msdp_err result;
- result = pim_msdp_mg_src_del(mg);
- switch (result) {
- case PIM_MSDP_ERR_NONE:
- break;
- case PIM_MSDP_ERR_NO_MG:
- vty_out (vty, "%% mesh-group does not exist\n");
- break;
- default:
- vty_out (vty, "%% mesh-group source del failed\n");
- }
+ result = pim_msdp_mg_src_del(mg);
+ switch (result) {
+ case PIM_MSDP_ERR_NONE:
+ break;
+ case PIM_MSDP_ERR_NO_MG:
+ vty_out(vty, "%% mesh-group does not exist\n");
+ break;
+ default:
+ vty_out(vty, "%% mesh-group source del failed\n");
+ }
- return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
+ return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
}
-static int
-ip_no_msdp_mesh_group_cmd_worker(struct vty *vty, const char *mg)
+static int ip_no_msdp_mesh_group_cmd_worker(struct vty *vty, const char *mg)
{
- enum pim_msdp_err result;
+ enum pim_msdp_err result;
- result = pim_msdp_mg_del(mg);
- switch (result) {
- case PIM_MSDP_ERR_NONE:
- break;
- case PIM_MSDP_ERR_NO_MG:
- vty_out (vty, "%% mesh-group does not exist\n");
- break;
- default:
- vty_out (vty, "%% mesh-group source del failed\n");
- }
+ result = pim_msdp_mg_del(mg);
+ switch (result) {
+ case PIM_MSDP_ERR_NONE:
+ break;
+ case PIM_MSDP_ERR_NO_MG:
+ vty_out(vty, "%% mesh-group does not exist\n");
+ break;
+ default:
+ vty_out(vty, "%% mesh-group source del failed\n");
+ }
- return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
+ return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
}
DEFUN (no_ip_msdp_mesh_group_source,
@@ -6285,86 +6713,87 @@ DEFUN (no_ip_msdp_mesh_group_source,
"mesh group source\n"
"mesh group local address\n")
{
- if (argc == 7)
- return ip_no_msdp_mesh_group_cmd_worker(vty, argv[6]->arg);
- else
- return ip_no_msdp_mesh_group_source_cmd_worker(vty, argv[4]->arg);
-}
-
-static void
-print_empty_json_obj(struct vty *vty)
-{
- json_object *json;
- json = json_object_new_object();
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
-}
-
-static void
-ip_msdp_show_mesh_group(struct vty *vty, u_char uj)
-{
- struct listnode *mbrnode;
- struct pim_msdp_mg_mbr *mbr;
- struct pim_msdp_mg *mg = msdp->mg;
- char mbr_str[INET_ADDRSTRLEN];
- char src_str[INET_ADDRSTRLEN];
- char state_str[PIM_MSDP_STATE_STRLEN];
- enum pim_msdp_peer_state state;
- json_object *json = NULL;
- json_object *json_mg_row = NULL;
- json_object *json_members = NULL;
- json_object *json_row = NULL;
-
- if (!mg) {
- if (uj)
- print_empty_json_obj(vty);
- return;
- }
-
- pim_inet4_dump("<source?>", mg->src_ip, src_str, sizeof(src_str));
- if (uj) {
- json = json_object_new_object();
- /* currently there is only one mesh group but we should still make
- * it a dict with mg-name as key */
- json_mg_row = json_object_new_object();
- json_object_string_add(json_mg_row, "name", mg->mesh_group_name);
- json_object_string_add(json_mg_row, "source", src_str);
- } else {
- vty_out (vty, "Mesh group : %s\n", mg->mesh_group_name);
- vty_out (vty, " Source : %s\n", src_str);
- vty_out (vty, " Member State\n");
- }
-
- for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
- pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str, sizeof(mbr_str));
- if (mbr->mp) {
- state = mbr->mp->state;
- } else {
- state = PIM_MSDP_DISABLED;
- }
- pim_msdp_state_dump(state, state_str, sizeof(state_str));
- if (uj) {
- json_row = json_object_new_object();
- json_object_string_add(json_row, "member", mbr_str);
- json_object_string_add(json_row, "state", state_str);
- if (!json_members) {
- json_members = json_object_new_object();
- json_object_object_add(json_mg_row, "members", json_members);
- }
- json_object_object_add(json_members, mbr_str, json_row);
- } else {
- vty_out (vty, " %-15s %11s\n",
- mbr_str, state_str);
- }
- }
-
- if (uj) {
- json_object_object_add(json, mg->mesh_group_name, json_mg_row);
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
+ if (argc == 7)
+ return ip_no_msdp_mesh_group_cmd_worker(vty, argv[6]->arg);
+ else
+ return ip_no_msdp_mesh_group_source_cmd_worker(vty,
+ argv[4]->arg);
+}
+
+static void print_empty_json_obj(struct vty *vty)
+{
+ json_object *json;
+ json = json_object_new_object();
+ vty_out(vty, "%s\n",
+ json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+}
+
+static void ip_msdp_show_mesh_group(struct vty *vty, u_char uj)
+{
+ struct listnode *mbrnode;
+ struct pim_msdp_mg_mbr *mbr;
+ struct pim_msdp_mg *mg = msdp->mg;
+ char mbr_str[INET_ADDRSTRLEN];
+ char src_str[INET_ADDRSTRLEN];
+ char state_str[PIM_MSDP_STATE_STRLEN];
+ enum pim_msdp_peer_state state;
+ json_object *json = NULL;
+ json_object *json_mg_row = NULL;
+ json_object *json_members = NULL;
+ json_object *json_row = NULL;
+
+ if (!mg) {
+ if (uj)
+ print_empty_json_obj(vty);
+ return;
+ }
+
+ pim_inet4_dump("<source?>", mg->src_ip, src_str, sizeof(src_str));
+ if (uj) {
+ json = json_object_new_object();
+ /* currently there is only one mesh group but we should still
+ * make
+ * it a dict with mg-name as key */
+ json_mg_row = json_object_new_object();
+ json_object_string_add(json_mg_row, "name",
+ mg->mesh_group_name);
+ json_object_string_add(json_mg_row, "source", src_str);
+ } else {
+ vty_out(vty, "Mesh group : %s\n", mg->mesh_group_name);
+ vty_out(vty, " Source : %s\n", src_str);
+ vty_out(vty, " Member State\n");
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
+ pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str, sizeof(mbr_str));
+ if (mbr->mp) {
+ state = mbr->mp->state;
+ } else {
+ state = PIM_MSDP_DISABLED;
+ }
+ pim_msdp_state_dump(state, state_str, sizeof(state_str));
+ if (uj) {
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "member", mbr_str);
+ json_object_string_add(json_row, "state", state_str);
+ if (!json_members) {
+ json_members = json_object_new_object();
+ json_object_object_add(json_mg_row, "members",
+ json_members);
+ }
+ json_object_object_add(json_members, mbr_str, json_row);
+ } else {
+ vty_out(vty, " %-15s %11s\n", mbr_str, state_str);
+ }
+ }
+
+ if (uj) {
+ json_object_object_add(json, mg->mesh_group_name, json_mg_row);
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
}
DEFUN (show_ip_msdp_mesh_group,
@@ -6376,151 +6805,168 @@ DEFUN (show_ip_msdp_mesh_group,
"MSDP mesh-group information\n"
"JavaScript Object Notation\n")
{
- u_char uj = use_json(argc, argv);
- ip_msdp_show_mesh_group(vty, uj);
-
- return CMD_SUCCESS;
-}
-
-static void
-ip_msdp_show_peers(struct vty *vty, u_char uj)
-{
- struct listnode *mpnode;
- struct pim_msdp_peer *mp;
- char peer_str[INET_ADDRSTRLEN];
- char local_str[INET_ADDRSTRLEN];
- char state_str[PIM_MSDP_STATE_STRLEN];
- char timebuf[PIM_MSDP_UPTIME_STRLEN];
- int64_t now;
- json_object *json = NULL;
- json_object *json_row = NULL;
-
-
- if (uj) {
- json = json_object_new_object();
- } else {
- vty_out (vty,
- "Peer Local State Uptime SaCnt\n");
- }
-
- for (ALL_LIST_ELEMENTS_RO(msdp->peer_list, mpnode, mp)) {
- if (mp->state == PIM_MSDP_ESTABLISHED) {
- now = pim_time_monotonic_sec();
- pim_time_uptime(timebuf, sizeof(timebuf), now - mp->uptime);
- } else {
- strcpy(timebuf, "-");
- }
- pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
- pim_inet4_dump("<local?>", mp->local, local_str, sizeof(local_str));
- pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
- if (uj) {
- json_row = json_object_new_object();
- json_object_string_add(json_row, "peer", peer_str);
- json_object_string_add(json_row, "local", local_str);
- json_object_string_add(json_row, "state", state_str);
- json_object_string_add(json_row, "upTime", timebuf);
- json_object_int_add(json_row, "saCount", mp->sa_cnt);
- json_object_object_add(json, peer_str, json_row);
- } else {
- vty_out (vty, "%-15s %15s %11s %8s %6d\n",
- peer_str, local_str, state_str,
- timebuf, mp->sa_cnt);
- }
- }
-
- if (uj) {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
-}
-
-static void
-ip_msdp_show_peers_detail(struct vty *vty, const char *peer, u_char uj)
-{
- struct listnode *mpnode;
- struct pim_msdp_peer *mp;
- char peer_str[INET_ADDRSTRLEN];
- char local_str[INET_ADDRSTRLEN];
- char state_str[PIM_MSDP_STATE_STRLEN];
- char timebuf[PIM_MSDP_UPTIME_STRLEN];
- char katimer[PIM_MSDP_TIMER_STRLEN];
- char crtimer[PIM_MSDP_TIMER_STRLEN];
- char holdtimer[PIM_MSDP_TIMER_STRLEN];
- int64_t now;
- json_object *json = NULL;
- json_object *json_row = NULL;
-
- if (uj) {
- json = json_object_new_object();
- }
-
- for (ALL_LIST_ELEMENTS_RO(msdp->peer_list, mpnode, mp)) {
- pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
- if (strcmp(peer, "detail") &&
- strcmp(peer, peer_str))
- continue;
-
- if (mp->state == PIM_MSDP_ESTABLISHED) {
- now = pim_time_monotonic_sec();
- pim_time_uptime(timebuf, sizeof(timebuf), now - mp->uptime);
- } else {
- strcpy(timebuf, "-");
- }
- pim_inet4_dump("<local?>", mp->local, local_str, sizeof(local_str));
- pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
- pim_time_timer_to_hhmmss(katimer, sizeof(katimer), mp->ka_timer);
- pim_time_timer_to_hhmmss(crtimer, sizeof(crtimer), mp->cr_timer);
- pim_time_timer_to_hhmmss(holdtimer, sizeof(holdtimer), mp->hold_timer);
-
- if (uj) {
- json_row = json_object_new_object();
- json_object_string_add(json_row, "peer", peer_str);
- json_object_string_add(json_row, "local", local_str);
- json_object_string_add(json_row, "meshGroupName", mp->mesh_group_name);
- json_object_string_add(json_row, "state", state_str);
- json_object_string_add(json_row, "upTime", timebuf);
- json_object_string_add(json_row, "keepAliveTimer", katimer);
- json_object_string_add(json_row, "connRetryTimer", crtimer);
- json_object_string_add(json_row, "holdTimer", holdtimer);
- json_object_string_add(json_row, "lastReset", mp->last_reset);
- json_object_int_add(json_row, "connAttempts", mp->conn_attempts);
- json_object_int_add(json_row, "establishedChanges", mp->est_flaps);
- json_object_int_add(json_row, "saCount", mp->sa_cnt);
- json_object_int_add(json_row, "kaSent", mp->ka_tx_cnt);
- json_object_int_add(json_row, "kaRcvd", mp->ka_rx_cnt);
- json_object_int_add(json_row, "saSent", mp->sa_tx_cnt);
- json_object_int_add(json_row, "saRcvd", mp->sa_rx_cnt);
- json_object_object_add(json, peer_str, json_row);
- } else {
- vty_out (vty, "Peer : %s\n", peer_str);
- vty_out (vty, " Local : %s\n", local_str);
- vty_out (vty, " Mesh Group : %s\n", mp->mesh_group_name);
- vty_out (vty, " State : %s\n", state_str);
- vty_out (vty, " Uptime : %s\n", timebuf);
-
- vty_out (vty, " Keepalive Timer : %s\n", katimer);
- vty_out (vty, " Conn Retry Timer : %s\n", crtimer);
- vty_out (vty, " Hold Timer : %s\n", holdtimer);
- vty_out (vty, " Last Reset : %s\n", mp->last_reset);
- vty_out (vty, " Conn Attempts : %d\n", mp->conn_attempts);
- vty_out (vty, " Established Changes : %d\n", mp->est_flaps);
- vty_out (vty, " SA Count : %d\n", mp->sa_cnt);
- vty_out (vty, " Statistics :\n");
- vty_out (vty, " Sent Rcvd\n");
- vty_out (vty, " Keepalives : %10d %10d\n",
- mp->ka_tx_cnt, mp->ka_rx_cnt);
- vty_out (vty, " SAs : %10d %10d\n",
- mp->sa_tx_cnt, mp->sa_rx_cnt);
- vty_out (vty, "\n");
- }
- }
-
- if (uj) {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
+ u_char uj = use_json(argc, argv);
+ ip_msdp_show_mesh_group(vty, uj);
+
+ return CMD_SUCCESS;
+}
+
+static void ip_msdp_show_peers(struct vty *vty, u_char uj)
+{
+ struct listnode *mpnode;
+ struct pim_msdp_peer *mp;
+ char peer_str[INET_ADDRSTRLEN];
+ char local_str[INET_ADDRSTRLEN];
+ char state_str[PIM_MSDP_STATE_STRLEN];
+ char timebuf[PIM_MSDP_UPTIME_STRLEN];
+ int64_t now;
+ json_object *json = NULL;
+ json_object *json_row = NULL;
+
+
+ if (uj) {
+ json = json_object_new_object();
+ } else {
+ vty_out(vty,
+ "Peer Local State Uptime SaCnt\n");
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(msdp->peer_list, mpnode, mp)) {
+ if (mp->state == PIM_MSDP_ESTABLISHED) {
+ now = pim_time_monotonic_sec();
+ pim_time_uptime(timebuf, sizeof(timebuf),
+ now - mp->uptime);
+ } else {
+ strcpy(timebuf, "-");
+ }
+ pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
+ pim_inet4_dump("<local?>", mp->local, local_str,
+ sizeof(local_str));
+ pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
+ if (uj) {
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "peer", peer_str);
+ json_object_string_add(json_row, "local", local_str);
+ json_object_string_add(json_row, "state", state_str);
+ json_object_string_add(json_row, "upTime", timebuf);
+ json_object_int_add(json_row, "saCount", mp->sa_cnt);
+ json_object_object_add(json, peer_str, json_row);
+ } else {
+ vty_out(vty, "%-15s %15s %11s %8s %6d\n", peer_str,
+ local_str, state_str, timebuf, mp->sa_cnt);
+ }
+ }
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
+}
+
+static void ip_msdp_show_peers_detail(struct vty *vty, const char *peer,
+ u_char uj)
+{
+ struct listnode *mpnode;
+ struct pim_msdp_peer *mp;
+ char peer_str[INET_ADDRSTRLEN];
+ char local_str[INET_ADDRSTRLEN];
+ char state_str[PIM_MSDP_STATE_STRLEN];
+ char timebuf[PIM_MSDP_UPTIME_STRLEN];
+ char katimer[PIM_MSDP_TIMER_STRLEN];
+ char crtimer[PIM_MSDP_TIMER_STRLEN];
+ char holdtimer[PIM_MSDP_TIMER_STRLEN];
+ int64_t now;
+ json_object *json = NULL;
+ json_object *json_row = NULL;
+
+ if (uj) {
+ json = json_object_new_object();
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(msdp->peer_list, mpnode, mp)) {
+ pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
+ if (strcmp(peer, "detail") && strcmp(peer, peer_str))
+ continue;
+
+ if (mp->state == PIM_MSDP_ESTABLISHED) {
+ now = pim_time_monotonic_sec();
+ pim_time_uptime(timebuf, sizeof(timebuf),
+ now - mp->uptime);
+ } else {
+ strcpy(timebuf, "-");
+ }
+ pim_inet4_dump("<local?>", mp->local, local_str,
+ sizeof(local_str));
+ pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
+ pim_time_timer_to_hhmmss(katimer, sizeof(katimer),
+ mp->ka_timer);
+ pim_time_timer_to_hhmmss(crtimer, sizeof(crtimer),
+ mp->cr_timer);
+ pim_time_timer_to_hhmmss(holdtimer, sizeof(holdtimer),
+ mp->hold_timer);
+
+ if (uj) {
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "peer", peer_str);
+ json_object_string_add(json_row, "local", local_str);
+ json_object_string_add(json_row, "meshGroupName",
+ mp->mesh_group_name);
+ json_object_string_add(json_row, "state", state_str);
+ json_object_string_add(json_row, "upTime", timebuf);
+ json_object_string_add(json_row, "keepAliveTimer",
+ katimer);
+ json_object_string_add(json_row, "connRetryTimer",
+ crtimer);
+ json_object_string_add(json_row, "holdTimer",
+ holdtimer);
+ json_object_string_add(json_row, "lastReset",
+ mp->last_reset);
+ json_object_int_add(json_row, "connAttempts",
+ mp->conn_attempts);
+ json_object_int_add(json_row, "establishedChanges",
+ mp->est_flaps);
+ json_object_int_add(json_row, "saCount", mp->sa_cnt);
+ json_object_int_add(json_row, "kaSent", mp->ka_tx_cnt);
+ json_object_int_add(json_row, "kaRcvd", mp->ka_rx_cnt);
+ json_object_int_add(json_row, "saSent", mp->sa_tx_cnt);
+ json_object_int_add(json_row, "saRcvd", mp->sa_rx_cnt);
+ json_object_object_add(json, peer_str, json_row);
+ } else {
+ vty_out(vty, "Peer : %s\n", peer_str);
+ vty_out(vty, " Local : %s\n", local_str);
+ vty_out(vty, " Mesh Group : %s\n",
+ mp->mesh_group_name);
+ vty_out(vty, " State : %s\n", state_str);
+ vty_out(vty, " Uptime : %s\n", timebuf);
+
+ vty_out(vty, " Keepalive Timer : %s\n", katimer);
+ vty_out(vty, " Conn Retry Timer : %s\n", crtimer);
+ vty_out(vty, " Hold Timer : %s\n", holdtimer);
+ vty_out(vty, " Last Reset : %s\n",
+ mp->last_reset);
+ vty_out(vty, " Conn Attempts : %d\n",
+ mp->conn_attempts);
+ vty_out(vty, " Established Changes : %d\n",
+ mp->est_flaps);
+ vty_out(vty, " SA Count : %d\n",
+ mp->sa_cnt);
+ vty_out(vty, " Statistics :\n");
+ vty_out(vty,
+ " Sent Rcvd\n");
+ vty_out(vty, " Keepalives : %10d %10d\n",
+ mp->ka_tx_cnt, mp->ka_rx_cnt);
+ vty_out(vty, " SAs : %10d %10d\n",
+ mp->sa_tx_cnt, mp->sa_rx_cnt);
+ vty_out(vty, "\n");
+ }
+ }
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
}
DEFUN (show_ip_msdp_peer_detail,
@@ -6534,181 +6980,183 @@ DEFUN (show_ip_msdp_peer_detail,
"peer ip address\n"
"JavaScript Object Notation\n")
{
- u_char uj = use_json(argc, argv);
- if (uj)
- argc--;
-
- if (argc > 4)
- ip_msdp_show_peers_detail(vty, argv[4]->arg, uj);
- else
- ip_msdp_show_peers(vty, uj);
-
- return CMD_SUCCESS;
-}
-
-static void
-ip_msdp_show_sa(struct vty *vty, u_char uj)
-{
- struct listnode *sanode;
- struct pim_msdp_sa *sa;
- char src_str[INET_ADDRSTRLEN];
- char grp_str[INET_ADDRSTRLEN];
- char rp_str[INET_ADDRSTRLEN];
- char timebuf[PIM_MSDP_UPTIME_STRLEN];
- char spt_str[8];
- char local_str[8];
- int64_t now;
- json_object *json = NULL;
- json_object *json_group = NULL;
- json_object *json_row = NULL;
-
- if (uj) {
- json = json_object_new_object();
- } else {
- vty_out (vty,
- "Source Group RP Local SPT Uptime\n");
- }
-
- for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
- now = pim_time_monotonic_sec();
- pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
- pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
- if (sa->flags & PIM_MSDP_SAF_PEER) {
- pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
- if (sa->up) {
- strcpy(spt_str, "yes");
- } else {
- strcpy(spt_str, "no");
- }
- } else {
- strcpy(rp_str, "-");
- strcpy(spt_str, "-");
- }
- if (sa->flags & PIM_MSDP_SAF_LOCAL) {
- strcpy(local_str, "yes");
- } else {
- strcpy(local_str, "no");
- }
- if (uj) {
- json_object_object_get_ex(json, grp_str, &json_group);
-
- if (!json_group) {
- json_group = json_object_new_object();
- json_object_object_add(json, grp_str, json_group);
- }
-
- json_row = json_object_new_object();
- json_object_string_add(json_row, "source", src_str);
- json_object_string_add(json_row, "group", grp_str);
- json_object_string_add(json_row, "rp", rp_str);
- json_object_string_add(json_row, "local", local_str);
- json_object_string_add(json_row, "sptSetup", spt_str);
- json_object_string_add(json_row, "upTime", timebuf);
- json_object_object_add(json_group, src_str, json_row);
- } else {
- vty_out (vty, "%-15s %15s %15s %5c %3c %8s\n",
- src_str, grp_str, rp_str, local_str[0], spt_str[0], timebuf);
- }
- }
-
-
- if (uj) {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
-}
-
-static void
-ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa, const char *src_str,
- const char *grp_str, struct vty *vty,
- u_char uj, json_object *json)
-{
- char rp_str[INET_ADDRSTRLEN];
- char peer_str[INET_ADDRSTRLEN];
- char timebuf[PIM_MSDP_UPTIME_STRLEN];
- char spt_str[8];
- char local_str[8];
- char statetimer[PIM_MSDP_TIMER_STRLEN];
- int64_t now;
- json_object *json_group = NULL;
- json_object *json_row = NULL;
-
- now = pim_time_monotonic_sec();
- pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
- if (sa->flags & PIM_MSDP_SAF_PEER) {
- pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
- pim_inet4_dump("<peer?>", sa->peer, peer_str, sizeof(peer_str));
- if (sa->up) {
- strcpy(spt_str, "yes");
- } else {
- strcpy(spt_str, "no");
- }
- } else {
- strcpy(rp_str, "-");
- strcpy(peer_str, "-");
- strcpy(spt_str, "-");
- }
- if (sa->flags & PIM_MSDP_SAF_LOCAL) {
- strcpy(local_str, "yes");
- } else {
- strcpy(local_str, "no");
- }
- pim_time_timer_to_hhmmss(statetimer, sizeof(statetimer), sa->sa_state_timer);
- if (uj) {
- json_object_object_get_ex(json, grp_str, &json_group);
-
- if (!json_group) {
- json_group = json_object_new_object();
- json_object_object_add(json, grp_str, json_group);
- }
-
- json_row = json_object_new_object();
- json_object_string_add(json_row, "source", src_str);
- json_object_string_add(json_row, "group", grp_str);
- json_object_string_add(json_row, "rp", rp_str);
- json_object_string_add(json_row, "local", local_str);
- json_object_string_add(json_row, "sptSetup", spt_str);
- json_object_string_add(json_row, "upTime", timebuf);
- json_object_string_add(json_row, "stateTimer", statetimer);
- json_object_object_add(json_group, src_str, json_row);
- } else {
- vty_out (vty, "SA : %s\n", sa->sg_str);
- vty_out (vty, " RP : %s\n", rp_str);
- vty_out (vty, " Peer : %s\n", peer_str);
- vty_out (vty, " Local : %s\n", local_str);
- vty_out (vty, " SPT Setup : %s\n", spt_str);
- vty_out (vty, " Uptime : %s\n", timebuf);
- vty_out (vty, " State Timer : %s\n", statetimer);
- vty_out (vty, "\n");
- }
-}
-
-static void
-ip_msdp_show_sa_detail(struct vty *vty, u_char uj)
-{
- struct listnode *sanode;
- struct pim_msdp_sa *sa;
- char src_str[INET_ADDRSTRLEN];
- char grp_str[INET_ADDRSTRLEN];
- json_object *json = NULL;
-
- if (uj) {
- json = json_object_new_object();
- }
-
- for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
- pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
- ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj, json);
- }
-
- if (uj) {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
+ u_char uj = use_json(argc, argv);
+ if (uj)
+ argc--;
+
+ if (argc > 4)
+ ip_msdp_show_peers_detail(vty, argv[4]->arg, uj);
+ else
+ ip_msdp_show_peers(vty, uj);
+
+ return CMD_SUCCESS;
+}
+
+static void ip_msdp_show_sa(struct vty *vty, u_char uj)
+{
+ struct listnode *sanode;
+ struct pim_msdp_sa *sa;
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ char rp_str[INET_ADDRSTRLEN];
+ char timebuf[PIM_MSDP_UPTIME_STRLEN];
+ char spt_str[8];
+ char local_str[8];
+ int64_t now;
+ json_object *json = NULL;
+ json_object *json_group = NULL;
+ json_object *json_row = NULL;
+
+ if (uj) {
+ json = json_object_new_object();
+ } else {
+ vty_out(vty,
+ "Source Group RP Local SPT Uptime\n");
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
+ now = pim_time_monotonic_sec();
+ pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
+ pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
+ if (sa->flags & PIM_MSDP_SAF_PEER) {
+ pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
+ if (sa->up) {
+ strcpy(spt_str, "yes");
+ } else {
+ strcpy(spt_str, "no");
+ }
+ } else {
+ strcpy(rp_str, "-");
+ strcpy(spt_str, "-");
+ }
+ if (sa->flags & PIM_MSDP_SAF_LOCAL) {
+ strcpy(local_str, "yes");
+ } else {
+ strcpy(local_str, "no");
+ }
+ if (uj) {
+ json_object_object_get_ex(json, grp_str, &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str,
+ json_group);
+ }
+
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "source", src_str);
+ json_object_string_add(json_row, "group", grp_str);
+ json_object_string_add(json_row, "rp", rp_str);
+ json_object_string_add(json_row, "local", local_str);
+ json_object_string_add(json_row, "sptSetup", spt_str);
+ json_object_string_add(json_row, "upTime", timebuf);
+ json_object_object_add(json_group, src_str, json_row);
+ } else {
+ vty_out(vty, "%-15s %15s %15s %5c %3c %8s\n",
+ src_str, grp_str, rp_str, local_str[0],
+ spt_str[0], timebuf);
+ }
+ }
+
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
+}
+
+static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa,
+ const char *src_str,
+ const char *grp_str, struct vty *vty,
+ u_char uj, json_object *json)
+{
+ char rp_str[INET_ADDRSTRLEN];
+ char peer_str[INET_ADDRSTRLEN];
+ char timebuf[PIM_MSDP_UPTIME_STRLEN];
+ char spt_str[8];
+ char local_str[8];
+ char statetimer[PIM_MSDP_TIMER_STRLEN];
+ int64_t now;
+ json_object *json_group = NULL;
+ json_object *json_row = NULL;
+
+ now = pim_time_monotonic_sec();
+ pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
+ if (sa->flags & PIM_MSDP_SAF_PEER) {
+ pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
+ pim_inet4_dump("<peer?>", sa->peer, peer_str, sizeof(peer_str));
+ if (sa->up) {
+ strcpy(spt_str, "yes");
+ } else {
+ strcpy(spt_str, "no");
+ }
+ } else {
+ strcpy(rp_str, "-");
+ strcpy(peer_str, "-");
+ strcpy(spt_str, "-");
+ }
+ if (sa->flags & PIM_MSDP_SAF_LOCAL) {
+ strcpy(local_str, "yes");
+ } else {
+ strcpy(local_str, "no");
+ }
+ pim_time_timer_to_hhmmss(statetimer, sizeof(statetimer),
+ sa->sa_state_timer);
+ if (uj) {
+ json_object_object_get_ex(json, grp_str, &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(json, grp_str, json_group);
+ }
+
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "source", src_str);
+ json_object_string_add(json_row, "group", grp_str);
+ json_object_string_add(json_row, "rp", rp_str);
+ json_object_string_add(json_row, "local", local_str);
+ json_object_string_add(json_row, "sptSetup", spt_str);
+ json_object_string_add(json_row, "upTime", timebuf);
+ json_object_string_add(json_row, "stateTimer", statetimer);
+ json_object_object_add(json_group, src_str, json_row);
+ } else {
+ vty_out(vty, "SA : %s\n", sa->sg_str);
+ vty_out(vty, " RP : %s\n", rp_str);
+ vty_out(vty, " Peer : %s\n", peer_str);
+ vty_out(vty, " Local : %s\n", local_str);
+ vty_out(vty, " SPT Setup : %s\n", spt_str);
+ vty_out(vty, " Uptime : %s\n", timebuf);
+ vty_out(vty, " State Timer : %s\n", statetimer);
+ vty_out(vty, "\n");
+ }
+}
+
+static void ip_msdp_show_sa_detail(struct vty *vty, u_char uj)
+{
+ struct listnode *sanode;
+ struct pim_msdp_sa *sa;
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ json_object *json = NULL;
+
+ if (uj) {
+ json = json_object_new_object();
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
+ pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
+ ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj,
+ json);
+ }
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
}
DEFUN (show_ip_msdp_sa_detail,
@@ -6721,66 +7169,67 @@ DEFUN (show_ip_msdp_sa_detail,
"Detailed output\n"
"JavaScript Object Notation\n")
{
- u_char uj = use_json(argc, argv);
- ip_msdp_show_sa_detail(vty, uj);
+ u_char uj = use_json(argc, argv);
+ ip_msdp_show_sa_detail(vty, uj);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
-static void
-ip_msdp_show_sa_addr(struct vty *vty, const char *addr, u_char uj)
+static void ip_msdp_show_sa_addr(struct vty *vty, const char *addr, u_char uj)
{
- struct listnode *sanode;
- struct pim_msdp_sa *sa;
- char src_str[INET_ADDRSTRLEN];
- char grp_str[INET_ADDRSTRLEN];
- json_object *json = NULL;
+ struct listnode *sanode;
+ struct pim_msdp_sa *sa;
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ json_object *json = NULL;
- if (uj) {
- json = json_object_new_object();
- }
+ if (uj) {
+ json = json_object_new_object();
+ }
- for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
- pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
- if (!strcmp(addr, src_str) || !strcmp(addr, grp_str)) {
- ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj, json);
- }
- }
+ for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
+ pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
+ if (!strcmp(addr, src_str) || !strcmp(addr, grp_str)) {
+ ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
+ uj, json);
+ }
+ }
- if (uj) {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
}
-static void
-ip_msdp_show_sa_sg(struct vty *vty, const char *src, const char *grp, u_char uj)
+static void ip_msdp_show_sa_sg(struct vty *vty, const char *src,
+ const char *grp, u_char uj)
{
- struct listnode *sanode;
- struct pim_msdp_sa *sa;
- char src_str[INET_ADDRSTRLEN];
- char grp_str[INET_ADDRSTRLEN];
- json_object *json = NULL;
+ struct listnode *sanode;
+ struct pim_msdp_sa *sa;
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ json_object *json = NULL;
- if (uj) {
- json = json_object_new_object();
- }
+ if (uj) {
+ json = json_object_new_object();
+ }
- for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
- pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
- if (!strcmp(src, src_str) && !strcmp(grp, grp_str)) {
- ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj, json);
- }
- }
+ for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
+ pim_inet4_dump("<src?>", sa->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", sa->sg.grp, grp_str, sizeof(grp_str));
+ if (!strcmp(src, src_str) && !strcmp(grp, grp_str)) {
+ ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
+ uj, json);
+ }
+ }
- if (uj) {
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
}
DEFUN (show_ip_msdp_sa_sg,
@@ -6794,218 +7243,227 @@ DEFUN (show_ip_msdp_sa_sg,
"group ip\n"
"JavaScript Object Notation\n")
{
- u_char uj = use_json(argc, argv);
+ u_char uj = use_json(argc, argv);
- int idx = 0;
- char *src_ip = argv_find (argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg : NULL;
- char *grp_ip = idx < argc && argv_find (argv, argc, "A.B.C.D", &idx) ?
- argv[idx]->arg : NULL;
+ int idx = 0;
+ char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
+ : NULL;
+ char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
+ ? argv[idx]->arg
+ : NULL;
- if (src_ip && grp_ip)
- ip_msdp_show_sa_sg(vty, src_ip, grp_ip, uj);
- else if (src_ip)
- ip_msdp_show_sa_addr(vty, src_ip, uj);
- else
- ip_msdp_show_sa(vty, uj);
+ if (src_ip && grp_ip)
+ ip_msdp_show_sa_sg(vty, src_ip, grp_ip, uj);
+ else if (src_ip)
+ ip_msdp_show_sa_addr(vty, src_ip, uj);
+ else
+ ip_msdp_show_sa(vty, uj);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
void pim_cmd_init()
{
- install_node (&pim_global_node, pim_global_config_write); /* PIM_NODE */
- install_node (&interface_node, pim_interface_config_write); /* INTERFACE_NODE */
- if_cmd_init ();
-
- install_node (&debug_node, pim_debug_config_write);
-
- install_element (CONFIG_NODE, &ip_multicast_routing_cmd);
- install_element (CONFIG_NODE, &no_ip_multicast_routing_cmd);
- install_element (CONFIG_NODE, &ip_pim_rp_cmd);
- install_element (CONFIG_NODE, &no_ip_pim_rp_cmd);
- install_element (CONFIG_NODE, &ip_pim_rp_prefix_list_cmd);
- install_element (CONFIG_NODE, &no_ip_pim_rp_prefix_list_cmd);
- install_element (CONFIG_NODE, &no_ip_pim_ssm_prefix_list_cmd);
- install_element (CONFIG_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
- install_element (CONFIG_NODE, &ip_pim_ssm_prefix_list_cmd);
- install_element (CONFIG_NODE, &ip_pim_register_suppress_cmd);
- install_element (CONFIG_NODE, &no_ip_pim_register_suppress_cmd);
- install_element (CONFIG_NODE, &ip_pim_spt_switchover_infinity_cmd);
- install_element (CONFIG_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
- install_element (CONFIG_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
- install_element (CONFIG_NODE, &no_ip_pim_spt_switchover_infinity_plist_cmd);
- install_element (CONFIG_NODE, &ip_pim_joinprune_time_cmd);
- install_element (CONFIG_NODE, &no_ip_pim_joinprune_time_cmd);
- install_element (CONFIG_NODE, &ip_pim_keep_alive_cmd);
- install_element (CONFIG_NODE, &no_ip_pim_keep_alive_cmd);
- install_element (CONFIG_NODE, &ip_pim_packets_cmd);
- install_element (CONFIG_NODE, &no_ip_pim_packets_cmd);
- install_element (CONFIG_NODE, &ip_pim_v6_secondary_cmd);
- install_element (CONFIG_NODE, &no_ip_pim_v6_secondary_cmd);
- install_element (CONFIG_NODE, &ip_ssmpingd_cmd);
- install_element (CONFIG_NODE, &no_ip_ssmpingd_cmd);
- install_element (CONFIG_NODE, &ip_msdp_peer_cmd);
- install_element (CONFIG_NODE, &no_ip_msdp_peer_cmd);
- install_element (CONFIG_NODE, &ip_pim_ecmp_cmd);
- install_element (CONFIG_NODE, &no_ip_pim_ecmp_cmd);
- install_element (CONFIG_NODE, &ip_pim_ecmp_rebalance_cmd);
- install_element (CONFIG_NODE, &no_ip_pim_ecmp_rebalance_cmd);
-
- install_element (INTERFACE_NODE, &interface_ip_igmp_cmd);
- install_element (INTERFACE_NODE, &interface_no_ip_igmp_cmd);
- install_element (INTERFACE_NODE, &interface_ip_igmp_join_cmd);
- install_element (INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
- install_element (INTERFACE_NODE, &interface_ip_igmp_version_cmd);
- install_element (INTERFACE_NODE, &interface_no_ip_igmp_version_cmd);
- install_element (INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
- install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_interval_cmd);
- install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_cmd);
- install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_cmd);
- install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_dsec_cmd);
- install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
- install_element (INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
- install_element (INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
- install_element (INTERFACE_NODE, &interface_ip_pim_sm_cmd);
- install_element (INTERFACE_NODE, &interface_no_ip_pim_sm_cmd);
- install_element (INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
- install_element (INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
- install_element (INTERFACE_NODE, &interface_ip_pim_hello_cmd);
- install_element (INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
-
- // Static mroutes NEB
- install_element (INTERFACE_NODE, &interface_ip_mroute_cmd);
- install_element (INTERFACE_NODE, &interface_ip_mroute_source_cmd);
- install_element (INTERFACE_NODE, &interface_no_ip_mroute_cmd);
- install_element (INTERFACE_NODE, &interface_no_ip_mroute_source_cmd);
-
- install_element (VIEW_NODE, &show_ip_igmp_interface_cmd);
- install_element (VIEW_NODE, &show_ip_igmp_join_cmd);
- install_element (VIEW_NODE, &show_ip_igmp_groups_cmd);
- install_element (VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
- install_element (VIEW_NODE, &show_ip_igmp_sources_cmd);
- install_element (VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
- install_element (VIEW_NODE, &show_ip_pim_assert_cmd);
- install_element (VIEW_NODE, &show_ip_pim_assert_internal_cmd);
- install_element (VIEW_NODE, &show_ip_pim_assert_metric_cmd);
- install_element (VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
- install_element (VIEW_NODE, &show_ip_pim_interface_traffic_cmd);
- install_element (VIEW_NODE, &show_ip_pim_interface_cmd);
- install_element (VIEW_NODE, &show_ip_pim_join_cmd);
- install_element (VIEW_NODE, &show_ip_pim_local_membership_cmd);
- install_element (VIEW_NODE, &show_ip_pim_neighbor_cmd);
- install_element (VIEW_NODE, &show_ip_pim_rpf_cmd);
- install_element (VIEW_NODE, &show_ip_pim_secondary_cmd);
- install_element (VIEW_NODE, &show_ip_pim_state_cmd);
- install_element (VIEW_NODE, &show_ip_pim_upstream_cmd);
- install_element (VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
- install_element (VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
- install_element (VIEW_NODE, &show_ip_pim_rp_cmd);
- install_element (VIEW_NODE, &show_ip_multicast_cmd);
- install_element (VIEW_NODE, &show_ip_mroute_cmd);
- install_element (VIEW_NODE, &show_ip_mroute_count_cmd);
- install_element (VIEW_NODE, &show_ip_rib_cmd);
- install_element (VIEW_NODE, &show_ip_ssmpingd_cmd);
- install_element (VIEW_NODE, &show_debugging_pim_cmd);
- install_element (VIEW_NODE, &show_ip_pim_nexthop_cmd);
- install_element (VIEW_NODE, &show_ip_pim_nexthop_lookup_cmd);
-
- install_element (ENABLE_NODE, &clear_ip_interfaces_cmd);
- install_element (ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
- install_element (ENABLE_NODE, &clear_ip_mroute_cmd);
- install_element (ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
- install_element (ENABLE_NODE, &clear_ip_pim_interface_traffic_cmd);
- install_element (ENABLE_NODE, &clear_ip_pim_oil_cmd);
-
- install_element (ENABLE_NODE, &debug_igmp_cmd);
- install_element (ENABLE_NODE, &no_debug_igmp_cmd);
- install_element (ENABLE_NODE, &debug_igmp_events_cmd);
- install_element (ENABLE_NODE, &no_debug_igmp_events_cmd);
- install_element (ENABLE_NODE, &debug_igmp_packets_cmd);
- install_element (ENABLE_NODE, &no_debug_igmp_packets_cmd);
- install_element (ENABLE_NODE, &debug_igmp_trace_cmd);
- install_element (ENABLE_NODE, &no_debug_igmp_trace_cmd);
- install_element (ENABLE_NODE, &debug_mroute_cmd);
- install_element (ENABLE_NODE, &debug_mroute_detail_cmd);
- install_element (ENABLE_NODE, &no_debug_mroute_cmd);
- install_element (ENABLE_NODE, &no_debug_mroute_detail_cmd);
- install_element (ENABLE_NODE, &debug_static_cmd);
- install_element (ENABLE_NODE, &no_debug_static_cmd);
- install_element (ENABLE_NODE, &debug_pim_cmd);
- install_element (ENABLE_NODE, &no_debug_pim_cmd);
- install_element (ENABLE_NODE, &debug_pim_events_cmd);
- install_element (ENABLE_NODE, &no_debug_pim_events_cmd);
- install_element (ENABLE_NODE, &debug_pim_packets_cmd);
- install_element (ENABLE_NODE, &no_debug_pim_packets_cmd);
- install_element (ENABLE_NODE, &debug_pim_packetdump_send_cmd);
- install_element (ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
- install_element (ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
- install_element (ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
- install_element (ENABLE_NODE, &debug_pim_trace_cmd);
- install_element (ENABLE_NODE, &no_debug_pim_trace_cmd);
- install_element (ENABLE_NODE, &debug_ssmpingd_cmd);
- install_element (ENABLE_NODE, &no_debug_ssmpingd_cmd);
- install_element (ENABLE_NODE, &debug_pim_zebra_cmd);
- install_element (ENABLE_NODE, &no_debug_pim_zebra_cmd);
- install_element (ENABLE_NODE, &debug_msdp_cmd);
- install_element (ENABLE_NODE, &no_debug_msdp_cmd);
- install_element (ENABLE_NODE, &undebug_msdp_cmd);
- install_element (ENABLE_NODE, &debug_msdp_events_cmd);
- install_element (ENABLE_NODE, &no_debug_msdp_events_cmd);
- install_element (ENABLE_NODE, &undebug_msdp_events_cmd);
- install_element (ENABLE_NODE, &debug_msdp_packets_cmd);
- install_element (ENABLE_NODE, &no_debug_msdp_packets_cmd);
- install_element (ENABLE_NODE, &undebug_msdp_packets_cmd);
-
- install_element (CONFIG_NODE, &debug_igmp_cmd);
- install_element (CONFIG_NODE, &no_debug_igmp_cmd);
- install_element (CONFIG_NODE, &debug_igmp_events_cmd);
- install_element (CONFIG_NODE, &no_debug_igmp_events_cmd);
- install_element (CONFIG_NODE, &debug_igmp_packets_cmd);
- install_element (CONFIG_NODE, &no_debug_igmp_packets_cmd);
- install_element (CONFIG_NODE, &debug_igmp_trace_cmd);
- install_element (CONFIG_NODE, &no_debug_igmp_trace_cmd);
- install_element (CONFIG_NODE, &debug_mroute_cmd);
- install_element (CONFIG_NODE, &debug_mroute_detail_cmd);
- install_element (CONFIG_NODE, &no_debug_mroute_cmd);
- install_element (CONFIG_NODE, &no_debug_mroute_detail_cmd);
- install_element (CONFIG_NODE, &debug_static_cmd);
- install_element (CONFIG_NODE, &no_debug_static_cmd);
- install_element (CONFIG_NODE, &debug_pim_cmd);
- install_element (CONFIG_NODE, &no_debug_pim_cmd);
- install_element (CONFIG_NODE, &debug_pim_events_cmd);
- install_element (CONFIG_NODE, &no_debug_pim_events_cmd);
- install_element (CONFIG_NODE, &debug_pim_packets_cmd);
- install_element (CONFIG_NODE, &no_debug_pim_packets_cmd);
- install_element (CONFIG_NODE, &debug_pim_trace_cmd);
- install_element (CONFIG_NODE, &no_debug_pim_trace_cmd);
- install_element (CONFIG_NODE, &debug_ssmpingd_cmd);
- install_element (CONFIG_NODE, &no_debug_ssmpingd_cmd);
- install_element (CONFIG_NODE, &debug_pim_zebra_cmd);
- install_element (CONFIG_NODE, &no_debug_pim_zebra_cmd);
- install_element (CONFIG_NODE, &debug_msdp_cmd);
- install_element (CONFIG_NODE, &no_debug_msdp_cmd);
- install_element (CONFIG_NODE, &undebug_msdp_cmd);
- install_element (CONFIG_NODE, &debug_msdp_events_cmd);
- install_element (CONFIG_NODE, &no_debug_msdp_events_cmd);
- install_element (CONFIG_NODE, &undebug_msdp_events_cmd);
- install_element (CONFIG_NODE, &debug_msdp_packets_cmd);
- install_element (CONFIG_NODE, &no_debug_msdp_packets_cmd);
- install_element (CONFIG_NODE, &undebug_msdp_packets_cmd);
- install_element (CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
- install_element (CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);
- install_element (CONFIG_NODE, &ip_msdp_mesh_group_source_cmd);
- install_element (CONFIG_NODE, &no_ip_msdp_mesh_group_source_cmd);
- install_element (VIEW_NODE, &show_ip_msdp_peer_detail_cmd);
- install_element (VIEW_NODE, &show_ip_msdp_sa_detail_cmd);
- install_element (VIEW_NODE, &show_ip_msdp_sa_sg_cmd);
- install_element (VIEW_NODE, &show_ip_msdp_mesh_group_cmd);
- install_element (VIEW_NODE, &show_ip_pim_ssm_range_cmd);
- install_element (VIEW_NODE, &show_ip_pim_group_type_cmd);
- install_element (INTERFACE_NODE, &interface_pim_use_source_cmd);
- install_element (INTERFACE_NODE, &interface_no_pim_use_source_cmd);
- /* Install BFD command */
- install_element (INTERFACE_NODE, &ip_pim_bfd_cmd);
- install_element (INTERFACE_NODE, &ip_pim_bfd_param_cmd);
- install_element (INTERFACE_NODE, &no_ip_pim_bfd_cmd);
- install_element (INTERFACE_NODE, &no_ip_pim_bfd_param_cmd);
+ install_node(&pim_global_node, pim_global_config_write); /* PIM_NODE */
+ install_node(&interface_node,
+ pim_interface_config_write); /* INTERFACE_NODE */
+ if_cmd_init();
+
+ install_node(&debug_node, pim_debug_config_write);
+
+ install_element(CONFIG_NODE, &ip_multicast_routing_cmd);
+ install_element(CONFIG_NODE, &no_ip_multicast_routing_cmd);
+ install_element(CONFIG_NODE, &ip_pim_rp_cmd);
+ install_element(CONFIG_NODE, &no_ip_pim_rp_cmd);
+ install_element(CONFIG_NODE, &ip_pim_rp_prefix_list_cmd);
+ install_element(CONFIG_NODE, &no_ip_pim_rp_prefix_list_cmd);
+ install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_cmd);
+ install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
+ install_element(CONFIG_NODE, &ip_pim_ssm_prefix_list_cmd);
+ install_element(CONFIG_NODE, &ip_pim_register_suppress_cmd);
+ install_element(CONFIG_NODE, &no_ip_pim_register_suppress_cmd);
+ install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_cmd);
+ install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
+ install_element(CONFIG_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
+ install_element(CONFIG_NODE,
+ &no_ip_pim_spt_switchover_infinity_plist_cmd);
+ install_element(CONFIG_NODE, &ip_pim_joinprune_time_cmd);
+ install_element(CONFIG_NODE, &no_ip_pim_joinprune_time_cmd);
+ install_element(CONFIG_NODE, &ip_pim_keep_alive_cmd);
+ install_element(CONFIG_NODE, &no_ip_pim_keep_alive_cmd);
+ install_element(CONFIG_NODE, &ip_pim_packets_cmd);
+ install_element(CONFIG_NODE, &no_ip_pim_packets_cmd);
+ install_element(CONFIG_NODE, &ip_pim_v6_secondary_cmd);
+ install_element(CONFIG_NODE, &no_ip_pim_v6_secondary_cmd);
+ install_element(CONFIG_NODE, &ip_ssmpingd_cmd);
+ install_element(CONFIG_NODE, &no_ip_ssmpingd_cmd);
+ install_element(CONFIG_NODE, &ip_msdp_peer_cmd);
+ install_element(CONFIG_NODE, &no_ip_msdp_peer_cmd);
+ install_element(CONFIG_NODE, &ip_pim_ecmp_cmd);
+ install_element(CONFIG_NODE, &no_ip_pim_ecmp_cmd);
+ install_element(CONFIG_NODE, &ip_pim_ecmp_rebalance_cmd);
+ install_element(CONFIG_NODE, &no_ip_pim_ecmp_rebalance_cmd);
+
+ install_element(INTERFACE_NODE, &interface_ip_igmp_cmd);
+ install_element(INTERFACE_NODE, &interface_no_ip_igmp_cmd);
+ install_element(INTERFACE_NODE, &interface_ip_igmp_join_cmd);
+ install_element(INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
+ install_element(INTERFACE_NODE, &interface_ip_igmp_version_cmd);
+ install_element(INTERFACE_NODE, &interface_no_ip_igmp_version_cmd);
+ install_element(INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
+ install_element(INTERFACE_NODE,
+ &interface_no_ip_igmp_query_interval_cmd);
+ install_element(INTERFACE_NODE,
+ &interface_ip_igmp_query_max_response_time_cmd);
+ install_element(INTERFACE_NODE,
+ &interface_no_ip_igmp_query_max_response_time_cmd);
+ install_element(INTERFACE_NODE,
+ &interface_ip_igmp_query_max_response_time_dsec_cmd);
+ install_element(INTERFACE_NODE,
+ &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
+ install_element(INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
+ install_element(INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
+ install_element(INTERFACE_NODE, &interface_ip_pim_sm_cmd);
+ install_element(INTERFACE_NODE, &interface_no_ip_pim_sm_cmd);
+ install_element(INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
+ install_element(INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
+ install_element(INTERFACE_NODE, &interface_ip_pim_hello_cmd);
+ install_element(INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
+
+ // Static mroutes NEB
+ install_element(INTERFACE_NODE, &interface_ip_mroute_cmd);
+ install_element(INTERFACE_NODE, &interface_ip_mroute_source_cmd);
+ install_element(INTERFACE_NODE, &interface_no_ip_mroute_cmd);
+ install_element(INTERFACE_NODE, &interface_no_ip_mroute_source_cmd);
+
+ install_element(VIEW_NODE, &show_ip_igmp_interface_cmd);
+ install_element(VIEW_NODE, &show_ip_igmp_join_cmd);
+ install_element(VIEW_NODE, &show_ip_igmp_groups_cmd);
+ install_element(VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
+ install_element(VIEW_NODE, &show_ip_igmp_sources_cmd);
+ install_element(VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_assert_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_assert_internal_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_assert_metric_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_interface_traffic_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_interface_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_join_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_local_membership_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_neighbor_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_rpf_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_secondary_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_state_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_upstream_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_rp_cmd);
+ install_element(VIEW_NODE, &show_ip_multicast_cmd);
+ install_element(VIEW_NODE, &show_ip_mroute_cmd);
+ install_element(VIEW_NODE, &show_ip_mroute_count_cmd);
+ install_element(VIEW_NODE, &show_ip_rib_cmd);
+ install_element(VIEW_NODE, &show_ip_ssmpingd_cmd);
+ install_element(VIEW_NODE, &show_debugging_pim_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_nexthop_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_nexthop_lookup_cmd);
+
+ install_element(ENABLE_NODE, &clear_ip_interfaces_cmd);
+ install_element(ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
+ install_element(ENABLE_NODE, &clear_ip_mroute_cmd);
+ install_element(ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
+ install_element(ENABLE_NODE, &clear_ip_pim_interface_traffic_cmd);
+ install_element(ENABLE_NODE, &clear_ip_pim_oil_cmd);
+
+ install_element(ENABLE_NODE, &debug_igmp_cmd);
+ install_element(ENABLE_NODE, &no_debug_igmp_cmd);
+ install_element(ENABLE_NODE, &debug_igmp_events_cmd);
+ install_element(ENABLE_NODE, &no_debug_igmp_events_cmd);
+ install_element(ENABLE_NODE, &debug_igmp_packets_cmd);
+ install_element(ENABLE_NODE, &no_debug_igmp_packets_cmd);
+ install_element(ENABLE_NODE, &debug_igmp_trace_cmd);
+ install_element(ENABLE_NODE, &no_debug_igmp_trace_cmd);
+ install_element(ENABLE_NODE, &debug_mroute_cmd);
+ install_element(ENABLE_NODE, &debug_mroute_detail_cmd);
+ install_element(ENABLE_NODE, &no_debug_mroute_cmd);
+ install_element(ENABLE_NODE, &no_debug_mroute_detail_cmd);
+ install_element(ENABLE_NODE, &debug_static_cmd);
+ install_element(ENABLE_NODE, &no_debug_static_cmd);
+ install_element(ENABLE_NODE, &debug_pim_cmd);
+ install_element(ENABLE_NODE, &no_debug_pim_cmd);
+ install_element(ENABLE_NODE, &debug_pim_events_cmd);
+ install_element(ENABLE_NODE, &no_debug_pim_events_cmd);
+ install_element(ENABLE_NODE, &debug_pim_packets_cmd);
+ install_element(ENABLE_NODE, &no_debug_pim_packets_cmd);
+ install_element(ENABLE_NODE, &debug_pim_packetdump_send_cmd);
+ install_element(ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
+ install_element(ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
+ install_element(ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
+ install_element(ENABLE_NODE, &debug_pim_trace_cmd);
+ install_element(ENABLE_NODE, &no_debug_pim_trace_cmd);
+ install_element(ENABLE_NODE, &debug_ssmpingd_cmd);
+ install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd);
+ install_element(ENABLE_NODE, &debug_pim_zebra_cmd);
+ install_element(ENABLE_NODE, &no_debug_pim_zebra_cmd);
+ install_element(ENABLE_NODE, &debug_msdp_cmd);
+ install_element(ENABLE_NODE, &no_debug_msdp_cmd);
+ install_element(ENABLE_NODE, &undebug_msdp_cmd);
+ install_element(ENABLE_NODE, &debug_msdp_events_cmd);
+ install_element(ENABLE_NODE, &no_debug_msdp_events_cmd);
+ install_element(ENABLE_NODE, &undebug_msdp_events_cmd);
+ install_element(ENABLE_NODE, &debug_msdp_packets_cmd);
+ install_element(ENABLE_NODE, &no_debug_msdp_packets_cmd);
+ install_element(ENABLE_NODE, &undebug_msdp_packets_cmd);
+
+ install_element(CONFIG_NODE, &debug_igmp_cmd);
+ install_element(CONFIG_NODE, &no_debug_igmp_cmd);
+ install_element(CONFIG_NODE, &debug_igmp_events_cmd);
+ install_element(CONFIG_NODE, &no_debug_igmp_events_cmd);
+ install_element(CONFIG_NODE, &debug_igmp_packets_cmd);
+ install_element(CONFIG_NODE, &no_debug_igmp_packets_cmd);
+ install_element(CONFIG_NODE, &debug_igmp_trace_cmd);
+ install_element(CONFIG_NODE, &no_debug_igmp_trace_cmd);
+ install_element(CONFIG_NODE, &debug_mroute_cmd);
+ install_element(CONFIG_NODE, &debug_mroute_detail_cmd);
+ install_element(CONFIG_NODE, &no_debug_mroute_cmd);
+ install_element(CONFIG_NODE, &no_debug_mroute_detail_cmd);
+ install_element(CONFIG_NODE, &debug_static_cmd);
+ install_element(CONFIG_NODE, &no_debug_static_cmd);
+ install_element(CONFIG_NODE, &debug_pim_cmd);
+ install_element(CONFIG_NODE, &no_debug_pim_cmd);
+ install_element(CONFIG_NODE, &debug_pim_events_cmd);
+ install_element(CONFIG_NODE, &no_debug_pim_events_cmd);
+ install_element(CONFIG_NODE, &debug_pim_packets_cmd);
+ install_element(CONFIG_NODE, &no_debug_pim_packets_cmd);
+ install_element(CONFIG_NODE, &debug_pim_trace_cmd);
+ install_element(CONFIG_NODE, &no_debug_pim_trace_cmd);
+ install_element(CONFIG_NODE, &debug_ssmpingd_cmd);
+ install_element(CONFIG_NODE, &no_debug_ssmpingd_cmd);
+ install_element(CONFIG_NODE, &debug_pim_zebra_cmd);
+ install_element(CONFIG_NODE, &no_debug_pim_zebra_cmd);
+ install_element(CONFIG_NODE, &debug_msdp_cmd);
+ install_element(CONFIG_NODE, &no_debug_msdp_cmd);
+ install_element(CONFIG_NODE, &undebug_msdp_cmd);
+ install_element(CONFIG_NODE, &debug_msdp_events_cmd);
+ install_element(CONFIG_NODE, &no_debug_msdp_events_cmd);
+ install_element(CONFIG_NODE, &undebug_msdp_events_cmd);
+ install_element(CONFIG_NODE, &debug_msdp_packets_cmd);
+ install_element(CONFIG_NODE, &no_debug_msdp_packets_cmd);
+ install_element(CONFIG_NODE, &undebug_msdp_packets_cmd);
+ install_element(CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
+ install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);
+ install_element(CONFIG_NODE, &ip_msdp_mesh_group_source_cmd);
+ install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_source_cmd);
+ install_element(VIEW_NODE, &show_ip_msdp_peer_detail_cmd);
+ install_element(VIEW_NODE, &show_ip_msdp_sa_detail_cmd);
+ install_element(VIEW_NODE, &show_ip_msdp_sa_sg_cmd);
+ install_element(VIEW_NODE, &show_ip_msdp_mesh_group_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_ssm_range_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_group_type_cmd);
+ install_element(INTERFACE_NODE, &interface_pim_use_source_cmd);
+ install_element(INTERFACE_NODE, &interface_no_pim_use_source_cmd);
+ /* Install BFD command */
+ install_element(INTERFACE_NODE, &ip_pim_bfd_cmd);
+ install_element(INTERFACE_NODE, &ip_pim_bfd_param_cmd);
+ install_element(INTERFACE_NODE, &no_ip_pim_bfd_cmd);
+ install_element(INTERFACE_NODE, &no_ip_pim_bfd_param_cmd);
}
diff --git a/pimd/pim_hello.c b/pimd/pim_hello.c
index 0c08cfa46..2592514f3 100644
--- a/pimd/pim_hello.c
+++ b/pimd/pim_hello.c
@@ -32,71 +32,66 @@
#include "pim_neighbor.h"
#include "pim_upstream.h"
-static void on_trace(const char *label,
- struct interface *ifp, struct in_addr src)
+static void on_trace(const char *label, struct interface *ifp,
+ struct in_addr src)
{
- if (PIM_DEBUG_PIM_TRACE) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src, src_str, sizeof(src_str));
- zlog_debug("%s: from %s on %s",
- label, src_str, ifp->name);
- }
+ if (PIM_DEBUG_PIM_TRACE) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src, src_str, sizeof(src_str));
+ zlog_debug("%s: from %s on %s", label, src_str, ifp->name);
+ }
}
static void tlv_trace_bool(const char *label, const char *tlv_name,
const char *ifname, struct in_addr src_addr,
int isset, int value)
{
- if (isset) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_debug("%s: PIM hello option from %s on interface %s: %s=%d",
- label,
- src_str, ifname,
- tlv_name, value);
- }
+ if (isset) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ zlog_debug(
+ "%s: PIM hello option from %s on interface %s: %s=%d",
+ label, src_str, ifname, tlv_name, value);
+ }
}
static void tlv_trace_uint16(const char *label, const char *tlv_name,
const char *ifname, struct in_addr src_addr,
int isset, uint16_t value)
{
- if (isset) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_debug("%s: PIM hello option from %s on interface %s: %s=%u",
- label,
- src_str, ifname,
- tlv_name, value);
- }
+ if (isset) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ zlog_debug(
+ "%s: PIM hello option from %s on interface %s: %s=%u",
+ label, src_str, ifname, tlv_name, value);
+ }
}
static void tlv_trace_uint32(const char *label, const char *tlv_name,
const char *ifname, struct in_addr src_addr,
int isset, uint32_t value)
{
- if (isset) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_debug("%s: PIM hello option from %s on interface %s: %s=%u",
- label,
- src_str, ifname,
- tlv_name, value);
- }
+ if (isset) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ zlog_debug(
+ "%s: PIM hello option from %s on interface %s: %s=%u",
+ label, src_str, ifname, tlv_name, value);
+ }
}
static void tlv_trace_uint32_hex(const char *label, const char *tlv_name,
const char *ifname, struct in_addr src_addr,
int isset, uint32_t value)
{
- if (isset) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_debug("%s: PIM hello option from %s on interface %s: %s=%08x",
- label,
- src_str, ifname,
- tlv_name, value);
- }
+ if (isset) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ zlog_debug(
+ "%s: PIM hello option from %s on interface %s: %s=%08x",
+ label, src_str, ifname, tlv_name, value);
+ }
}
#if 0
@@ -119,418 +114,423 @@ static void tlv_trace_list(const char *label, const char *tlv_name,
const char *ifname, struct in_addr src_addr,
int isset, struct list *addr_list)
{
- if (isset) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_debug("%s: PIM hello option from %s on interface %s: %s size=%d list=%p",
- label,
- src_str, ifname,
- tlv_name,
- addr_list ? ((int) listcount(addr_list)) : -1,
- (void *) addr_list);
- }
+ if (isset) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ zlog_debug(
+ "%s: PIM hello option from %s on interface %s: %s size=%d list=%p",
+ label, src_str, ifname, tlv_name,
+ addr_list ? ((int)listcount(addr_list)) : -1,
+ (void *)addr_list);
+ }
}
-#define FREE_ADDR_LIST \
- if (hello_option_addr_list) { \
- list_delete(hello_option_addr_list); \
- }
+#define FREE_ADDR_LIST \
+ if (hello_option_addr_list) { \
+ list_delete(hello_option_addr_list); \
+ }
-#define FREE_ADDR_LIST_THEN_RETURN(code) \
-{ \
- FREE_ADDR_LIST \
- return (code); \
-}
+#define FREE_ADDR_LIST_THEN_RETURN(code) \
+ { \
+ FREE_ADDR_LIST \
+ return (code); \
+ }
-int pim_hello_recv(struct interface *ifp,
- struct in_addr src_addr,
+int pim_hello_recv(struct interface *ifp, struct in_addr src_addr,
uint8_t *tlv_buf, int tlv_buf_size)
{
- struct pim_interface *pim_ifp;
- struct pim_neighbor *neigh;
- uint8_t *tlv_curr;
- uint8_t *tlv_pastend;
- pim_hello_options hello_options = 0; /* bit array recording options found */
- uint16_t hello_option_holdtime = 0;
- uint16_t hello_option_propagation_delay = 0;
- uint16_t hello_option_override_interval = 0;
- uint32_t hello_option_dr_priority = 0;
- uint32_t hello_option_generation_id = 0;
- struct list *hello_option_addr_list = 0;
-
- if (PIM_DEBUG_PIM_HELLO)
- on_trace(__PRETTY_FUNCTION__, ifp, src_addr);
-
- pim_ifp = ifp->info;
- zassert(pim_ifp);
-
- ++pim_ifp->pim_ifstat_hello_recv;
-
- /*
- Parse PIM hello TLVs
- */
- zassert(tlv_buf_size >= 0);
- tlv_curr = tlv_buf;
- tlv_pastend = tlv_buf + tlv_buf_size;
-
- while (tlv_curr < tlv_pastend) {
- uint16_t option_type;
- uint16_t option_len;
- int remain = tlv_pastend - tlv_curr;
-
- if (remain < PIM_TLV_MIN_SIZE) {
- if (PIM_DEBUG_PIM_HELLO) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_debug("%s: short PIM hello TLV size=%d < min=%d from %s on interface %s",
- __PRETTY_FUNCTION__,
- remain, PIM_TLV_MIN_SIZE,
- src_str, ifp->name);
- }
- FREE_ADDR_LIST_THEN_RETURN(-1);
- }
-
- option_type = PIM_TLV_GET_TYPE(tlv_curr);
- tlv_curr += PIM_TLV_TYPE_SIZE;
- option_len = PIM_TLV_GET_LENGTH(tlv_curr);
- tlv_curr += PIM_TLV_LENGTH_SIZE;
-
- if ((tlv_curr + option_len) > tlv_pastend) {
- if (PIM_DEBUG_PIM_HELLO) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_debug("%s: long PIM hello TLV type=%d length=%d > left=%td from %s on interface %s",
- __PRETTY_FUNCTION__,
- option_type, option_len, tlv_pastend - tlv_curr,
- src_str, ifp->name);
- }
- FREE_ADDR_LIST_THEN_RETURN(-2);
- }
-
- if (PIM_DEBUG_PIM_HELLO) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_debug("%s: parse left_size=%d: PIM hello TLV type=%d length=%d from %s on %s",
- __PRETTY_FUNCTION__,
- remain,
- option_type, option_len,
- src_str, ifp->name);
- }
-
- switch (option_type) {
- case PIM_MSG_OPTION_TYPE_HOLDTIME:
- if (pim_tlv_parse_holdtime(ifp->name, src_addr,
- &hello_options,
- &hello_option_holdtime,
- option_len,
- tlv_curr)) {
- FREE_ADDR_LIST_THEN_RETURN(-3);
- }
- break;
- case PIM_MSG_OPTION_TYPE_LAN_PRUNE_DELAY:
- if (pim_tlv_parse_lan_prune_delay(ifp->name, src_addr,
- &hello_options,
- &hello_option_propagation_delay,
- &hello_option_override_interval,
- option_len,
- tlv_curr)) {
- FREE_ADDR_LIST_THEN_RETURN(-4);
- }
- break;
- case PIM_MSG_OPTION_TYPE_DR_PRIORITY:
- if (pim_tlv_parse_dr_priority(ifp->name, src_addr,
- &hello_options,
- &hello_option_dr_priority,
- option_len,
+ struct pim_interface *pim_ifp;
+ struct pim_neighbor *neigh;
+ uint8_t *tlv_curr;
+ uint8_t *tlv_pastend;
+ pim_hello_options hello_options =
+ 0; /* bit array recording options found */
+ uint16_t hello_option_holdtime = 0;
+ uint16_t hello_option_propagation_delay = 0;
+ uint16_t hello_option_override_interval = 0;
+ uint32_t hello_option_dr_priority = 0;
+ uint32_t hello_option_generation_id = 0;
+ struct list *hello_option_addr_list = 0;
+
+ if (PIM_DEBUG_PIM_HELLO)
+ on_trace(__PRETTY_FUNCTION__, ifp, src_addr);
+
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+
+ ++pim_ifp->pim_ifstat_hello_recv;
+
+ /*
+ Parse PIM hello TLVs
+ */
+ zassert(tlv_buf_size >= 0);
+ tlv_curr = tlv_buf;
+ tlv_pastend = tlv_buf + tlv_buf_size;
+
+ while (tlv_curr < tlv_pastend) {
+ uint16_t option_type;
+ uint16_t option_len;
+ int remain = tlv_pastend - tlv_curr;
+
+ if (remain < PIM_TLV_MIN_SIZE) {
+ if (PIM_DEBUG_PIM_HELLO) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str,
+ sizeof(src_str));
+ zlog_debug(
+ "%s: short PIM hello TLV size=%d < min=%d from %s on interface %s",
+ __PRETTY_FUNCTION__, remain,
+ PIM_TLV_MIN_SIZE, src_str, ifp->name);
+ }
+ FREE_ADDR_LIST_THEN_RETURN(-1);
+ }
+
+ option_type = PIM_TLV_GET_TYPE(tlv_curr);
+ tlv_curr += PIM_TLV_TYPE_SIZE;
+ option_len = PIM_TLV_GET_LENGTH(tlv_curr);
+ tlv_curr += PIM_TLV_LENGTH_SIZE;
+
+ if ((tlv_curr + option_len) > tlv_pastend) {
+ if (PIM_DEBUG_PIM_HELLO) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str,
+ sizeof(src_str));
+ zlog_debug(
+ "%s: long PIM hello TLV type=%d length=%d > left=%td from %s on interface %s",
+ __PRETTY_FUNCTION__, option_type,
+ option_len, tlv_pastend - tlv_curr,
+ src_str, ifp->name);
+ }
+ FREE_ADDR_LIST_THEN_RETURN(-2);
+ }
+
+ if (PIM_DEBUG_PIM_HELLO) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str,
+ sizeof(src_str));
+ zlog_debug(
+ "%s: parse left_size=%d: PIM hello TLV type=%d length=%d from %s on %s",
+ __PRETTY_FUNCTION__, remain, option_type,
+ option_len, src_str, ifp->name);
+ }
+
+ switch (option_type) {
+ case PIM_MSG_OPTION_TYPE_HOLDTIME:
+ if (pim_tlv_parse_holdtime(ifp->name, src_addr,
+ &hello_options,
+ &hello_option_holdtime,
+ option_len, tlv_curr)) {
+ FREE_ADDR_LIST_THEN_RETURN(-3);
+ }
+ break;
+ case PIM_MSG_OPTION_TYPE_LAN_PRUNE_DELAY:
+ if (pim_tlv_parse_lan_prune_delay(
+ ifp->name, src_addr, &hello_options,
+ &hello_option_propagation_delay,
+ &hello_option_override_interval, option_len,
tlv_curr)) {
- FREE_ADDR_LIST_THEN_RETURN(-5);
- }
- break;
- case PIM_MSG_OPTION_TYPE_GENERATION_ID:
- if (pim_tlv_parse_generation_id(ifp->name, src_addr,
- &hello_options,
- &hello_option_generation_id,
- option_len,
- tlv_curr)) {
- FREE_ADDR_LIST_THEN_RETURN(-6);
- }
- break;
- case PIM_MSG_OPTION_TYPE_ADDRESS_LIST:
- if (pim_tlv_parse_addr_list(ifp->name, src_addr,
- &hello_options,
- &hello_option_addr_list,
- option_len,
- tlv_curr)) {
- return -7;
- }
- break;
- case PIM_MSG_OPTION_TYPE_DM_STATE_REFRESH:
- if (PIM_DEBUG_PIM_HELLO) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_debug("%s: ignoring PIM hello dense-mode state refresh TLV option type=%d length=%d from %s on interface %s",
- __PRETTY_FUNCTION__,
- option_type, option_len,
- src_str, ifp->name);
- }
- break;
- default:
- if (PIM_DEBUG_PIM_HELLO) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_debug("%s: ignoring unknown PIM hello TLV type=%d length=%d from %s on interface %s",
- __PRETTY_FUNCTION__,
- option_type, option_len,
- src_str, ifp->name);
- }
- }
-
- tlv_curr += option_len;
- }
+ FREE_ADDR_LIST_THEN_RETURN(-4);
+ }
+ break;
+ case PIM_MSG_OPTION_TYPE_DR_PRIORITY:
+ if (pim_tlv_parse_dr_priority(ifp->name, src_addr,
+ &hello_options,
+ &hello_option_dr_priority,
+ option_len, tlv_curr)) {
+ FREE_ADDR_LIST_THEN_RETURN(-5);
+ }
+ break;
+ case PIM_MSG_OPTION_TYPE_GENERATION_ID:
+ if (pim_tlv_parse_generation_id(
+ ifp->name, src_addr, &hello_options,
+ &hello_option_generation_id, option_len,
+ tlv_curr)) {
+ FREE_ADDR_LIST_THEN_RETURN(-6);
+ }
+ break;
+ case PIM_MSG_OPTION_TYPE_ADDRESS_LIST:
+ if (pim_tlv_parse_addr_list(ifp->name, src_addr,
+ &hello_options,
+ &hello_option_addr_list,
+ option_len, tlv_curr)) {
+ return -7;
+ }
+ break;
+ case PIM_MSG_OPTION_TYPE_DM_STATE_REFRESH:
+ if (PIM_DEBUG_PIM_HELLO) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str,
+ sizeof(src_str));
+ zlog_debug(
+ "%s: ignoring PIM hello dense-mode state refresh TLV option type=%d length=%d from %s on interface %s",
+ __PRETTY_FUNCTION__, option_type,
+ option_len, src_str, ifp->name);
+ }
+ break;
+ default:
+ if (PIM_DEBUG_PIM_HELLO) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str,
+ sizeof(src_str));
+ zlog_debug(
+ "%s: ignoring unknown PIM hello TLV type=%d length=%d from %s on interface %s",
+ __PRETTY_FUNCTION__, option_type,
+ option_len, src_str, ifp->name);
+ }
+ }
+
+ tlv_curr += option_len;
+ }
- /*
- Check received PIM hello options
- */
-
- if (PIM_DEBUG_PIM_HELLO) {
- tlv_trace_uint16(__PRETTY_FUNCTION__, "holdtime",
- ifp->name, src_addr,
- PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_HOLDTIME),
- hello_option_holdtime);
- tlv_trace_uint16(__PRETTY_FUNCTION__, "propagation_delay",
- ifp->name, src_addr,
- PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY),
- hello_option_propagation_delay);
- tlv_trace_uint16(__PRETTY_FUNCTION__, "override_interval",
- ifp->name, src_addr,
- PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY),
- hello_option_override_interval);
- tlv_trace_bool(__PRETTY_FUNCTION__, "can_disable_join_suppression",
- ifp->name, src_addr,
- PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY),
- PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION));
- tlv_trace_uint32(__PRETTY_FUNCTION__, "dr_priority",
- ifp->name, src_addr,
- PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_DR_PRIORITY),
- hello_option_dr_priority);
- tlv_trace_uint32_hex(__PRETTY_FUNCTION__, "generation_id",
- ifp->name, src_addr,
- PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_GENERATION_ID),
- hello_option_generation_id);
- tlv_trace_list(__PRETTY_FUNCTION__, "address_list",
- ifp->name, src_addr,
- PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_ADDRESS_LIST),
- hello_option_addr_list);
- }
+ /*
+ Check received PIM hello options
+ */
- if (!PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_HOLDTIME)) {
- if (PIM_DEBUG_PIM_HELLO) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_debug("%s: PIM hello missing holdtime from %s on interface %s",
- __PRETTY_FUNCTION__,
- src_str, ifp->name);
- }
- }
+ if (PIM_DEBUG_PIM_HELLO) {
+ tlv_trace_uint16(__PRETTY_FUNCTION__, "holdtime", ifp->name,
+ src_addr,
+ PIM_OPTION_IS_SET(hello_options,
+ PIM_OPTION_MASK_HOLDTIME),
+ hello_option_holdtime);
+ tlv_trace_uint16(
+ __PRETTY_FUNCTION__, "propagation_delay", ifp->name,
+ src_addr,
+ PIM_OPTION_IS_SET(hello_options,
+ PIM_OPTION_MASK_LAN_PRUNE_DELAY),
+ hello_option_propagation_delay);
+ tlv_trace_uint16(
+ __PRETTY_FUNCTION__, "override_interval", ifp->name,
+ src_addr,
+ PIM_OPTION_IS_SET(hello_options,
+ PIM_OPTION_MASK_LAN_PRUNE_DELAY),
+ hello_option_override_interval);
+ tlv_trace_bool(
+ __PRETTY_FUNCTION__, "can_disable_join_suppression",
+ ifp->name, src_addr,
+ PIM_OPTION_IS_SET(hello_options,
+ PIM_OPTION_MASK_LAN_PRUNE_DELAY),
+ PIM_OPTION_IS_SET(
+ hello_options,
+ PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION));
+ tlv_trace_uint32(__PRETTY_FUNCTION__, "dr_priority", ifp->name,
+ src_addr,
+ PIM_OPTION_IS_SET(hello_options,
+ PIM_OPTION_MASK_DR_PRIORITY),
+ hello_option_dr_priority);
+ tlv_trace_uint32_hex(
+ __PRETTY_FUNCTION__, "generation_id", ifp->name,
+ src_addr,
+ PIM_OPTION_IS_SET(hello_options,
+ PIM_OPTION_MASK_GENERATION_ID),
+ hello_option_generation_id);
+ tlv_trace_list(__PRETTY_FUNCTION__, "address_list", ifp->name,
+ src_addr,
+ PIM_OPTION_IS_SET(hello_options,
+ PIM_OPTION_MASK_ADDRESS_LIST),
+ hello_option_addr_list);
+ }
- /*
- New neighbor?
- */
-
- neigh = pim_neighbor_find(ifp, src_addr);
- if (!neigh) {
- /* Add as new neighbor */
-
- neigh = pim_neighbor_add(ifp, src_addr,
- hello_options,
- hello_option_holdtime,
- hello_option_propagation_delay,
- hello_option_override_interval,
- hello_option_dr_priority,
- hello_option_generation_id,
- hello_option_addr_list,
- PIM_NEIGHBOR_SEND_DELAY);
- if (!neigh) {
- if (PIM_DEBUG_PIM_HELLO) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_warn("%s: failure creating PIM neighbor %s on interface %s",
- __PRETTY_FUNCTION__,
- src_str, ifp->name);
- }
- FREE_ADDR_LIST_THEN_RETURN(-8);
- }
-
- /* actual addr list has been saved under neighbor */
- return 0;
- }
+ if (!PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_HOLDTIME)) {
+ if (PIM_DEBUG_PIM_HELLO) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str,
+ sizeof(src_str));
+ zlog_debug(
+ "%s: PIM hello missing holdtime from %s on interface %s",
+ __PRETTY_FUNCTION__, src_str, ifp->name);
+ }
+ }
- /*
- Received generation ID ?
- */
-
- if (PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_GENERATION_ID)) {
- /* GenID mismatch ? */
- if (!PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_GENERATION_ID) ||
- (hello_option_generation_id != neigh->generation_id)) {
- /* GenID mismatch, then replace neighbor */
-
- if (PIM_DEBUG_PIM_HELLO) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_debug("%s: GenId mismatch new=%08x old=%08x: replacing neighbor %s on %s",
- __PRETTY_FUNCTION__,
- hello_option_generation_id,
- neigh->generation_id,
- src_str, ifp->name);
- }
-
- pim_upstream_rpf_genid_changed(neigh->source_addr);
-
- pim_neighbor_delete(ifp, neigh, "GenID mismatch");
- neigh = pim_neighbor_add(ifp, src_addr,
- hello_options,
- hello_option_holdtime,
- hello_option_propagation_delay,
- hello_option_override_interval,
- hello_option_dr_priority,
- hello_option_generation_id,
- hello_option_addr_list,
- PIM_NEIGHBOR_SEND_NOW);
- if (!neigh) {
- if (PIM_DEBUG_PIM_HELLO) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_debug("%s: failure re-creating PIM neighbor %s on interface %s",
- __PRETTY_FUNCTION__,
- src_str, ifp->name);
+ /*
+ New neighbor?
+ */
+
+ neigh = pim_neighbor_find(ifp, src_addr);
+ if (!neigh) {
+ /* Add as new neighbor */
+
+ neigh = pim_neighbor_add(
+ ifp, src_addr, hello_options, hello_option_holdtime,
+ hello_option_propagation_delay,
+ hello_option_override_interval,
+ hello_option_dr_priority, hello_option_generation_id,
+ hello_option_addr_list, PIM_NEIGHBOR_SEND_DELAY);
+ if (!neigh) {
+ if (PIM_DEBUG_PIM_HELLO) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str,
+ sizeof(src_str));
+ zlog_warn(
+ "%s: failure creating PIM neighbor %s on interface %s",
+ __PRETTY_FUNCTION__, src_str,
+ ifp->name);
+ }
+ FREE_ADDR_LIST_THEN_RETURN(-8);
+ }
+
+ /* actual addr list has been saved under neighbor */
+ return 0;
}
- FREE_ADDR_LIST_THEN_RETURN(-9);
- }
- /* actual addr list is saved under neighbor */
- return 0;
-
- } /* GenId mismatch: replace neighbor */
-
- } /* GenId received */
-
- /*
- Update existing neighbor
- */
-
- pim_neighbor_update(neigh,
- hello_options,
- hello_option_holdtime,
- hello_option_dr_priority,
- hello_option_addr_list);
- /* actual addr list is saved under neighbor */
- return 0;
+
+ /*
+ Received generation ID ?
+ */
+
+ if (PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_GENERATION_ID)) {
+ /* GenID mismatch ? */
+ if (!PIM_OPTION_IS_SET(neigh->hello_options,
+ PIM_OPTION_MASK_GENERATION_ID)
+ || (hello_option_generation_id != neigh->generation_id)) {
+ /* GenID mismatch, then replace neighbor */
+
+ if (PIM_DEBUG_PIM_HELLO) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str,
+ sizeof(src_str));
+ zlog_debug(
+ "%s: GenId mismatch new=%08x old=%08x: replacing neighbor %s on %s",
+ __PRETTY_FUNCTION__,
+ hello_option_generation_id,
+ neigh->generation_id, src_str,
+ ifp->name);
+ }
+
+ pim_upstream_rpf_genid_changed(neigh->source_addr);
+
+ pim_neighbor_delete(ifp, neigh, "GenID mismatch");
+ neigh = pim_neighbor_add(ifp, src_addr, hello_options,
+ hello_option_holdtime,
+ hello_option_propagation_delay,
+ hello_option_override_interval,
+ hello_option_dr_priority,
+ hello_option_generation_id,
+ hello_option_addr_list,
+ PIM_NEIGHBOR_SEND_NOW);
+ if (!neigh) {
+ if (PIM_DEBUG_PIM_HELLO) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr,
+ src_str,
+ sizeof(src_str));
+ zlog_debug(
+ "%s: failure re-creating PIM neighbor %s on interface %s",
+ __PRETTY_FUNCTION__, src_str,
+ ifp->name);
+ }
+ FREE_ADDR_LIST_THEN_RETURN(-9);
+ }
+ /* actual addr list is saved under neighbor */
+ return 0;
+
+ } /* GenId mismatch: replace neighbor */
+
+ } /* GenId received */
+
+ /*
+ Update existing neighbor
+ */
+
+ pim_neighbor_update(neigh, hello_options, hello_option_holdtime,
+ hello_option_dr_priority, hello_option_addr_list);
+ /* actual addr list is saved under neighbor */
+ return 0;
}
-int pim_hello_build_tlv(struct interface *ifp,
- uint8_t *tlv_buf, int tlv_buf_size,
- uint16_t holdtime,
- uint32_t dr_priority,
- uint32_t generation_id,
- uint16_t propagation_delay,
- uint16_t override_interval,
+int pim_hello_build_tlv(struct interface *ifp, uint8_t *tlv_buf,
+ int tlv_buf_size, uint16_t holdtime,
+ uint32_t dr_priority, uint32_t generation_id,
+ uint16_t propagation_delay, uint16_t override_interval,
int can_disable_join_suppression)
{
- uint8_t *curr = tlv_buf;
- uint8_t *pastend = tlv_buf + tlv_buf_size;
- uint8_t *tmp;
-
- /*
- * Append options
- */
-
- /* Holdtime */
- curr = pim_tlv_append_uint16(curr,
- pastend,
- PIM_MSG_OPTION_TYPE_HOLDTIME,
- holdtime);
- if (!curr) {
- if (PIM_DEBUG_PIM_HELLO) {
- zlog_debug("%s: could not set PIM hello Holdtime option for interface %s",
- __PRETTY_FUNCTION__, ifp->name);
- }
- return -1;
- }
+ uint8_t *curr = tlv_buf;
+ uint8_t *pastend = tlv_buf + tlv_buf_size;
+ uint8_t *tmp;
+
+ /*
+ * Append options
+ */
+
+ /* Holdtime */
+ curr = pim_tlv_append_uint16(curr, pastend,
+ PIM_MSG_OPTION_TYPE_HOLDTIME, holdtime);
+ if (!curr) {
+ if (PIM_DEBUG_PIM_HELLO) {
+ zlog_debug(
+ "%s: could not set PIM hello Holdtime option for interface %s",
+ __PRETTY_FUNCTION__, ifp->name);
+ }
+ return -1;
+ }
- /* LAN Prune Delay */
- tmp = pim_tlv_append_2uint16(curr,
- pastend,
- PIM_MSG_OPTION_TYPE_LAN_PRUNE_DELAY,
- propagation_delay,
- override_interval);
- if (!tmp) {
- if (PIM_DEBUG_PIM_HELLO) {
- zlog_debug("%s: could not set PIM LAN Prune Delay option for interface %s",
- __PRETTY_FUNCTION__, ifp->name);
- }
- return -1;
- }
- if (can_disable_join_suppression) {
- *((uint8_t*)(curr) + 4) |= 0x80; /* enable T bit */
- }
- curr = tmp;
-
- /* DR Priority */
- curr = pim_tlv_append_uint32(curr,
- pastend,
- PIM_MSG_OPTION_TYPE_DR_PRIORITY,
- dr_priority);
- if (!curr) {
- if (PIM_DEBUG_PIM_HELLO) {
- zlog_debug("%s: could not set PIM hello DR Priority option for interface %s",
- __PRETTY_FUNCTION__, ifp->name);
- }
- return -2;
- }
+ /* LAN Prune Delay */
+ tmp = pim_tlv_append_2uint16(curr, pastend,
+ PIM_MSG_OPTION_TYPE_LAN_PRUNE_DELAY,
+ propagation_delay, override_interval);
+ if (!tmp) {
+ if (PIM_DEBUG_PIM_HELLO) {
+ zlog_debug(
+ "%s: could not set PIM LAN Prune Delay option for interface %s",
+ __PRETTY_FUNCTION__, ifp->name);
+ }
+ return -1;
+ }
+ if (can_disable_join_suppression) {
+ *((uint8_t *)(curr) + 4) |= 0x80; /* enable T bit */
+ }
+ curr = tmp;
+
+ /* DR Priority */
+ curr = pim_tlv_append_uint32(
+ curr, pastend, PIM_MSG_OPTION_TYPE_DR_PRIORITY, dr_priority);
+ if (!curr) {
+ if (PIM_DEBUG_PIM_HELLO) {
+ zlog_debug(
+ "%s: could not set PIM hello DR Priority option for interface %s",
+ __PRETTY_FUNCTION__, ifp->name);
+ }
+ return -2;
+ }
- /* Generation ID */
- curr = pim_tlv_append_uint32(curr,
- pastend,
- PIM_MSG_OPTION_TYPE_GENERATION_ID,
- generation_id);
- if (!curr) {
- if (PIM_DEBUG_PIM_HELLO) {
- zlog_debug("%s: could not set PIM hello Generation ID option for interface %s",
- __PRETTY_FUNCTION__, ifp->name);
- }
- return -3;
- }
+ /* Generation ID */
+ curr = pim_tlv_append_uint32(curr, pastend,
+ PIM_MSG_OPTION_TYPE_GENERATION_ID,
+ generation_id);
+ if (!curr) {
+ if (PIM_DEBUG_PIM_HELLO) {
+ zlog_debug(
+ "%s: could not set PIM hello Generation ID option for interface %s",
+ __PRETTY_FUNCTION__, ifp->name);
+ }
+ return -3;
+ }
- /* Secondary Address List */
- if (ifp->connected->count) {
- curr = pim_tlv_append_addrlist_ucast(curr,
- pastend,
- ifp->connected,
- AF_INET);
- if (!curr) {
- if (PIM_DEBUG_PIM_HELLO) {
- zlog_debug("%s: could not set PIM hello v4 Secondary Address List option for interface %s",
- __PRETTY_FUNCTION__, ifp->name);
- }
- return -4;
- }
- if (pimg->send_v6_secondary)
- {
- curr = pim_tlv_append_addrlist_ucast(curr,
- pastend,
- ifp->connected,
- AF_INET6);
- if (!curr) {
- if (PIM_DEBUG_PIM_HELLO) {
- zlog_debug("%s: could not sent PIM hello v6 secondary Address List option for interface %s",
- __PRETTY_FUNCTION__, ifp->name);
- }
- return -4;
- }
- }
- }
+ /* Secondary Address List */
+ if (ifp->connected->count) {
+ curr = pim_tlv_append_addrlist_ucast(curr, pastend,
+ ifp->connected, AF_INET);
+ if (!curr) {
+ if (PIM_DEBUG_PIM_HELLO) {
+ zlog_debug(
+ "%s: could not set PIM hello v4 Secondary Address List option for interface %s",
+ __PRETTY_FUNCTION__, ifp->name);
+ }
+ return -4;
+ }
+ if (pimg->send_v6_secondary) {
+ curr = pim_tlv_append_addrlist_ucast(
+ curr, pastend, ifp->connected, AF_INET6);
+ if (!curr) {
+ if (PIM_DEBUG_PIM_HELLO) {
+ zlog_debug(
+ "%s: could not sent PIM hello v6 secondary Address List option for interface %s",
+ __PRETTY_FUNCTION__, ifp->name);
+ }
+ return -4;
+ }
+ }
+ }
- return curr - tlv_buf;
+ return curr - tlv_buf;
}
/*
@@ -544,16 +544,16 @@ int pim_hello_build_tlv(struct interface *ifp,
*/
void pim_hello_require(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
+ struct pim_interface *pim_ifp;
- zassert(ifp);
+ zassert(ifp);
- pim_ifp = ifp->info;
+ pim_ifp = ifp->info;
- zassert(pim_ifp);
+ zassert(pim_ifp);
- if (pim_ifp->pim_ifstat_hello_sent)
- return;
+ if (pim_ifp->pim_ifstat_hello_sent)
+ return;
- pim_hello_restart_now(ifp); /* Send hello and restart timer */
+ pim_hello_restart_now(ifp); /* Send hello and restart timer */
}
diff --git a/pimd/pim_hello.h b/pimd/pim_hello.h
index ff799b20f..df41f97d9 100644
--- a/pimd/pim_hello.h
+++ b/pimd/pim_hello.h
@@ -24,17 +24,13 @@
#include "if.h"
-int pim_hello_recv(struct interface *ifp,
- struct in_addr src_addr,
+int pim_hello_recv(struct interface *ifp, struct in_addr src_addr,
uint8_t *tlv_buf, int tlv_buf_size);
-int pim_hello_build_tlv(struct interface *ifp,
- uint8_t *tlv_buf, int tlv_buf_size,
- uint16_t holdtime,
- uint32_t dr_priority,
- uint32_t generation_id,
- uint16_t propagation_delay,
- uint16_t override_interval,
+int pim_hello_build_tlv(struct interface *ifp, uint8_t *tlv_buf,
+ int tlv_buf_size, uint16_t holdtime,
+ uint32_t dr_priority, uint32_t generation_id,
+ uint16_t propagation_delay, uint16_t override_interval,
int can_disable_join_suppression);
void pim_hello_require(struct interface *ifp);
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index f4125af9b..820162524 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -50,907 +50,919 @@ static int pim_iface_vif_index[MAXVIFS];
static void pim_if_igmp_join_del_all(struct interface *ifp);
static int igmp_join_sock(const char *ifname, ifindex_t ifindex,
- struct in_addr group_addr, struct in_addr source_addr);
+ struct in_addr group_addr,
+ struct in_addr source_addr);
-void
-pim_if_init (void)
+void pim_if_init(void)
{
- int i;
+ int i;
- for (i = 0; i < MAXVIFS; i++)
- pim_iface_vif_index[i] = 0;
+ for (i = 0; i < MAXVIFS; i++)
+ pim_iface_vif_index[i] = 0;
- pim_ifchannel_list = list_new();
- pim_ifchannel_list->cmp = (int (*)(void *, void *))pim_ifchannel_compare;
+ pim_ifchannel_list = list_new();
+ pim_ifchannel_list->cmp =
+ (int (*)(void *, void *))pim_ifchannel_compare;
}
-void
-pim_if_terminate (void)
+void pim_if_terminate(void)
{
- if (pim_ifchannel_list)
- list_free (pim_ifchannel_list);
+ if (pim_ifchannel_list)
+ list_free(pim_ifchannel_list);
}
static void *if_list_clean(struct pim_interface *pim_ifp)
{
- if (pim_ifp->igmp_join_list) {
- list_delete(pim_ifp->igmp_join_list);
- }
+ if (pim_ifp->igmp_join_list) {
+ list_delete(pim_ifp->igmp_join_list);
+ }
- if (pim_ifp->igmp_socket_list) {
- list_delete(pim_ifp->igmp_socket_list);
- }
+ if (pim_ifp->igmp_socket_list) {
+ list_delete(pim_ifp->igmp_socket_list);
+ }
- if (pim_ifp->pim_neighbor_list) {
- list_delete(pim_ifp->pim_neighbor_list);
- }
+ if (pim_ifp->pim_neighbor_list) {
+ list_delete(pim_ifp->pim_neighbor_list);
+ }
- if (pim_ifp->upstream_switch_list)
- list_delete(pim_ifp->upstream_switch_list);
+ if (pim_ifp->upstream_switch_list)
+ list_delete(pim_ifp->upstream_switch_list);
- if (pim_ifp->pim_ifchannel_list) {
- list_delete(pim_ifp->pim_ifchannel_list);
- }
+ if (pim_ifp->pim_ifchannel_list) {
+ list_delete(pim_ifp->pim_ifchannel_list);
+ }
- if (pim_ifp->pim_ifchannel_hash)
- hash_free(pim_ifp->pim_ifchannel_hash);
+ if (pim_ifp->pim_ifchannel_hash)
+ hash_free(pim_ifp->pim_ifchannel_hash);
- XFREE(MTYPE_PIM_INTERFACE, pim_ifp);
+ XFREE(MTYPE_PIM_INTERFACE, pim_ifp);
- return 0;
+ return 0;
}
struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim)
{
- struct pim_interface *pim_ifp;
-
- zassert(ifp);
- zassert(!ifp->info);
-
- pim_ifp = XCALLOC(MTYPE_PIM_INTERFACE, sizeof(*pim_ifp));
- if (!pim_ifp) {
- zlog_err("PIM XCALLOC(%zu) failure", sizeof(*pim_ifp));
- return 0;
- }
-
- pim_ifp->options = 0;
- pim_ifp->mroute_vif_index = -1;
-
- pim_ifp->igmp_version = IGMP_DEFAULT_VERSION;
- 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
- The number of seconds represented by the [Query Response Interval]
- must be less than the [Query Interval].
- */
- zassert(pim_ifp->igmp_query_max_response_time_dsec < pim_ifp->igmp_default_query_interval);
-
- if (pim)
- PIM_IF_DO_PIM(pim_ifp->options);
- if (igmp)
- PIM_IF_DO_IGMP(pim_ifp->options);
-
- PIM_IF_DO_IGMP_LISTEN_ALLROUTERS(pim_ifp->options);
-
- pim_ifp->igmp_join_list = NULL;
- pim_ifp->igmp_socket_list = NULL;
- pim_ifp->pim_neighbor_list = NULL;
- pim_ifp->upstream_switch_list = NULL;
- pim_ifp->pim_ifchannel_list = NULL;
- pim_ifp->pim_ifchannel_hash = NULL;
- pim_ifp->pim_generation_id = 0;
-
- /* list of struct igmp_sock */
- pim_ifp->igmp_socket_list = list_new();
- if (!pim_ifp->igmp_socket_list) {
- zlog_err("%s %s: failure: igmp_socket_list=list_new()",
- __FILE__, __PRETTY_FUNCTION__);
- return if_list_clean(pim_ifp);
- }
- pim_ifp->igmp_socket_list->del = (void (*)(void *)) igmp_sock_free;
-
- /* list of struct pim_neighbor */
- pim_ifp->pim_neighbor_list = list_new();
- if (!pim_ifp->pim_neighbor_list) {
- zlog_err("%s %s: failure: pim_neighbor_list=list_new()",
- __FILE__, __PRETTY_FUNCTION__);
- return if_list_clean(pim_ifp);
- }
- pim_ifp->pim_neighbor_list->del = (void (*)(void *)) pim_neighbor_free;
-
- pim_ifp->upstream_switch_list = list_new();
- if (!pim_ifp->upstream_switch_list) {
- zlog_err("%s %s: failure: upstream_switch_list=list_new()",
- __FILE__, __PRETTY_FUNCTION__);
- return if_list_clean(pim_ifp);
- }
-
- /* list of struct pim_ifchannel */
- pim_ifp->pim_ifchannel_list = list_new();
- if (!pim_ifp->pim_ifchannel_list) {
- zlog_err("%s %s: failure: pim_ifchannel_list=list_new()",
- __FILE__, __PRETTY_FUNCTION__);
- return if_list_clean(pim_ifp);
- }
- pim_ifp->pim_ifchannel_list->del = (void (*)(void *)) pim_ifchannel_free;
- pim_ifp->pim_ifchannel_list->cmp = (int (*)(void *, void *)) pim_ifchannel_compare;
-
- pim_ifp->pim_ifchannel_hash = hash_create (pim_ifchannel_hash_key,
- pim_ifchannel_equal, NULL);
-
- ifp->info = pim_ifp;
-
- pim_sock_reset(ifp);
-
- pim_if_add_vif(ifp);
-
- return pim_ifp;
+ struct pim_interface *pim_ifp;
+
+ zassert(ifp);
+ zassert(!ifp->info);
+
+ pim_ifp = XCALLOC(MTYPE_PIM_INTERFACE, sizeof(*pim_ifp));
+ if (!pim_ifp) {
+ zlog_err("PIM XCALLOC(%zu) failure", sizeof(*pim_ifp));
+ return 0;
+ }
+
+ pim_ifp->options = 0;
+ pim_ifp->mroute_vif_index = -1;
+
+ pim_ifp->igmp_version = IGMP_DEFAULT_VERSION;
+ 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
+ The number of seconds represented by the [Query Response Interval]
+ must be less than the [Query Interval].
+ */
+ zassert(pim_ifp->igmp_query_max_response_time_dsec
+ < pim_ifp->igmp_default_query_interval);
+
+ if (pim)
+ PIM_IF_DO_PIM(pim_ifp->options);
+ if (igmp)
+ PIM_IF_DO_IGMP(pim_ifp->options);
+
+ PIM_IF_DO_IGMP_LISTEN_ALLROUTERS(pim_ifp->options);
+
+ pim_ifp->igmp_join_list = NULL;
+ pim_ifp->igmp_socket_list = NULL;
+ pim_ifp->pim_neighbor_list = NULL;
+ pim_ifp->upstream_switch_list = NULL;
+ pim_ifp->pim_ifchannel_list = NULL;
+ pim_ifp->pim_ifchannel_hash = NULL;
+ pim_ifp->pim_generation_id = 0;
+
+ /* list of struct igmp_sock */
+ pim_ifp->igmp_socket_list = list_new();
+ if (!pim_ifp->igmp_socket_list) {
+ zlog_err("%s %s: failure: igmp_socket_list=list_new()",
+ __FILE__, __PRETTY_FUNCTION__);
+ return if_list_clean(pim_ifp);
+ }
+ pim_ifp->igmp_socket_list->del = (void (*)(void *))igmp_sock_free;
+
+ /* list of struct pim_neighbor */
+ pim_ifp->pim_neighbor_list = list_new();
+ if (!pim_ifp->pim_neighbor_list) {
+ zlog_err("%s %s: failure: pim_neighbor_list=list_new()",
+ __FILE__, __PRETTY_FUNCTION__);
+ return if_list_clean(pim_ifp);
+ }
+ pim_ifp->pim_neighbor_list->del = (void (*)(void *))pim_neighbor_free;
+
+ pim_ifp->upstream_switch_list = list_new();
+ if (!pim_ifp->upstream_switch_list) {
+ zlog_err("%s %s: failure: upstream_switch_list=list_new()",
+ __FILE__, __PRETTY_FUNCTION__);
+ return if_list_clean(pim_ifp);
+ }
+
+ /* list of struct pim_ifchannel */
+ pim_ifp->pim_ifchannel_list = list_new();
+ if (!pim_ifp->pim_ifchannel_list) {
+ zlog_err("%s %s: failure: pim_ifchannel_list=list_new()",
+ __FILE__, __PRETTY_FUNCTION__);
+ return if_list_clean(pim_ifp);
+ }
+ pim_ifp->pim_ifchannel_list->del = (void (*)(void *))pim_ifchannel_free;
+ pim_ifp->pim_ifchannel_list->cmp =
+ (int (*)(void *, void *))pim_ifchannel_compare;
+
+ pim_ifp->pim_ifchannel_hash =
+ hash_create(pim_ifchannel_hash_key, pim_ifchannel_equal, NULL);
+
+ ifp->info = pim_ifp;
+
+ pim_sock_reset(ifp);
+
+ pim_if_add_vif(ifp);
+
+ return pim_ifp;
}
void pim_if_delete(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
+ struct pim_interface *pim_ifp;
- zassert(ifp);
- pim_ifp = ifp->info;
- zassert(pim_ifp);
+ zassert(ifp);
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
- if (pim_ifp->igmp_join_list) {
- pim_if_igmp_join_del_all(ifp);
- }
+ if (pim_ifp->igmp_join_list) {
+ pim_if_igmp_join_del_all(ifp);
+ }
- pim_ifchannel_delete_all (ifp);
- igmp_sock_delete_all (ifp);
+ pim_ifchannel_delete_all(ifp);
+ igmp_sock_delete_all(ifp);
- pim_neighbor_delete_all (ifp, "Interface removed from configuration");
+ pim_neighbor_delete_all(ifp, "Interface removed from configuration");
- pim_if_del_vif(ifp);
+ pim_if_del_vif(ifp);
- list_delete(pim_ifp->igmp_socket_list);
- list_delete(pim_ifp->pim_neighbor_list);
- list_delete(pim_ifp->upstream_switch_list);
- list_delete(pim_ifp->pim_ifchannel_list);
+ list_delete(pim_ifp->igmp_socket_list);
+ list_delete(pim_ifp->pim_neighbor_list);
+ list_delete(pim_ifp->upstream_switch_list);
+ list_delete(pim_ifp->pim_ifchannel_list);
- hash_free (pim_ifp->pim_ifchannel_hash);
+ hash_free(pim_ifp->pim_ifchannel_hash);
- XFREE(MTYPE_PIM_INTERFACE, pim_ifp);
+ XFREE(MTYPE_PIM_INTERFACE, pim_ifp);
- ifp->info = NULL;
+ ifp->info = NULL;
}
void pim_if_update_could_assert(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
- struct listnode *node;
- struct listnode *next_node;
- struct pim_ifchannel *ch;
+ struct pim_interface *pim_ifp;
+ struct listnode *node;
+ struct listnode *next_node;
+ struct pim_ifchannel *ch;
- pim_ifp = ifp->info;
- zassert(pim_ifp);
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
- for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, node, next_node, ch)) {
- pim_ifchannel_update_could_assert(ch);
- }
+ for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, node, next_node,
+ ch)) {
+ pim_ifchannel_update_could_assert(ch);
+ }
}
static void pim_if_update_my_assert_metric(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
- struct listnode *node;
- struct listnode *next_node;
- struct pim_ifchannel *ch;
+ struct pim_interface *pim_ifp;
+ struct listnode *node;
+ struct listnode *next_node;
+ struct pim_ifchannel *ch;
- pim_ifp = ifp->info;
- zassert(pim_ifp);
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
- for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, node, next_node, ch)) {
- pim_ifchannel_update_my_assert_metric(ch);
- }
+ for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, node, next_node,
+ ch)) {
+ pim_ifchannel_update_my_assert_metric(ch);
+ }
}
static void pim_addr_change(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
-
- pim_ifp = ifp->info;
- zassert(pim_ifp);
-
- pim_if_dr_election(ifp); /* router's own DR Priority (addr) changes -- Done TODO T30 */
- pim_if_update_join_desired(pim_ifp); /* depends on DR */
- pim_if_update_could_assert(ifp); /* depends on DR */
- pim_if_update_my_assert_metric(ifp); /* depends on could_assert */
- pim_if_update_assert_tracking_desired(ifp); /* depends on DR, join_desired */
-
- /*
- RFC 4601: 4.3.1. Sending Hello Messages
-
- 1) Before an interface goes down or changes primary IP address, a
- Hello message with a zero HoldTime should be sent immediately
- (with the old IP address if the IP address changed).
- -- FIXME See CAVEAT C13
-
- 2) After an interface has changed its IP address, it MUST send a
- Hello message with its new IP address.
- -- DONE below
-
- 3) If an interface changes one of its secondary IP addresses, a
- Hello message with an updated Address_List option and a non-zero
- HoldTime should be sent immediately.
- -- FIXME See TODO T31
- */
- pim_ifp->pim_ifstat_hello_sent = 0; /* reset hello counter */
- if (pim_ifp->pim_sock_fd < 0)
- return;
- pim_hello_restart_now(ifp); /* send hello and restart timer */
+ struct pim_interface *pim_ifp;
+
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+
+ pim_if_dr_election(ifp); /* router's own DR Priority (addr) changes --
+ Done TODO T30 */
+ pim_if_update_join_desired(pim_ifp); /* depends on DR */
+ pim_if_update_could_assert(ifp); /* depends on DR */
+ pim_if_update_my_assert_metric(ifp); /* depends on could_assert */
+ pim_if_update_assert_tracking_desired(
+ ifp); /* depends on DR, join_desired */
+
+ /*
+ RFC 4601: 4.3.1. Sending Hello Messages
+
+ 1) Before an interface goes down or changes primary IP address, a
+ Hello message with a zero HoldTime should be sent immediately
+ (with the old IP address if the IP address changed).
+ -- FIXME See CAVEAT C13
+
+ 2) After an interface has changed its IP address, it MUST send a
+ Hello message with its new IP address.
+ -- DONE below
+
+ 3) If an interface changes one of its secondary IP addresses, a
+ Hello message with an updated Address_List option and a non-zero
+ HoldTime should be sent immediately.
+ -- FIXME See TODO T31
+ */
+ pim_ifp->pim_ifstat_hello_sent = 0; /* reset hello counter */
+ if (pim_ifp->pim_sock_fd < 0)
+ return;
+ pim_hello_restart_now(ifp); /* send hello and restart timer */
}
static int detect_primary_address_change(struct interface *ifp,
int force_prim_as_any,
const char *caller)
{
- struct pim_interface *pim_ifp = ifp->info;
- struct in_addr new_prim_addr;
- int changed;
-
- if (force_prim_as_any)
- new_prim_addr.s_addr = INADDR_ANY;
- else
- new_prim_addr = pim_find_primary_addr(ifp);
-
- changed = new_prim_addr.s_addr != pim_ifp->primary_address.s_addr;
-
- if (PIM_DEBUG_ZEBRA) {
- char new_prim_str[INET_ADDRSTRLEN];
- char old_prim_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<new?>", new_prim_addr, new_prim_str, sizeof(new_prim_str));
- pim_inet4_dump("<old?>", pim_ifp->primary_address, old_prim_str, sizeof(old_prim_str));
- zlog_debug("%s: old=%s new=%s on interface %s: %s",
- __PRETTY_FUNCTION__,
- old_prim_str, new_prim_str, ifp->name,
- changed ? "changed" : "unchanged");
- }
-
- if (changed) {
- pim_ifp->primary_address = new_prim_addr;
- }
-
- return changed;
+ struct pim_interface *pim_ifp = ifp->info;
+ struct in_addr new_prim_addr;
+ int changed;
+
+ if (force_prim_as_any)
+ new_prim_addr.s_addr = INADDR_ANY;
+ else
+ new_prim_addr = pim_find_primary_addr(ifp);
+
+ changed = new_prim_addr.s_addr != pim_ifp->primary_address.s_addr;
+
+ if (PIM_DEBUG_ZEBRA) {
+ char new_prim_str[INET_ADDRSTRLEN];
+ char old_prim_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<new?>", new_prim_addr, new_prim_str,
+ sizeof(new_prim_str));
+ pim_inet4_dump("<old?>", pim_ifp->primary_address, old_prim_str,
+ sizeof(old_prim_str));
+ zlog_debug("%s: old=%s new=%s on interface %s: %s",
+ __PRETTY_FUNCTION__, old_prim_str, new_prim_str,
+ ifp->name, changed ? "changed" : "unchanged");
+ }
+
+ if (changed) {
+ pim_ifp->primary_address = new_prim_addr;
+ }
+
+ return changed;
}
static int pim_sec_addr_comp(const void *p1, const void *p2)
{
- const struct pim_secondary_addr *sec1 = p1;
- const struct pim_secondary_addr *sec2 = p2;
-
- if (sec1->addr.family == AF_INET &&
- sec2->addr.family == AF_INET6)
- return -1;
-
- if (sec1->addr.family == AF_INET6 &&
- sec2->addr.family == AF_INET)
- return 1;
-
- if (sec1->addr.family == AF_INET)
- {
- if (ntohl(sec1->addr.u.prefix4.s_addr) < ntohl(sec2->addr.u.prefix4.s_addr))
- return -1;
-
- if (ntohl(sec1->addr.u.prefix4.s_addr) > ntohl(sec2->addr.u.prefix4.s_addr))
- return 1;
- }
- else
- {
- return memcmp (&sec1->addr.u.prefix6,
- &sec2->addr.u.prefix6,
- sizeof (struct in6_addr));
- }
-
- return 0;
+ const struct pim_secondary_addr *sec1 = p1;
+ const struct pim_secondary_addr *sec2 = p2;
+
+ if (sec1->addr.family == AF_INET && sec2->addr.family == AF_INET6)
+ return -1;
+
+ if (sec1->addr.family == AF_INET6 && sec2->addr.family == AF_INET)
+ return 1;
+
+ if (sec1->addr.family == AF_INET) {
+ if (ntohl(sec1->addr.u.prefix4.s_addr)
+ < ntohl(sec2->addr.u.prefix4.s_addr))
+ return -1;
+
+ if (ntohl(sec1->addr.u.prefix4.s_addr)
+ > ntohl(sec2->addr.u.prefix4.s_addr))
+ return 1;
+ } else {
+ return memcmp(&sec1->addr.u.prefix6, &sec2->addr.u.prefix6,
+ sizeof(struct in6_addr));
+ }
+
+ return 0;
}
static void pim_sec_addr_free(struct pim_secondary_addr *sec_addr)
{
- XFREE(MTYPE_PIM_SEC_ADDR, sec_addr);
+ XFREE(MTYPE_PIM_SEC_ADDR, sec_addr);
}
static struct pim_secondary_addr *
pim_sec_addr_find(struct pim_interface *pim_ifp, struct prefix *addr)
{
- struct pim_secondary_addr *sec_addr;
- struct listnode *node;
+ struct pim_secondary_addr *sec_addr;
+ struct listnode *node;
- if (!pim_ifp->sec_addr_list) {
- return NULL;
- }
+ if (!pim_ifp->sec_addr_list) {
+ return NULL;
+ }
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, node, sec_addr)) {
- if (prefix_cmp(&sec_addr->addr, addr)) {
- return sec_addr;
- }
- }
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, node, sec_addr)) {
+ if (prefix_cmp(&sec_addr->addr, addr)) {
+ return sec_addr;
+ }
+ }
- return NULL;
+ return NULL;
}
static void pim_sec_addr_del(struct pim_interface *pim_ifp,
- struct pim_secondary_addr *sec_addr)
+ struct pim_secondary_addr *sec_addr)
{
- listnode_delete(pim_ifp->sec_addr_list, sec_addr);
- pim_sec_addr_free(sec_addr);
+ listnode_delete(pim_ifp->sec_addr_list, sec_addr);
+ pim_sec_addr_free(sec_addr);
}
static int pim_sec_addr_add(struct pim_interface *pim_ifp, struct prefix *addr)
{
- int changed = 0;
- struct pim_secondary_addr *sec_addr;
-
- sec_addr = pim_sec_addr_find(pim_ifp, addr);
- if (sec_addr) {
- sec_addr->flags &= ~PIM_SEC_ADDRF_STALE;
- return changed;
- }
-
- if (!pim_ifp->sec_addr_list) {
- pim_ifp->sec_addr_list = list_new();
- pim_ifp->sec_addr_list->del = (void (*)(void *))pim_sec_addr_free;
- pim_ifp->sec_addr_list->cmp = (int (*)(void *, void *))pim_sec_addr_comp;
- }
-
- sec_addr = XCALLOC(MTYPE_PIM_SEC_ADDR, sizeof(*sec_addr));
- if (!sec_addr) {
- if (list_isempty(pim_ifp->sec_addr_list)) {
- list_free(pim_ifp->sec_addr_list);
- pim_ifp->sec_addr_list = NULL;
- }
- return changed;
- }
-
- changed = 1;
- sec_addr->addr = *addr;
- listnode_add_sort(pim_ifp->sec_addr_list, sec_addr);
-
- return changed;
+ int changed = 0;
+ struct pim_secondary_addr *sec_addr;
+
+ sec_addr = pim_sec_addr_find(pim_ifp, addr);
+ if (sec_addr) {
+ sec_addr->flags &= ~PIM_SEC_ADDRF_STALE;
+ return changed;
+ }
+
+ if (!pim_ifp->sec_addr_list) {
+ pim_ifp->sec_addr_list = list_new();
+ pim_ifp->sec_addr_list->del =
+ (void (*)(void *))pim_sec_addr_free;
+ pim_ifp->sec_addr_list->cmp =
+ (int (*)(void *, void *))pim_sec_addr_comp;
+ }
+
+ sec_addr = XCALLOC(MTYPE_PIM_SEC_ADDR, sizeof(*sec_addr));
+ if (!sec_addr) {
+ if (list_isempty(pim_ifp->sec_addr_list)) {
+ list_free(pim_ifp->sec_addr_list);
+ pim_ifp->sec_addr_list = NULL;
+ }
+ return changed;
+ }
+
+ changed = 1;
+ sec_addr->addr = *addr;
+ listnode_add_sort(pim_ifp->sec_addr_list, sec_addr);
+
+ return changed;
}
static int pim_sec_addr_del_all(struct pim_interface *pim_ifp)
{
- int changed = 0;
-
- if (!pim_ifp->sec_addr_list) {
- return changed;
- }
- if (!list_isempty(pim_ifp->sec_addr_list)) {
- changed = 1;
- /* remove all nodes and free up the list itself */
- list_delete_all_node(pim_ifp->sec_addr_list);
- list_free(pim_ifp->sec_addr_list);
- pim_ifp->sec_addr_list = NULL;
- }
-
- return changed;
+ int changed = 0;
+
+ if (!pim_ifp->sec_addr_list) {
+ return changed;
+ }
+ if (!list_isempty(pim_ifp->sec_addr_list)) {
+ changed = 1;
+ /* remove all nodes and free up the list itself */
+ list_delete_all_node(pim_ifp->sec_addr_list);
+ list_free(pim_ifp->sec_addr_list);
+ pim_ifp->sec_addr_list = NULL;
+ }
+
+ return changed;
}
static int pim_sec_addr_update(struct interface *ifp)
{
- struct pim_interface *pim_ifp = ifp->info;
- struct connected *ifc;
- struct listnode *node;
- struct listnode *nextnode;
- struct pim_secondary_addr *sec_addr;
- int changed = 0;
-
- if (pim_ifp->sec_addr_list) {
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, node, sec_addr)) {
- sec_addr->flags |= PIM_SEC_ADDRF_STALE;
- }
- }
-
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
- struct prefix *p = ifc->address;
-
- if (PIM_INADDR_IS_ANY(p->u.prefix4)) {
- continue;
- }
-
- if (pim_ifp->primary_address.s_addr == p->u.prefix4.s_addr) {
- /* don't add the primary address into the secondary address list */
- continue;
- }
-
- if (pim_sec_addr_add(pim_ifp, p)) {
- changed = 1;
- }
- }
-
- if (pim_ifp->sec_addr_list) {
- /* Drop stale entries */
- for (ALL_LIST_ELEMENTS(pim_ifp->sec_addr_list, node, nextnode, sec_addr)) {
- if (sec_addr->flags & PIM_SEC_ADDRF_STALE) {
- pim_sec_addr_del(pim_ifp, sec_addr);
- changed = 1;
- }
- }
-
- /* If the list went empty free it up */
- if (list_isempty(pim_ifp->sec_addr_list)) {
- list_free(pim_ifp->sec_addr_list);
- pim_ifp->sec_addr_list = NULL;
- }
- }
-
- return changed;
+ struct pim_interface *pim_ifp = ifp->info;
+ struct connected *ifc;
+ struct listnode *node;
+ struct listnode *nextnode;
+ struct pim_secondary_addr *sec_addr;
+ int changed = 0;
+
+ if (pim_ifp->sec_addr_list) {
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, node,
+ sec_addr)) {
+ sec_addr->flags |= PIM_SEC_ADDRF_STALE;
+ }
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
+ struct prefix *p = ifc->address;
+
+ if (PIM_INADDR_IS_ANY(p->u.prefix4)) {
+ continue;
+ }
+
+ if (pim_ifp->primary_address.s_addr == p->u.prefix4.s_addr) {
+ /* don't add the primary address into the secondary
+ * address list */
+ continue;
+ }
+
+ if (pim_sec_addr_add(pim_ifp, p)) {
+ changed = 1;
+ }
+ }
+
+ if (pim_ifp->sec_addr_list) {
+ /* Drop stale entries */
+ for (ALL_LIST_ELEMENTS(pim_ifp->sec_addr_list, node, nextnode,
+ sec_addr)) {
+ if (sec_addr->flags & PIM_SEC_ADDRF_STALE) {
+ pim_sec_addr_del(pim_ifp, sec_addr);
+ changed = 1;
+ }
+ }
+
+ /* If the list went empty free it up */
+ if (list_isempty(pim_ifp->sec_addr_list)) {
+ list_free(pim_ifp->sec_addr_list);
+ pim_ifp->sec_addr_list = NULL;
+ }
+ }
+
+ return changed;
}
static int detect_secondary_address_change(struct interface *ifp,
- int force_prim_as_any,
- const char *caller)
+ int force_prim_as_any,
+ const char *caller)
{
- struct pim_interface *pim_ifp = ifp->info;
- int changed = 0;
-
- if (force_prim_as_any) {
- /* if primary address is being forced to zero just flush the
- * secondary address list */
- changed = pim_sec_addr_del_all(pim_ifp);
- } else {
- /* re-evaluate the secondary address list */
- changed = pim_sec_addr_update(ifp);
- }
-
- return changed;
+ struct pim_interface *pim_ifp = ifp->info;
+ int changed = 0;
+
+ if (force_prim_as_any) {
+ /* if primary address is being forced to zero just flush the
+ * secondary address list */
+ changed = pim_sec_addr_del_all(pim_ifp);
+ } else {
+ /* re-evaluate the secondary address list */
+ changed = pim_sec_addr_update(ifp);
+ }
+
+ return changed;
}
-static void detect_address_change(struct interface *ifp,
- int force_prim_as_any,
- const char *caller)
+static void detect_address_change(struct interface *ifp, int force_prim_as_any,
+ const char *caller)
{
- int changed = 0;
- struct pim_interface *pim_ifp;
+ int changed = 0;
+ struct pim_interface *pim_ifp;
- pim_ifp = ifp->info;
- if (!pim_ifp)
- return;
+ pim_ifp = ifp->info;
+ if (!pim_ifp)
+ return;
- if (detect_primary_address_change(ifp, force_prim_as_any, caller)) {
- changed = 1;
- }
+ if (detect_primary_address_change(ifp, force_prim_as_any, caller)) {
+ changed = 1;
+ }
- if (detect_secondary_address_change(ifp, force_prim_as_any, caller)) {
- changed = 1;
- }
+ if (detect_secondary_address_change(ifp, force_prim_as_any, caller)) {
+ changed = 1;
+ }
- if (changed) {
- if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
- return;
- }
+ if (changed) {
+ if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
+ return;
+ }
- pim_addr_change(ifp);
- }
+ pim_addr_change(ifp);
+ }
- /* XXX: if we have unnumbered interfaces we need to run detect address
- * address change on all of them when the lo address changes */
+ /* XXX: if we have unnumbered interfaces we need to run detect address
+ * address change on all of them when the lo address changes */
}
int pim_update_source_set(struct interface *ifp, struct in_addr source)
{
- struct pim_interface *pim_ifp = ifp->info;
+ struct pim_interface *pim_ifp = ifp->info;
- if (!pim_ifp) {
- return PIM_IFACE_NOT_FOUND;
- }
+ if (!pim_ifp) {
+ return PIM_IFACE_NOT_FOUND;
+ }
- if (pim_ifp->update_source.s_addr == source.s_addr) {
- return PIM_UPDATE_SOURCE_DUP;
- }
+ if (pim_ifp->update_source.s_addr == source.s_addr) {
+ return PIM_UPDATE_SOURCE_DUP;
+ }
- pim_ifp->update_source = source;
- detect_address_change(ifp, 0 /* force_prim_as_any */,
- __PRETTY_FUNCTION__);
+ pim_ifp->update_source = source;
+ detect_address_change(ifp, 0 /* force_prim_as_any */,
+ __PRETTY_FUNCTION__);
- return PIM_SUCCESS;
+ return PIM_SUCCESS;
}
void pim_if_addr_add(struct connected *ifc)
{
- struct pim_interface *pim_ifp;
- struct interface *ifp;
- struct in_addr ifaddr;
-
- zassert(ifc);
-
- ifp = ifc->ifp;
- zassert(ifp);
- pim_ifp = ifp->info;
- if (!pim_ifp)
- return;
-
- if (!if_is_operative(ifp))
- return;
-
- if (PIM_DEBUG_ZEBRA) {
- char buf[BUFSIZ];
- prefix2str(ifc->address, buf, BUFSIZ);
- zlog_debug("%s: %s ifindex=%d connected IP address %s %s",
- __PRETTY_FUNCTION__,
- ifp->name, ifp->ifindex, buf,
- CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ?
- "secondary" : "primary");
- }
-
- ifaddr = ifc->address->u.prefix4;
-
- detect_address_change(ifp, 0, __PRETTY_FUNCTION__);
-
- if (ifc->address->family != AF_INET)
- return;
-
- if (PIM_IF_TEST_IGMP(pim_ifp->options)) {
- struct igmp_sock *igmp;
-
- /* lookup IGMP socket */
- igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->igmp_socket_list,
- ifaddr);
- if (!igmp) {
- /* if addr new, add IGMP socket */
- pim_igmp_sock_add(pim_ifp->igmp_socket_list, ifaddr, ifp);
- }
-
- /* Replay Static IGMP groups */
- if (pim_ifp->igmp_join_list)
- {
- struct listnode *node;
- struct listnode *nextnode;
- struct igmp_join *ij;
- int join_fd;
-
- for (ALL_LIST_ELEMENTS (pim_ifp->igmp_join_list, node, nextnode, ij))
- {
- /* Close socket and reopen with Source and Group */
- close(ij->sock_fd);
- join_fd = igmp_join_sock(ifp->name, ifp->ifindex, ij->group_addr, ij->source_addr);
- if (join_fd < 0)
- {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<grp?>", ij->group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<src?>", ij->source_addr, source_str, sizeof(source_str));
- zlog_warn("%s: igmp_join_sock() failure for IGMP group %s source %s on interface %s",
- __PRETTY_FUNCTION__,
- group_str, source_str, ifp->name);
- /* warning only */
- }
- else
- ij->sock_fd = join_fd;
- }
- }
- } /* igmp */
-
- if (PIM_IF_TEST_PIM(pim_ifp->options))
- {
-
- if (PIM_INADDR_ISNOT_ANY (pim_ifp->primary_address))
- {
-
- /* Interface has a valid socket ? */
- if (pim_ifp->pim_sock_fd < 0)
- {
- if (pim_sock_add (ifp))
- {
- zlog_warn ("Failure creating PIM socket for interface %s",
- ifp->name);
- }
- }
- struct pim_nexthop_cache *pnc = NULL;
- struct pim_rpf rpf;
- struct zclient *zclient = NULL;
-
- zclient = pim_zebra_zclient_get ();
- /* RP config might come prior to (local RP's interface) IF UP event.
- In this case, pnc would not have pim enabled nexthops.
- Once Interface is UP and pim info is available, reregister
- with RNH address to receive update and add the interface as nexthop. */
- memset (&rpf, 0, sizeof (struct pim_rpf));
- rpf.rpf_addr.family = AF_INET;
- rpf.rpf_addr.prefixlen = IPV4_MAX_BITLEN;
- rpf.rpf_addr.u.prefix4 = ifc->address->u.prefix4;
- pnc = pim_nexthop_cache_find (&rpf);
- if (pnc)
- pim_sendmsg_zebra_rnh (zclient, pnc,
- ZEBRA_NEXTHOP_REGISTER);
- }
- } /* pim */
-
- /*
- PIM or IGMP is enabled on interface, and there is at least one
- address assigned, then try to create a vif_index.
- */
- if (pim_ifp->mroute_vif_index < 0) {
- pim_if_add_vif(ifp);
- }
- pim_ifchannel_scan_forward_start (ifp);
+ struct pim_interface *pim_ifp;
+ struct interface *ifp;
+ struct in_addr ifaddr;
+
+ zassert(ifc);
+
+ ifp = ifc->ifp;
+ zassert(ifp);
+ pim_ifp = ifp->info;
+ if (!pim_ifp)
+ return;
+
+ if (!if_is_operative(ifp))
+ return;
+
+ if (PIM_DEBUG_ZEBRA) {
+ char buf[BUFSIZ];
+ prefix2str(ifc->address, buf, BUFSIZ);
+ zlog_debug("%s: %s ifindex=%d connected IP address %s %s",
+ __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, buf,
+ CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)
+ ? "secondary"
+ : "primary");
+ }
+
+ ifaddr = ifc->address->u.prefix4;
+
+ detect_address_change(ifp, 0, __PRETTY_FUNCTION__);
+
+ if (ifc->address->family != AF_INET)
+ return;
+
+ if (PIM_IF_TEST_IGMP(pim_ifp->options)) {
+ struct igmp_sock *igmp;
+
+ /* lookup IGMP socket */
+ igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->igmp_socket_list,
+ ifaddr);
+ if (!igmp) {
+ /* if addr new, add IGMP socket */
+ pim_igmp_sock_add(pim_ifp->igmp_socket_list, ifaddr,
+ ifp);
+ }
+
+ /* Replay Static IGMP groups */
+ if (pim_ifp->igmp_join_list) {
+ struct listnode *node;
+ struct listnode *nextnode;
+ struct igmp_join *ij;
+ int join_fd;
+
+ for (ALL_LIST_ELEMENTS(pim_ifp->igmp_join_list, node,
+ nextnode, ij)) {
+ /* Close socket and reopen with Source and Group
+ */
+ close(ij->sock_fd);
+ join_fd = igmp_join_sock(
+ ifp->name, ifp->ifindex, ij->group_addr,
+ ij->source_addr);
+ if (join_fd < 0) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<grp?>", ij->group_addr,
+ group_str,
+ sizeof(group_str));
+ pim_inet4_dump(
+ "<src?>", ij->source_addr,
+ source_str, sizeof(source_str));
+ zlog_warn(
+ "%s: igmp_join_sock() failure for IGMP group %s source %s on interface %s",
+ __PRETTY_FUNCTION__, group_str,
+ source_str, ifp->name);
+ /* warning only */
+ } else
+ ij->sock_fd = join_fd;
+ }
+ }
+ } /* igmp */
+
+ if (PIM_IF_TEST_PIM(pim_ifp->options)) {
+
+ if (PIM_INADDR_ISNOT_ANY(pim_ifp->primary_address)) {
+
+ /* Interface has a valid socket ? */
+ if (pim_ifp->pim_sock_fd < 0) {
+ if (pim_sock_add(ifp)) {
+ zlog_warn(
+ "Failure creating PIM socket for interface %s",
+ ifp->name);
+ }
+ }
+ struct pim_nexthop_cache *pnc = NULL;
+ struct pim_rpf rpf;
+ struct zclient *zclient = NULL;
+
+ zclient = pim_zebra_zclient_get();
+ /* RP config might come prior to (local RP's interface)
+ IF UP event.
+ In this case, pnc would not have pim enabled
+ nexthops.
+ Once Interface is UP and pim info is available,
+ reregister
+ with RNH address to receive update and add the
+ interface as nexthop. */
+ memset(&rpf, 0, sizeof(struct pim_rpf));
+ rpf.rpf_addr.family = AF_INET;
+ rpf.rpf_addr.prefixlen = IPV4_MAX_BITLEN;
+ rpf.rpf_addr.u.prefix4 = ifc->address->u.prefix4;
+ pnc = pim_nexthop_cache_find(&rpf);
+ if (pnc)
+ pim_sendmsg_zebra_rnh(zclient, pnc,
+ ZEBRA_NEXTHOP_REGISTER);
+ }
+ } /* pim */
+
+ /*
+ PIM or IGMP is enabled on interface, and there is at least one
+ address assigned, then try to create a vif_index.
+ */
+ if (pim_ifp->mroute_vif_index < 0) {
+ pim_if_add_vif(ifp);
+ }
+ pim_ifchannel_scan_forward_start(ifp);
}
static void pim_if_addr_del_igmp(struct connected *ifc)
{
- struct pim_interface *pim_ifp = ifc->ifp->info;
- struct igmp_sock *igmp;
- struct in_addr ifaddr;
-
- if (ifc->address->family != AF_INET) {
- /* non-IPv4 address */
- return;
- }
-
- if (!pim_ifp) {
- /* IGMP not enabled on interface */
- return;
- }
-
- ifaddr = ifc->address->u.prefix4;
-
- /* lookup IGMP socket */
- igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->igmp_socket_list,
- ifaddr);
- if (igmp) {
- /* if addr found, del IGMP socket */
- igmp_sock_delete(igmp);
- }
+ struct pim_interface *pim_ifp = ifc->ifp->info;
+ struct igmp_sock *igmp;
+ struct in_addr ifaddr;
+
+ if (ifc->address->family != AF_INET) {
+ /* non-IPv4 address */
+ return;
+ }
+
+ if (!pim_ifp) {
+ /* IGMP not enabled on interface */
+ return;
+ }
+
+ ifaddr = ifc->address->u.prefix4;
+
+ /* lookup IGMP socket */
+ igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->igmp_socket_list, ifaddr);
+ if (igmp) {
+ /* if addr found, del IGMP socket */
+ igmp_sock_delete(igmp);
+ }
}
static void pim_if_addr_del_pim(struct connected *ifc)
{
- struct pim_interface *pim_ifp = ifc->ifp->info;
-
- if (ifc->address->family != AF_INET) {
- /* non-IPv4 address */
- return;
- }
-
- if (!pim_ifp) {
- /* PIM not enabled on interface */
- return;
- }
-
- if (PIM_INADDR_ISNOT_ANY(pim_ifp->primary_address)) {
- /* Interface keeps a valid primary address */
- return;
- }
-
- if (pim_ifp->pim_sock_fd < 0) {
- /* Interface does not hold a valid socket any longer */
- return;
- }
-
- /*
- pim_sock_delete() closes the socket, stops read and timer threads,
- and kills all neighbors.
- */
- pim_sock_delete(ifc->ifp, "last address has been removed from interface");
-}
+ struct pim_interface *pim_ifp = ifc->ifp->info;
-void pim_if_addr_del(struct connected *ifc, int force_prim_as_any)
-{
- struct interface *ifp;
+ if (ifc->address->family != AF_INET) {
+ /* non-IPv4 address */
+ return;
+ }
- zassert(ifc);
- ifp = ifc->ifp;
- zassert(ifp);
+ if (!pim_ifp) {
+ /* PIM not enabled on interface */
+ return;
+ }
+
+ if (PIM_INADDR_ISNOT_ANY(pim_ifp->primary_address)) {
+ /* Interface keeps a valid primary address */
+ return;
+ }
- if (ifc->address->family != AF_INET)
- return;
+ if (pim_ifp->pim_sock_fd < 0) {
+ /* Interface does not hold a valid socket any longer */
+ return;
+ }
- if (PIM_DEBUG_ZEBRA) {
- char buf[BUFSIZ];
- prefix2str(ifc->address, buf, BUFSIZ);
- zlog_debug("%s: %s ifindex=%d disconnected IP address %s %s",
- __PRETTY_FUNCTION__,
- ifp->name, ifp->ifindex, buf,
- CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ?
- "secondary" : "primary");
- }
+ /*
+ pim_sock_delete() closes the socket, stops read and timer threads,
+ and kills all neighbors.
+ */
+ pim_sock_delete(ifc->ifp,
+ "last address has been removed from interface");
+}
- detect_address_change(ifp, force_prim_as_any, __PRETTY_FUNCTION__);
+void pim_if_addr_del(struct connected *ifc, int force_prim_as_any)
+{
+ struct interface *ifp;
+
+ zassert(ifc);
+ ifp = ifc->ifp;
+ zassert(ifp);
+
+ if (ifc->address->family != AF_INET)
+ return;
+
+ if (PIM_DEBUG_ZEBRA) {
+ char buf[BUFSIZ];
+ prefix2str(ifc->address, buf, BUFSIZ);
+ zlog_debug("%s: %s ifindex=%d disconnected IP address %s %s",
+ __PRETTY_FUNCTION__, ifp->name, ifp->ifindex, buf,
+ CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)
+ ? "secondary"
+ : "primary");
+ }
- pim_if_addr_del_igmp(ifc);
- pim_if_addr_del_pim(ifc);
+ detect_address_change(ifp, force_prim_as_any, __PRETTY_FUNCTION__);
+
+ pim_if_addr_del_igmp(ifc);
+ pim_if_addr_del_pim(ifc);
}
void pim_if_addr_add_all(struct interface *ifp)
{
- struct connected *ifc;
- struct listnode *node;
- struct listnode *nextnode;
- int v4_addrs = 0;
- int v6_addrs = 0;
- struct pim_interface *pim_ifp = ifp->info;
-
-
- /* PIM/IGMP enabled ? */
- if (!pim_ifp)
- return;
-
- for (ALL_LIST_ELEMENTS(ifp->connected, node, nextnode, ifc)) {
- struct prefix *p = ifc->address;
-
- if (p->family != AF_INET)
- v6_addrs++;
- else
- v4_addrs++;
- pim_if_addr_add(ifc);
- }
-
- if (!v4_addrs && v6_addrs && !if_is_loopback (ifp))
- {
- if (PIM_IF_TEST_PIM(pim_ifp->options)) {
-
- /* Interface has a valid primary address ? */
- if (PIM_INADDR_ISNOT_ANY(pim_ifp->primary_address)) {
+ struct connected *ifc;
+ struct listnode *node;
+ struct listnode *nextnode;
+ int v4_addrs = 0;
+ int v6_addrs = 0;
+ struct pim_interface *pim_ifp = ifp->info;
+
+
+ /* PIM/IGMP enabled ? */
+ if (!pim_ifp)
+ return;
+
+ for (ALL_LIST_ELEMENTS(ifp->connected, node, nextnode, ifc)) {
+ struct prefix *p = ifc->address;
+
+ if (p->family != AF_INET)
+ v6_addrs++;
+ else
+ v4_addrs++;
+ pim_if_addr_add(ifc);
+ }
- /* Interface has a valid socket ? */
- if (pim_ifp->pim_sock_fd < 0) {
- if (pim_sock_add(ifp)) {
- zlog_warn("Failure creating PIM socket for interface %s",
- ifp->name);
- }
- }
-
- }
- } /* pim */
- }
- /*
- * PIM or IGMP is enabled on interface, and there is at least one
- * address assigned, then try to create a vif_index.
- */
- if (pim_ifp->mroute_vif_index < 0) {
- pim_if_add_vif(ifp);
- }
- pim_ifchannel_scan_forward_start (ifp);
-
- pim_rp_setup();
- pim_rp_check_on_if_add(pim_ifp);
+ if (!v4_addrs && v6_addrs && !if_is_loopback(ifp)) {
+ if (PIM_IF_TEST_PIM(pim_ifp->options)) {
+
+ /* Interface has a valid primary address ? */
+ if (PIM_INADDR_ISNOT_ANY(pim_ifp->primary_address)) {
+
+ /* Interface has a valid socket ? */
+ if (pim_ifp->pim_sock_fd < 0) {
+ if (pim_sock_add(ifp)) {
+ zlog_warn(
+ "Failure creating PIM socket for interface %s",
+ ifp->name);
+ }
+ }
+ }
+ } /* pim */
+ }
+ /*
+ * PIM or IGMP is enabled on interface, and there is at least one
+ * address assigned, then try to create a vif_index.
+ */
+ if (pim_ifp->mroute_vif_index < 0) {
+ pim_if_add_vif(ifp);
+ }
+ pim_ifchannel_scan_forward_start(ifp);
+
+ pim_rp_setup();
+ pim_rp_check_on_if_add(pim_ifp);
}
void pim_if_addr_del_all(struct interface *ifp)
{
- struct connected *ifc;
- struct listnode *node;
- struct listnode *nextnode;
+ struct connected *ifc;
+ struct listnode *node;
+ struct listnode *nextnode;
+
+ /* PIM/IGMP enabled ? */
+ if (!ifp->info)
+ return;
- /* PIM/IGMP enabled ? */
- if (!ifp->info)
- return;
+ for (ALL_LIST_ELEMENTS(ifp->connected, node, nextnode, ifc)) {
+ struct prefix *p = ifc->address;
- for (ALL_LIST_ELEMENTS(ifp->connected, node, nextnode, ifc)) {
- struct prefix *p = ifc->address;
-
- if (p->family != AF_INET)
- continue;
+ if (p->family != AF_INET)
+ continue;
- pim_if_addr_del(ifc, 1 /* force_prim_as_any=true */);
- }
+ pim_if_addr_del(ifc, 1 /* force_prim_as_any=true */);
+ }
- pim_rp_setup();
- pim_i_am_rp_re_evaluate();
+ pim_rp_setup();
+ pim_i_am_rp_re_evaluate();
}
void pim_if_addr_del_all_igmp(struct interface *ifp)
{
- struct connected *ifc;
- struct listnode *node;
- struct listnode *nextnode;
-
- /* PIM/IGMP enabled ? */
- if (!ifp->info)
- return;
-
- for (ALL_LIST_ELEMENTS(ifp->connected, node, nextnode, ifc)) {
- struct prefix *p = ifc->address;
-
- if (p->family != AF_INET)
- continue;
-
- pim_if_addr_del_igmp(ifc);
- }
+ struct connected *ifc;
+ struct listnode *node;
+ struct listnode *nextnode;
+
+ /* PIM/IGMP enabled ? */
+ if (!ifp->info)
+ return;
+
+ for (ALL_LIST_ELEMENTS(ifp->connected, node, nextnode, ifc)) {
+ struct prefix *p = ifc->address;
+
+ if (p->family != AF_INET)
+ continue;
+
+ pim_if_addr_del_igmp(ifc);
+ }
}
void pim_if_addr_del_all_pim(struct interface *ifp)
{
- struct connected *ifc;
- struct listnode *node;
- struct listnode *nextnode;
-
- /* PIM/IGMP enabled ? */
- if (!ifp->info)
- return;
-
- for (ALL_LIST_ELEMENTS(ifp->connected, node, nextnode, ifc)) {
- struct prefix *p = ifc->address;
-
- if (p->family != AF_INET)
- continue;
-
- pim_if_addr_del_pim(ifc);
- }
+ struct connected *ifc;
+ struct listnode *node;
+ struct listnode *nextnode;
+
+ /* PIM/IGMP enabled ? */
+ if (!ifp->info)
+ return;
+
+ for (ALL_LIST_ELEMENTS(ifp->connected, node, nextnode, ifc)) {
+ struct prefix *p = ifc->address;
+
+ if (p->family != AF_INET)
+ continue;
+
+ pim_if_addr_del_pim(ifc);
+ }
}
-struct in_addr
-pim_find_primary_addr (struct interface *ifp)
+struct in_addr pim_find_primary_addr(struct interface *ifp)
{
- struct connected *ifc;
- struct listnode *node;
- struct in_addr addr;
- int v4_addrs = 0;
- int v6_addrs = 0;
- struct pim_interface *pim_ifp = ifp->info;
-
- if (pim_ifp && PIM_INADDR_ISNOT_ANY(pim_ifp->update_source)) {
- return pim_ifp->update_source;
- }
-
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
- struct prefix *p = ifc->address;
-
- if (p->family != AF_INET)
- {
- v6_addrs++;
- continue;
- }
-
- if (PIM_INADDR_IS_ANY(p->u.prefix4)) {
- zlog_warn("%s: null IPv4 address connected to interface %s",
- __PRETTY_FUNCTION__, ifp->name);
- continue;
- }
-
- v4_addrs++;
-
- if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY))
- continue;
-
- return p->u.prefix4;
- }
-
- /*
- * If we have no v4_addrs and v6 is configured
- * We probably are using unnumbered
- * So let's grab the loopbacks v4 address
- * and use that as the primary address
- */
- if (!v4_addrs && v6_addrs && !if_is_loopback (ifp))
- {
- struct interface *lo_ifp;
- lo_ifp = if_lookup_by_name ("lo", VRF_DEFAULT);
- if (lo_ifp)
- return pim_find_primary_addr (lo_ifp);
- }
-
- addr.s_addr = PIM_NET_INADDR_ANY;
-
- return addr;
+ struct connected *ifc;
+ struct listnode *node;
+ struct in_addr addr;
+ int v4_addrs = 0;
+ int v6_addrs = 0;
+ struct pim_interface *pim_ifp = ifp->info;
+
+ if (pim_ifp && PIM_INADDR_ISNOT_ANY(pim_ifp->update_source)) {
+ return pim_ifp->update_source;
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
+ struct prefix *p = ifc->address;
+
+ if (p->family != AF_INET) {
+ v6_addrs++;
+ continue;
+ }
+
+ if (PIM_INADDR_IS_ANY(p->u.prefix4)) {
+ zlog_warn(
+ "%s: null IPv4 address connected to interface %s",
+ __PRETTY_FUNCTION__, ifp->name);
+ continue;
+ }
+
+ v4_addrs++;
+
+ if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY))
+ continue;
+
+ return p->u.prefix4;
+ }
+
+ /*
+ * If we have no v4_addrs and v6 is configured
+ * We probably are using unnumbered
+ * So let's grab the loopbacks v4 address
+ * and use that as the primary address
+ */
+ if (!v4_addrs && v6_addrs && !if_is_loopback(ifp)) {
+ struct interface *lo_ifp;
+ lo_ifp = if_lookup_by_name("lo", VRF_DEFAULT);
+ if (lo_ifp)
+ return pim_find_primary_addr(lo_ifp);
+ }
+
+ addr.s_addr = PIM_NET_INADDR_ANY;
+
+ return addr;
}
-static int
-pim_iface_next_vif_index (struct interface *ifp)
+static int pim_iface_next_vif_index(struct interface *ifp)
{
- int i;
- /*
- * The pimreg vif is always going to be in index 0
- * of the table.
- */
- if (ifp->ifindex == PIM_OIF_PIM_REGISTER_VIF)
- return 0;
-
- for (i = 1 ; i < MAXVIFS; i++)
- {
- if (pim_iface_vif_index[i] == 0)
- return i;
- }
- return MAXVIFS;
+ int i;
+ /*
+ * The pimreg vif is always going to be in index 0
+ * of the table.
+ */
+ if (ifp->ifindex == PIM_OIF_PIM_REGISTER_VIF)
+ return 0;
+
+ for (i = 1; i < MAXVIFS; i++) {
+ if (pim_iface_vif_index[i] == 0)
+ return i;
+ }
+ return MAXVIFS;
}
/*
@@ -960,130 +972,131 @@ pim_iface_next_vif_index (struct interface *ifp)
*/
int pim_if_add_vif(struct interface *ifp)
{
- struct pim_interface *pim_ifp = ifp->info;
- struct in_addr ifaddr;
- unsigned char flags = 0;
-
- zassert(pim_ifp);
-
- if (pim_ifp->mroute_vif_index > 0) {
- zlog_warn("%s: vif_index=%d > 0 on interface %s ifindex=%d",
- __PRETTY_FUNCTION__,
- pim_ifp->mroute_vif_index, ifp->name, ifp->ifindex);
- return -1;
- }
-
- if (ifp->ifindex < 0) {
- zlog_warn("%s: ifindex=%d < 1 on interface %s",
- __PRETTY_FUNCTION__,
- ifp->ifindex, ifp->name);
- return -2;
- }
-
- ifaddr = pim_ifp->primary_address;
- if (ifp->ifindex != PIM_OIF_PIM_REGISTER_VIF && PIM_INADDR_IS_ANY(ifaddr)) {
- zlog_warn("%s: could not get address for interface %s ifindex=%d",
- __PRETTY_FUNCTION__,
- ifp->name, ifp->ifindex);
- return -4;
- }
-
- pim_ifp->mroute_vif_index = pim_iface_next_vif_index (ifp);
-
- if (pim_ifp->mroute_vif_index >= MAXVIFS)
- {
- zlog_warn("%s: Attempting to configure more than MAXVIFS=%d on pim enabled interface %s",
- __PRETTY_FUNCTION__,
- MAXVIFS, ifp->name);
- return -3;
- }
-
- if (ifp->ifindex == PIM_OIF_PIM_REGISTER_VIF)
- flags = VIFF_REGISTER;
+ struct pim_interface *pim_ifp = ifp->info;
+ struct in_addr ifaddr;
+ unsigned char flags = 0;
+
+ zassert(pim_ifp);
+
+ if (pim_ifp->mroute_vif_index > 0) {
+ zlog_warn("%s: vif_index=%d > 0 on interface %s ifindex=%d",
+ __PRETTY_FUNCTION__, pim_ifp->mroute_vif_index,
+ ifp->name, ifp->ifindex);
+ return -1;
+ }
+
+ if (ifp->ifindex < 0) {
+ zlog_warn("%s: ifindex=%d < 1 on interface %s",
+ __PRETTY_FUNCTION__, ifp->ifindex, ifp->name);
+ return -2;
+ }
+
+ ifaddr = pim_ifp->primary_address;
+ if (ifp->ifindex != PIM_OIF_PIM_REGISTER_VIF
+ && PIM_INADDR_IS_ANY(ifaddr)) {
+ zlog_warn(
+ "%s: could not get address for interface %s ifindex=%d",
+ __PRETTY_FUNCTION__, ifp->name, ifp->ifindex);
+ return -4;
+ }
+
+ pim_ifp->mroute_vif_index = pim_iface_next_vif_index(ifp);
+
+ if (pim_ifp->mroute_vif_index >= MAXVIFS) {
+ zlog_warn(
+ "%s: Attempting to configure more than MAXVIFS=%d on pim enabled interface %s",
+ __PRETTY_FUNCTION__, MAXVIFS, ifp->name);
+ return -3;
+ }
+
+ if (ifp->ifindex == PIM_OIF_PIM_REGISTER_VIF)
+ flags = VIFF_REGISTER;
#ifdef VIFF_USE_IFINDEX
- else
- flags = VIFF_USE_IFINDEX;
+ else
+ flags = VIFF_USE_IFINDEX;
#endif
- if (pim_mroute_add_vif(ifp, ifaddr, flags)) {
- /* pim_mroute_add_vif reported error */
- return -5;
- }
+ if (pim_mroute_add_vif(ifp, ifaddr, flags)) {
+ /* pim_mroute_add_vif reported error */
+ return -5;
+ }
- pim_iface_vif_index[pim_ifp->mroute_vif_index] = 1;
- return 0;
+ pim_iface_vif_index[pim_ifp->mroute_vif_index] = 1;
+ return 0;
}
int pim_if_del_vif(struct interface *ifp)
{
- struct pim_interface *pim_ifp = ifp->info;
+ struct pim_interface *pim_ifp = ifp->info;
- if (pim_ifp->mroute_vif_index < 1) {
- zlog_warn("%s: vif_index=%d < 1 on interface %s ifindex=%d",
- __PRETTY_FUNCTION__,
- pim_ifp->mroute_vif_index, ifp->name, ifp->ifindex);
- return -1;
- }
+ if (pim_ifp->mroute_vif_index < 1) {
+ zlog_warn("%s: vif_index=%d < 1 on interface %s ifindex=%d",
+ __PRETTY_FUNCTION__, pim_ifp->mroute_vif_index,
+ ifp->name, ifp->ifindex);
+ return -1;
+ }
- pim_mroute_del_vif(pim_ifp->mroute_vif_index);
+ pim_mroute_del_vif(pim_ifp->mroute_vif_index);
- /*
- Update vif_index
- */
- pim_iface_vif_index[pim_ifp->mroute_vif_index] = 0;
+ /*
+ Update vif_index
+ */
+ pim_iface_vif_index[pim_ifp->mroute_vif_index] = 0;
- pim_ifp->mroute_vif_index = -1;
+ pim_ifp->mroute_vif_index = -1;
- return 0;
+ return 0;
}
void pim_if_add_vif_all()
{
- struct listnode *ifnode;
- struct listnode *ifnextnode;
- struct interface *ifp;
+ struct listnode *ifnode;
+ struct listnode *ifnextnode;
+ struct interface *ifp;
- for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
- if (!ifp->info)
- continue;
+ for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), ifnode, ifnextnode,
+ ifp)) {
+ if (!ifp->info)
+ continue;
- pim_if_add_vif(ifp);
- }
+ pim_if_add_vif(ifp);
+ }
}
void pim_if_del_vif_all()
{
- struct listnode *ifnode;
- struct listnode *ifnextnode;
- struct interface *ifp;
+ struct listnode *ifnode;
+ struct listnode *ifnextnode;
+ struct interface *ifp;
- for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp)) {
- if (!ifp->info)
- continue;
+ for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), ifnode, ifnextnode,
+ ifp)) {
+ if (!ifp->info)
+ continue;
- pim_if_del_vif(ifp);
- }
+ pim_if_del_vif(ifp);
+ }
}
struct interface *pim_if_find_by_vif_index(ifindex_t vif_index)
{
- struct listnode *ifnode;
- struct interface *ifp;
+ struct listnode *ifnode;
+ struct interface *ifp;
- if (vif_index == 0)
- return if_lookup_by_name ("pimreg", VRF_DEFAULT);
+ if (vif_index == 0)
+ return if_lookup_by_name("pimreg", VRF_DEFAULT);
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) {
- if (ifp->info) {
- struct pim_interface *pim_ifp;
- pim_ifp = ifp->info;
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), ifnode, ifp)) {
+ if (ifp->info) {
+ struct pim_interface *pim_ifp;
+ pim_ifp = ifp->info;
- if (vif_index == pim_ifp->mroute_vif_index)
- return ifp;
- }
- }
+ if (vif_index == pim_ifp->mroute_vif_index)
+ return ifp;
+ }
+ }
- return 0;
+ return 0;
}
/*
@@ -1091,69 +1104,67 @@ struct interface *pim_if_find_by_vif_index(ifindex_t vif_index)
*/
int pim_if_find_vifindex_by_ifindex(ifindex_t ifindex)
{
- struct pim_interface *pim_ifp;
- struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ struct interface *ifp;
- ifp = if_lookup_by_index (ifindex, VRF_DEFAULT);
- if (!ifp || !ifp->info)
- return -1;
- pim_ifp = ifp->info;
+ ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
+ if (!ifp || !ifp->info)
+ return -1;
+ pim_ifp = ifp->info;
- return pim_ifp->mroute_vif_index;
+ return pim_ifp->mroute_vif_index;
}
int pim_if_lan_delay_enabled(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
+ struct pim_interface *pim_ifp;
- pim_ifp = ifp->info;
- zassert(pim_ifp);
- zassert(pim_ifp->pim_number_of_nonlandelay_neighbors >= 0);
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+ zassert(pim_ifp->pim_number_of_nonlandelay_neighbors >= 0);
- return pim_ifp->pim_number_of_nonlandelay_neighbors == 0;
+ return pim_ifp->pim_number_of_nonlandelay_neighbors == 0;
}
uint16_t pim_if_effective_propagation_delay_msec(struct interface *ifp)
{
- if (pim_if_lan_delay_enabled(ifp)) {
- struct pim_interface *pim_ifp;
- pim_ifp = ifp->info;
- return pim_ifp->pim_neighbors_highest_propagation_delay_msec;
- }
- else {
- return PIM_DEFAULT_PROPAGATION_DELAY_MSEC;
- }
+ if (pim_if_lan_delay_enabled(ifp)) {
+ struct pim_interface *pim_ifp;
+ pim_ifp = ifp->info;
+ return pim_ifp->pim_neighbors_highest_propagation_delay_msec;
+ } else {
+ return PIM_DEFAULT_PROPAGATION_DELAY_MSEC;
+ }
}
uint16_t pim_if_effective_override_interval_msec(struct interface *ifp)
{
- if (pim_if_lan_delay_enabled(ifp)) {
- struct pim_interface *pim_ifp;
- pim_ifp = ifp->info;
- return pim_ifp->pim_neighbors_highest_override_interval_msec;
- }
- else {
- return PIM_DEFAULT_OVERRIDE_INTERVAL_MSEC;
- }
+ if (pim_if_lan_delay_enabled(ifp)) {
+ struct pim_interface *pim_ifp;
+ pim_ifp = ifp->info;
+ return pim_ifp->pim_neighbors_highest_override_interval_msec;
+ } else {
+ return PIM_DEFAULT_OVERRIDE_INTERVAL_MSEC;
+ }
}
int pim_if_t_override_msec(struct interface *ifp)
{
- int effective_override_interval_msec;
- int t_override_msec;
+ int effective_override_interval_msec;
+ int t_override_msec;
- effective_override_interval_msec =
- pim_if_effective_override_interval_msec(ifp);
+ effective_override_interval_msec =
+ pim_if_effective_override_interval_msec(ifp);
- t_override_msec = random() % (effective_override_interval_msec + 1);
+ t_override_msec = random() % (effective_override_interval_msec + 1);
- return t_override_msec;
+ return t_override_msec;
}
uint16_t pim_if_jp_override_interval_msec(struct interface *ifp)
{
- return pim_if_effective_propagation_delay_msec(ifp) +
- pim_if_effective_override_interval_msec(ifp);
+ return pim_if_effective_propagation_delay_msec(ifp)
+ + pim_if_effective_override_interval_msec(ifp);
}
/*
@@ -1168,294 +1179,303 @@ uint16_t pim_if_jp_override_interval_msec(struct interface *ifp)
struct pim_neighbor *pim_if_find_neighbor(struct interface *ifp,
struct in_addr addr)
{
- struct listnode *neighnode;
- struct pim_neighbor *neigh;
- struct pim_interface *pim_ifp;
- struct prefix p;
-
- zassert(ifp);
-
- pim_ifp = ifp->info;
- if (!pim_ifp) {
- zlog_warn("%s: multicast not enabled on interface %s",
- __PRETTY_FUNCTION__,
- ifp->name);
- return 0;
- }
-
- p.family = AF_INET;
- p.u.prefix4 = addr;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
-
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
-
- /* primary address ? */
- if (neigh->source_addr.s_addr == addr.s_addr)
- return neigh;
-
- /* secondary address ? */
- if (pim_neighbor_find_secondary(neigh, &p))
- return neigh;
- }
-
- if (PIM_DEBUG_PIM_TRACE) {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_debug("%s: neighbor not found for address %s on interface %s",
- __PRETTY_FUNCTION__,
- addr_str, ifp->name);
- }
-
- return NULL;
+ struct listnode *neighnode;
+ struct pim_neighbor *neigh;
+ struct pim_interface *pim_ifp;
+ struct prefix p;
+
+ zassert(ifp);
+
+ pim_ifp = ifp->info;
+ if (!pim_ifp) {
+ zlog_warn("%s: multicast not enabled on interface %s",
+ __PRETTY_FUNCTION__, ifp->name);
+ return 0;
+ }
+
+ p.family = AF_INET;
+ p.u.prefix4 = addr;
+ p.prefixlen = IPV4_MAX_PREFIXLEN;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
+ neigh)) {
+
+ /* primary address ? */
+ if (neigh->source_addr.s_addr == addr.s_addr)
+ return neigh;
+
+ /* secondary address ? */
+ if (pim_neighbor_find_secondary(neigh, &p))
+ return neigh;
+ }
+
+ if (PIM_DEBUG_PIM_TRACE) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+ zlog_debug(
+ "%s: neighbor not found for address %s on interface %s",
+ __PRETTY_FUNCTION__, addr_str, ifp->name);
+ }
+
+ return NULL;
}
long pim_if_t_suppressed_msec(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
- long t_suppressed_msec;
- uint32_t ramount = 0;
+ struct pim_interface *pim_ifp;
+ long t_suppressed_msec;
+ uint32_t ramount = 0;
- pim_ifp = ifp->info;
- zassert(pim_ifp);
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
- /* join suppression disabled ? */
- if (PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options))
- return 0;
+ /* join suppression disabled ? */
+ if (PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options))
+ return 0;
- /* t_suppressed = t_periodic * rand(1.1, 1.4) */
- ramount = 1100 + (random() % (1400 - 1100 + 1));
- t_suppressed_msec = qpim_t_periodic * ramount;
+ /* t_suppressed = t_periodic * rand(1.1, 1.4) */
+ ramount = 1100 + (random() % (1400 - 1100 + 1));
+ t_suppressed_msec = qpim_t_periodic * ramount;
- return t_suppressed_msec;
+ return t_suppressed_msec;
}
static void igmp_join_free(struct igmp_join *ij)
{
- XFREE(MTYPE_PIM_IGMP_JOIN, ij);
+ XFREE(MTYPE_PIM_IGMP_JOIN, ij);
}
static struct igmp_join *igmp_join_find(struct list *join_list,
struct in_addr group_addr,
struct in_addr source_addr)
{
- struct listnode *node;
- struct igmp_join *ij;
+ struct listnode *node;
+ struct igmp_join *ij;
- zassert(join_list);
+ zassert(join_list);
- for (ALL_LIST_ELEMENTS_RO(join_list, node, ij)) {
- if ((group_addr.s_addr == ij->group_addr.s_addr) &&
- (source_addr.s_addr == ij->source_addr.s_addr))
- return ij;
- }
+ for (ALL_LIST_ELEMENTS_RO(join_list, node, ij)) {
+ if ((group_addr.s_addr == ij->group_addr.s_addr)
+ && (source_addr.s_addr == ij->source_addr.s_addr))
+ return ij;
+ }
- return 0;
+ return 0;
}
-static int igmp_join_sock(const char *ifname,
- ifindex_t ifindex,
- struct in_addr group_addr,
- struct in_addr source_addr)
+static int igmp_join_sock(const char *ifname, ifindex_t ifindex,
+ struct in_addr group_addr, struct in_addr source_addr)
{
- int join_fd;
+ int join_fd;
- join_fd = pim_socket_raw(IPPROTO_IGMP);
- if (join_fd < 0) {
- return -1;
- }
+ join_fd = pim_socket_raw(IPPROTO_IGMP);
+ if (join_fd < 0) {
+ return -1;
+ }
- if (pim_socket_join_source(join_fd, ifindex, group_addr, source_addr, ifname)) {
- close(join_fd);
- return -2;
- }
+ if (pim_socket_join_source(join_fd, ifindex, group_addr, source_addr,
+ ifname)) {
+ close(join_fd);
+ return -2;
+ }
- return join_fd;
+ return join_fd;
}
static struct igmp_join *igmp_join_new(struct interface *ifp,
struct in_addr group_addr,
struct in_addr source_addr)
{
- struct pim_interface *pim_ifp;
- struct igmp_join *ij;
- int join_fd;
-
- pim_ifp = ifp->info;
- zassert(pim_ifp);
-
- join_fd = igmp_join_sock(ifp->name, ifp->ifindex, group_addr, source_addr);
- if (join_fd < 0) {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- zlog_warn("%s: igmp_join_sock() failure for IGMP group %s source %s on interface %s",
- __PRETTY_FUNCTION__,
- group_str, source_str, ifp->name);
- return 0;
- }
-
- ij = XCALLOC(MTYPE_PIM_IGMP_JOIN, sizeof(*ij));
- if (!ij) {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- zlog_err("%s: XCALLOC(%zu) failure for IGMP group %s source %s on interface %s",
- __PRETTY_FUNCTION__,
- sizeof(*ij), group_str, source_str, ifp->name);
- close(join_fd);
- return 0;
- }
-
- ij->sock_fd = join_fd;
- ij->group_addr = group_addr;
- ij->source_addr = source_addr;
- ij->sock_creation = pim_time_monotonic_sec();
-
- listnode_add(pim_ifp->igmp_join_list, ij);
-
- return ij;
+ struct pim_interface *pim_ifp;
+ struct igmp_join *ij;
+ int join_fd;
+
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+
+ join_fd = igmp_join_sock(ifp->name, ifp->ifindex, group_addr,
+ source_addr);
+ if (join_fd < 0) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<grp?>", group_addr, group_str,
+ sizeof(group_str));
+ pim_inet4_dump("<src?>", source_addr, source_str,
+ sizeof(source_str));
+ zlog_warn(
+ "%s: igmp_join_sock() failure for IGMP group %s source %s on interface %s",
+ __PRETTY_FUNCTION__, group_str, source_str, ifp->name);
+ return 0;
+ }
+
+ ij = XCALLOC(MTYPE_PIM_IGMP_JOIN, sizeof(*ij));
+ if (!ij) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<grp?>", group_addr, group_str,
+ sizeof(group_str));
+ pim_inet4_dump("<src?>", source_addr, source_str,
+ sizeof(source_str));
+ zlog_err(
+ "%s: XCALLOC(%zu) failure for IGMP group %s source %s on interface %s",
+ __PRETTY_FUNCTION__, sizeof(*ij), group_str, source_str,
+ ifp->name);
+ close(join_fd);
+ return 0;
+ }
+
+ ij->sock_fd = join_fd;
+ ij->group_addr = group_addr;
+ ij->source_addr = source_addr;
+ ij->sock_creation = pim_time_monotonic_sec();
+
+ listnode_add(pim_ifp->igmp_join_list, ij);
+
+ return ij;
}
-int pim_if_igmp_join_add(struct interface *ifp,
- struct in_addr group_addr,
+int pim_if_igmp_join_add(struct interface *ifp, struct in_addr group_addr,
struct in_addr source_addr)
{
- struct pim_interface *pim_ifp;
- struct igmp_join *ij;
-
- pim_ifp = ifp->info;
- if (!pim_ifp) {
- zlog_warn("%s: multicast not enabled on interface %s",
- __PRETTY_FUNCTION__,
- ifp->name);
- return -1;
- }
-
- if (!pim_ifp->igmp_join_list) {
- pim_ifp->igmp_join_list = list_new();
- if (!pim_ifp->igmp_join_list) {
- zlog_err("%s %s: failure: igmp_join_list=list_new()",
- __FILE__, __PRETTY_FUNCTION__);
- return -2;
- }
- pim_ifp->igmp_join_list->del = (void (*)(void *)) igmp_join_free;
- }
-
- ij = igmp_join_find(pim_ifp->igmp_join_list, group_addr, source_addr);
- if (ij) {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- zlog_warn("%s: can't re-join existing IGMP group %s source %s on interface %s",
- __PRETTY_FUNCTION__,
- group_str, source_str, ifp->name);
- return -3;
- }
-
- ij = igmp_join_new(ifp, group_addr, source_addr);
- if (!ij) {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- zlog_warn("%s: igmp_join_new() failure for IGMP group %s source %s on interface %s",
- __PRETTY_FUNCTION__,
- group_str, source_str, ifp->name);
- return -4;
- }
-
- if (PIM_DEBUG_IGMP_EVENTS) {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- zlog_debug("%s: issued static igmp join for channel (S,G)=(%s,%s) on interface %s",
- __PRETTY_FUNCTION__,
- source_str, group_str, ifp->name);
- }
-
- return 0;
-}
+ struct pim_interface *pim_ifp;
+ struct igmp_join *ij;
+
+ pim_ifp = ifp->info;
+ if (!pim_ifp) {
+ zlog_warn("%s: multicast not enabled on interface %s",
+ __PRETTY_FUNCTION__, ifp->name);
+ return -1;
+ }
+
+ if (!pim_ifp->igmp_join_list) {
+ pim_ifp->igmp_join_list = list_new();
+ if (!pim_ifp->igmp_join_list) {
+ zlog_err("%s %s: failure: igmp_join_list=list_new()",
+ __FILE__, __PRETTY_FUNCTION__);
+ return -2;
+ }
+ pim_ifp->igmp_join_list->del = (void (*)(void *))igmp_join_free;
+ }
+
+ ij = igmp_join_find(pim_ifp->igmp_join_list, group_addr, source_addr);
+ if (ij) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<grp?>", group_addr, group_str,
+ sizeof(group_str));
+ pim_inet4_dump("<src?>", source_addr, source_str,
+ sizeof(source_str));
+ zlog_warn(
+ "%s: can't re-join existing IGMP group %s source %s on interface %s",
+ __PRETTY_FUNCTION__, group_str, source_str, ifp->name);
+ return -3;
+ }
+
+ ij = igmp_join_new(ifp, group_addr, source_addr);
+ if (!ij) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<grp?>", group_addr, group_str,
+ sizeof(group_str));
+ pim_inet4_dump("<src?>", source_addr, source_str,
+ sizeof(source_str));
+ zlog_warn(
+ "%s: igmp_join_new() failure for IGMP group %s source %s on interface %s",
+ __PRETTY_FUNCTION__, group_str, source_str, ifp->name);
+ return -4;
+ }
+
+ if (PIM_DEBUG_IGMP_EVENTS) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<grp?>", group_addr, group_str,
+ sizeof(group_str));
+ pim_inet4_dump("<src?>", source_addr, source_str,
+ sizeof(source_str));
+ zlog_debug(
+ "%s: issued static igmp join for channel (S,G)=(%s,%s) on interface %s",
+ __PRETTY_FUNCTION__, source_str, group_str, ifp->name);
+ }
+ return 0;
+}
-int pim_if_igmp_join_del(struct interface *ifp,
- struct in_addr group_addr,
+int pim_if_igmp_join_del(struct interface *ifp, struct in_addr group_addr,
struct in_addr source_addr)
{
- struct pim_interface *pim_ifp;
- struct igmp_join *ij;
-
- pim_ifp = ifp->info;
- if (!pim_ifp) {
- zlog_warn("%s: multicast not enabled on interface %s",
- __PRETTY_FUNCTION__,
- ifp->name);
- return -1;
- }
-
- if (!pim_ifp->igmp_join_list) {
- zlog_warn("%s: no IGMP join on interface %s",
- __PRETTY_FUNCTION__,
- ifp->name);
- return -2;
- }
-
- ij = igmp_join_find(pim_ifp->igmp_join_list, group_addr, source_addr);
- if (!ij) {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- zlog_warn("%s: could not find IGMP group %s source %s on interface %s",
- __PRETTY_FUNCTION__,
- group_str, source_str, ifp->name);
- return -3;
- }
-
- if (close(ij->sock_fd)) {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- zlog_warn("%s: failure closing sock_fd=%d for IGMP group %s source %s on interface %s: errno=%d: %s",
- __PRETTY_FUNCTION__,
- ij->sock_fd, group_str, source_str, ifp->name, errno, safe_strerror(errno));
- /* warning only */
- }
- listnode_delete(pim_ifp->igmp_join_list, ij);
- igmp_join_free(ij);
- if (listcount(pim_ifp->igmp_join_list) < 1) {
- list_delete(pim_ifp->igmp_join_list);
- pim_ifp->igmp_join_list = 0;
- }
-
- return 0;
+ struct pim_interface *pim_ifp;
+ struct igmp_join *ij;
+
+ pim_ifp = ifp->info;
+ if (!pim_ifp) {
+ zlog_warn("%s: multicast not enabled on interface %s",
+ __PRETTY_FUNCTION__, ifp->name);
+ return -1;
+ }
+
+ if (!pim_ifp->igmp_join_list) {
+ zlog_warn("%s: no IGMP join on interface %s",
+ __PRETTY_FUNCTION__, ifp->name);
+ return -2;
+ }
+
+ ij = igmp_join_find(pim_ifp->igmp_join_list, group_addr, source_addr);
+ if (!ij) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<grp?>", group_addr, group_str,
+ sizeof(group_str));
+ pim_inet4_dump("<src?>", source_addr, source_str,
+ sizeof(source_str));
+ zlog_warn(
+ "%s: could not find IGMP group %s source %s on interface %s",
+ __PRETTY_FUNCTION__, group_str, source_str, ifp->name);
+ return -3;
+ }
+
+ if (close(ij->sock_fd)) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<grp?>", group_addr, group_str,
+ sizeof(group_str));
+ pim_inet4_dump("<src?>", source_addr, source_str,
+ sizeof(source_str));
+ zlog_warn(
+ "%s: failure closing sock_fd=%d for IGMP group %s source %s on interface %s: errno=%d: %s",
+ __PRETTY_FUNCTION__, ij->sock_fd, group_str, source_str,
+ ifp->name, errno, safe_strerror(errno));
+ /* warning only */
+ }
+ listnode_delete(pim_ifp->igmp_join_list, ij);
+ igmp_join_free(ij);
+ if (listcount(pim_ifp->igmp_join_list) < 1) {
+ list_delete(pim_ifp->igmp_join_list);
+ pim_ifp->igmp_join_list = 0;
+ }
+
+ return 0;
}
static void pim_if_igmp_join_del_all(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
- struct listnode *node;
- struct listnode *nextnode;
- struct igmp_join *ij;
-
- pim_ifp = ifp->info;
- if (!pim_ifp) {
- zlog_warn("%s: multicast not enabled on interface %s",
- __PRETTY_FUNCTION__,
- ifp->name);
- return;
- }
-
- if (!pim_ifp->igmp_join_list)
- return;
-
- for (ALL_LIST_ELEMENTS(pim_ifp->igmp_join_list, node, nextnode, ij))
- pim_if_igmp_join_del(ifp, ij->group_addr, ij->source_addr);
+ struct pim_interface *pim_ifp;
+ struct listnode *node;
+ struct listnode *nextnode;
+ struct igmp_join *ij;
+
+ pim_ifp = ifp->info;
+ if (!pim_ifp) {
+ zlog_warn("%s: multicast not enabled on interface %s",
+ __PRETTY_FUNCTION__, ifp->name);
+ return;
+ }
+
+ if (!pim_ifp->igmp_join_list)
+ return;
+
+ for (ALL_LIST_ELEMENTS(pim_ifp->igmp_join_list, node, nextnode, ij))
+ pim_if_igmp_join_del(ifp, ij->group_addr, ij->source_addr);
}
/*
@@ -1475,63 +1495,66 @@ static void pim_if_igmp_join_del_all(struct interface *ifp)
void pim_if_assert_on_neighbor_down(struct interface *ifp,
struct in_addr neigh_addr)
{
- struct pim_interface *pim_ifp;
- struct listnode *node;
- struct listnode *next_node;
- struct pim_ifchannel *ch;
-
- pim_ifp = ifp->info;
- zassert(pim_ifp);
-
- for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, node, next_node, ch)) {
- /* Is (S,G,I) assert loser ? */
- if (ch->ifassert_state != PIM_IFASSERT_I_AM_LOSER)
- continue;
- /* Dead neighbor was winner ? */
- if (ch->ifassert_winner.s_addr != neigh_addr.s_addr)
- continue;
-
- assert_action_a5(ch);
- }
+ struct pim_interface *pim_ifp;
+ struct listnode *node;
+ struct listnode *next_node;
+ struct pim_ifchannel *ch;
+
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+
+ for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, node, next_node,
+ ch)) {
+ /* Is (S,G,I) assert loser ? */
+ if (ch->ifassert_state != PIM_IFASSERT_I_AM_LOSER)
+ continue;
+ /* Dead neighbor was winner ? */
+ if (ch->ifassert_winner.s_addr != neigh_addr.s_addr)
+ continue;
+
+ assert_action_a5(ch);
+ }
}
void pim_if_update_join_desired(struct pim_interface *pim_ifp)
{
- struct listnode *ch_node;
- struct pim_ifchannel *ch;
+ struct listnode *ch_node;
+ struct pim_ifchannel *ch;
- /* clear off flag from interface's upstreams */
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
- PIM_UPSTREAM_FLAG_UNSET_DR_JOIN_DESIRED_UPDATED(ch->upstream->flags);
- }
+ /* clear off flag from interface's upstreams */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
+ PIM_UPSTREAM_FLAG_UNSET_DR_JOIN_DESIRED_UPDATED(
+ ch->upstream->flags);
+ }
- /* scan per-interface (S,G,I) state on this I interface */
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
- struct pim_upstream *up = ch->upstream;
+ /* scan per-interface (S,G,I) state on this I interface */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
+ struct pim_upstream *up = ch->upstream;
- if (PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED_UPDATED(up->flags))
- continue;
+ if (PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED_UPDATED(up->flags))
+ continue;
- /* update join_desired for the global (S,G) state */
- pim_upstream_update_join_desired(up);
- PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED_UPDATED(up->flags);
- }
+ /* update join_desired for the global (S,G) state */
+ pim_upstream_update_join_desired(up);
+ PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED_UPDATED(up->flags);
+ }
}
void pim_if_update_assert_tracking_desired(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
- struct listnode *node;
- struct listnode *next_node;
- struct pim_ifchannel *ch;
-
- pim_ifp = ifp->info;
- if (!pim_ifp)
- return;
-
- for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, node, next_node, ch)) {
- pim_ifchannel_update_assert_tracking_desired(ch);
- }
+ struct pim_interface *pim_ifp;
+ struct listnode *node;
+ struct listnode *next_node;
+ struct pim_ifchannel *ch;
+
+ pim_ifp = ifp->info;
+ if (!pim_ifp)
+ return;
+
+ for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, node, next_node,
+ ch)) {
+ pim_ifchannel_update_assert_tracking_desired(ch);
+ }
}
/*
@@ -1539,52 +1562,48 @@ void pim_if_update_assert_tracking_desired(struct interface *ifp)
* The pimreg is a special interface that we have that is not
* quite an inteface but a VIF is created for it.
*/
-void pim_if_create_pimreg (void)
+void pim_if_create_pimreg(void)
{
- if (!pim_regiface) {
- pim_regiface = if_create("pimreg", strlen("pimreg"), VRF_DEFAULT);
- pim_regiface->ifindex = PIM_OIF_PIM_REGISTER_VIF;
+ if (!pim_regiface) {
+ pim_regiface =
+ if_create("pimreg", strlen("pimreg"), VRF_DEFAULT);
+ pim_regiface->ifindex = PIM_OIF_PIM_REGISTER_VIF;
- pim_if_new(pim_regiface, 0, 0);
- }
+ pim_if_new(pim_regiface, 0, 0);
+ }
}
-int
-pim_if_connected_to_source (struct interface *ifp, struct in_addr src)
+int pim_if_connected_to_source(struct interface *ifp, struct in_addr src)
{
- struct listnode *cnode;
- struct connected *c;
- struct prefix p;
-
- if (!ifp)
- return 0;
-
- p.family = AF_INET;
- p.u.prefix4 = src;
- p.prefixlen = IPV4_MAX_BITLEN;
-
- for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
- {
- if ((c->address->family == AF_INET) &&
- prefix_match (CONNECTED_PREFIX (c), &p))
- {
- return 1;
- }
- }
-
- return 0;
+ struct listnode *cnode;
+ struct connected *c;
+ struct prefix p;
+
+ if (!ifp)
+ return 0;
+
+ p.family = AF_INET;
+ p.u.prefix4 = src;
+ p.prefixlen = IPV4_MAX_BITLEN;
+
+ for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) {
+ if ((c->address->family == AF_INET)
+ && prefix_match(CONNECTED_PREFIX(c), &p)) {
+ return 1;
+ }
+ }
+
+ return 0;
}
-struct interface *
-pim_if_lookup_address_vrf (struct in_addr src, vrf_id_t vrf_id)
+struct interface *pim_if_lookup_address_vrf(struct in_addr src, vrf_id_t vrf_id)
{
- struct listnode *ifnode;
- struct interface *ifp;
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist(vrf_id), ifnode, ifp))
- {
- if (pim_if_connected_to_source (ifp, src) && ifp->info)
- return ifp;
- }
- return NULL;
+ struct listnode *ifnode;
+ struct interface *ifp;
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf_id), ifnode, ifp)) {
+ if (pim_if_connected_to_source(ifp, src) && ifp->info)
+ return ifp;
+ }
+ return NULL;
}
diff --git a/pimd/pim_iface.h b/pimd/pim_iface.h
index a1c2b692f..e742e68f6 100644
--- a/pimd/pim_iface.h
+++ b/pimd/pim_iface.h
@@ -56,81 +56,86 @@
#define PIM_I_am_DR(pim_ifp) (pim_ifp)->pim_dr_addr.s_addr == (pim_ifp)->primary_address.s_addr
struct pim_iface_upstream_switch {
- struct in_addr address;
- struct list *us;
+ struct in_addr address;
+ struct list *us;
};
enum pim_secondary_addr_flags {
- PIM_SEC_ADDRF_NONE = 0,
- PIM_SEC_ADDRF_STALE = (1 << 0)
+ PIM_SEC_ADDRF_NONE = 0,
+ PIM_SEC_ADDRF_STALE = (1 << 0)
};
struct pim_secondary_addr {
- struct prefix addr;
- enum pim_secondary_addr_flags flags;
+ struct prefix addr;
+ enum pim_secondary_addr_flags flags;
};
struct pim_interface {
- uint32_t options; /* bit vector */
- ifindex_t mroute_vif_index;
- struct in_addr primary_address; /* remember addr to detect change */
- struct list *sec_addr_list; /* list of struct pim_secondary_addr */
- struct in_addr update_source; /* user can statically set the primary
- * address of the interface */
-
- int igmp_version; /* IGMP version */
- 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 */
- int64_t pim_sock_creation; /* timestamp of PIM socket creation */
-
- struct thread *t_pim_hello_timer;
- int pim_hello_period;
- int pim_default_holdtime;
- int pim_triggered_hello_delay;
- uint32_t pim_generation_id;
- uint16_t pim_propagation_delay_msec; /* config */
- uint16_t pim_override_interval_msec; /* config */
- struct list *pim_neighbor_list; /* list of struct pim_neighbor */
- struct list *upstream_switch_list;
- struct list *pim_ifchannel_list; /* list of struct pim_ifchannel */
- struct hash *pim_ifchannel_hash;
-
- /* neighbors without lan_delay */
- int pim_number_of_nonlandelay_neighbors;
- uint16_t pim_neighbors_highest_propagation_delay_msec;
- uint16_t pim_neighbors_highest_override_interval_msec;
-
- /* DR Election */
- int64_t pim_dr_election_last; /* timestamp */
- int pim_dr_election_count;
- int pim_dr_election_changes;
- struct in_addr pim_dr_addr;
- uint32_t pim_dr_priority; /* config */
- int pim_dr_num_nondrpri_neighbors; /* neighbors without dr_pri */
-
- int64_t pim_ifstat_start; /* start timestamp for stats */
- uint32_t pim_ifstat_hello_sent;
- uint32_t pim_ifstat_hello_sendfail;
- uint32_t pim_ifstat_hello_recv;
- uint32_t pim_ifstat_hello_recvfail;
- uint32_t pim_ifstat_join_recv;
- uint32_t pim_ifstat_join_send;
- uint32_t pim_ifstat_prune_recv;
- uint32_t pim_ifstat_prune_send;
- uint32_t pim_ifstat_reg_recv;
- uint32_t pim_ifstat_reg_send;
- uint32_t pim_ifstat_reg_stop_recv;
- uint32_t pim_ifstat_reg_stop_send;
- uint32_t pim_ifstat_assert_recv;
- uint32_t pim_ifstat_assert_send;
- struct bfd_info *bfd_info;
+ uint32_t options; /* bit vector */
+ ifindex_t mroute_vif_index;
+ struct in_addr primary_address; /* remember addr to detect change */
+ struct list *sec_addr_list; /* list of struct pim_secondary_addr */
+ struct in_addr update_source; /* user can statically set the primary
+ * address of the interface */
+
+ int igmp_version; /* IGMP version */
+ 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 */
+ int64_t pim_sock_creation; /* timestamp of PIM socket creation */
+
+ struct thread *t_pim_hello_timer;
+ int pim_hello_period;
+ int pim_default_holdtime;
+ int pim_triggered_hello_delay;
+ uint32_t pim_generation_id;
+ uint16_t pim_propagation_delay_msec; /* config */
+ uint16_t pim_override_interval_msec; /* config */
+ struct list *pim_neighbor_list; /* list of struct pim_neighbor */
+ struct list *upstream_switch_list;
+ struct list *pim_ifchannel_list; /* list of struct pim_ifchannel */
+ struct hash *pim_ifchannel_hash;
+
+ /* neighbors without lan_delay */
+ int pim_number_of_nonlandelay_neighbors;
+ uint16_t pim_neighbors_highest_propagation_delay_msec;
+ uint16_t pim_neighbors_highest_override_interval_msec;
+
+ /* DR Election */
+ int64_t pim_dr_election_last; /* timestamp */
+ int pim_dr_election_count;
+ int pim_dr_election_changes;
+ struct in_addr pim_dr_addr;
+ uint32_t pim_dr_priority; /* config */
+ int pim_dr_num_nondrpri_neighbors; /* neighbors without dr_pri */
+
+ int64_t pim_ifstat_start; /* start timestamp for stats */
+ uint32_t pim_ifstat_hello_sent;
+ uint32_t pim_ifstat_hello_sendfail;
+ uint32_t pim_ifstat_hello_recv;
+ uint32_t pim_ifstat_hello_recvfail;
+ uint32_t pim_ifstat_join_recv;
+ uint32_t pim_ifstat_join_send;
+ uint32_t pim_ifstat_prune_recv;
+ uint32_t pim_ifstat_prune_send;
+ uint32_t pim_ifstat_reg_recv;
+ uint32_t pim_ifstat_reg_send;
+ uint32_t pim_ifstat_reg_stop_recv;
+ uint32_t pim_ifstat_reg_stop_send;
+ uint32_t pim_ifstat_assert_recv;
+ uint32_t pim_ifstat_assert_send;
+ struct bfd_info *bfd_info;
};
extern struct interface *pim_regiface;
@@ -139,16 +144,16 @@ extern struct list *pim_ifchannel_list;
if default_holdtime is set (>= 0), use it;
otherwise default_holdtime is 3.5 * hello_period
*/
-#define PIM_IF_DEFAULT_HOLDTIME(pim_ifp) \
- (((pim_ifp)->pim_default_holdtime < 0) ? \
- ((pim_ifp)->pim_hello_period * 7 / 2) : \
- ((pim_ifp)->pim_default_holdtime))
+#define PIM_IF_DEFAULT_HOLDTIME(pim_ifp) \
+ (((pim_ifp)->pim_default_holdtime < 0) \
+ ? ((pim_ifp)->pim_hello_period * 7 / 2) \
+ : ((pim_ifp)->pim_default_holdtime))
void pim_if_init(void);
-void pim_if_terminate (void);
+void pim_if_terminate(void);
struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim);
-void pim_if_delete(struct interface *ifp);
+void pim_if_delete(struct interface *ifp);
void pim_if_addr_add(struct connected *ifc);
void pim_if_addr_del(struct connected *ifc, int force_prim_as_any);
void pim_if_addr_add_all(struct interface *ifp);
@@ -156,7 +161,8 @@ void pim_if_addr_del_all(struct interface *ifp);
void pim_if_addr_del_all_igmp(struct interface *ifp);
void pim_if_addr_del_all_pim(struct interface *ifp);
-struct interface *pim_if_lookup_address_vrf (struct in_addr src, vrf_id_t vrf_id);
+struct interface *pim_if_lookup_address_vrf(struct in_addr src,
+ vrf_id_t vrf_id);
int pim_if_add_vif(struct interface *ifp);
int pim_if_del_vif(struct interface *ifp);
@@ -178,11 +184,9 @@ int pim_if_t_override_msec(struct interface *ifp);
struct in_addr pim_find_primary_addr(struct interface *ifp);
-int pim_if_igmp_join_add(struct interface *ifp,
- struct in_addr group_addr,
+int pim_if_igmp_join_add(struct interface *ifp, struct in_addr group_addr,
struct in_addr source_addr);
-int pim_if_igmp_join_del(struct interface *ifp,
- struct in_addr group_addr,
+int pim_if_igmp_join_del(struct interface *ifp, struct in_addr group_addr,
struct in_addr source_addr);
void pim_if_update_could_assert(struct interface *ifp);
@@ -199,7 +203,7 @@ void pim_if_update_assert_tracking_desired(struct interface *ifp);
void pim_if_create_pimreg(void);
-int pim_if_connected_to_source (struct interface *ifp, struct in_addr src);
+int pim_if_connected_to_source(struct interface *ifp, struct in_addr src);
int pim_update_source_set(struct interface *ifp, struct in_addr source);
#endif /* PIM_IFACE_H */
diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c
index 021722dfc..d4916518e 100644
--- a/pimd/pim_ifchannel.c
+++ b/pimd/pim_ifchannel.c
@@ -43,34 +43,33 @@
#include "pim_upstream.h"
#include "pim_ssm.h"
-int
-pim_ifchannel_compare (struct pim_ifchannel *ch1, struct pim_ifchannel *ch2)
+int pim_ifchannel_compare(struct pim_ifchannel *ch1, struct pim_ifchannel *ch2)
{
- struct pim_interface *pim_ifp1;
- struct pim_interface *pim_ifp2;
+ struct pim_interface *pim_ifp1;
+ struct pim_interface *pim_ifp2;
- pim_ifp1 = ch1->interface->info;
- pim_ifp2 = ch2->interface->info;
+ pim_ifp1 = ch1->interface->info;
+ pim_ifp2 = ch2->interface->info;
- if (pim_ifp1->mroute_vif_index < pim_ifp2->mroute_vif_index)
- return -1;
+ if (pim_ifp1->mroute_vif_index < pim_ifp2->mroute_vif_index)
+ return -1;
- if (pim_ifp1->mroute_vif_index > pim_ifp2->mroute_vif_index)
- return 1;
+ if (pim_ifp1->mroute_vif_index > pim_ifp2->mroute_vif_index)
+ return 1;
- if (ntohl(ch1->sg.grp.s_addr) < ntohl(ch2->sg.grp.s_addr))
- return -1;
+ if (ntohl(ch1->sg.grp.s_addr) < ntohl(ch2->sg.grp.s_addr))
+ return -1;
- if (ntohl(ch1->sg.grp.s_addr) > ntohl(ch2->sg.grp.s_addr))
- return 1;
+ if (ntohl(ch1->sg.grp.s_addr) > ntohl(ch2->sg.grp.s_addr))
+ return 1;
- if (ntohl(ch1->sg.src.s_addr) < ntohl(ch2->sg.src.s_addr))
- return -1;
+ if (ntohl(ch1->sg.src.s_addr) < ntohl(ch2->sg.src.s_addr))
+ return -1;
- if (ntohl(ch1->sg.src.s_addr) > ntohl(ch2->sg.src.s_addr))
- return 1;
+ if (ntohl(ch1->sg.src.s_addr) > ntohl(ch2->sg.src.s_addr))
+ return 1;
- return 0;
+ return 0;
}
/*
@@ -78,20 +77,18 @@ pim_ifchannel_compare (struct pim_ifchannel *ch1, struct pim_ifchannel *ch2)
* remove the parent pointer from
* those pointing at us
*/
-static void
-pim_ifchannel_remove_children (struct pim_ifchannel *ch)
+static void pim_ifchannel_remove_children(struct pim_ifchannel *ch)
{
- struct pim_ifchannel *child;
+ struct pim_ifchannel *child;
- if (!ch->sources)
- return;
+ if (!ch->sources)
+ return;
- while (!list_isempty (ch->sources))
- {
- child = listnode_head (ch->sources);
- child->parent = NULL;
- listnode_delete (ch->sources, child);
- }
+ while (!list_isempty(ch->sources)) {
+ child = listnode_head(ch->sources);
+ child->parent = NULL;
+ listnode_delete(ch->sources, child);
+ }
}
/*
@@ -99,284 +96,302 @@ pim_ifchannel_remove_children (struct pim_ifchannel *ch)
* find all the children that would point
* at us.
*/
-static void
-pim_ifchannel_find_new_children (struct pim_ifchannel *ch)
+static void pim_ifchannel_find_new_children(struct pim_ifchannel *ch)
{
- struct pim_interface *pim_ifp = ch->interface->info;
- struct pim_ifchannel *child;
- struct listnode *ch_node;
-
- // Basic Sanity that we are not being silly
- if ((ch->sg.src.s_addr != INADDR_ANY) &&
- (ch->sg.grp.s_addr != INADDR_ANY))
- return;
-
- if ((ch->sg.src.s_addr == INADDR_ANY) &&
- (ch->sg.grp.s_addr == INADDR_ANY))
- return;
-
- for (ALL_LIST_ELEMENTS_RO (pim_ifp->pim_ifchannel_list, ch_node, child))
- {
- if ((ch->sg.grp.s_addr != INADDR_ANY) &&
- (child->sg.grp.s_addr == ch->sg.grp.s_addr) &&
- (child != ch))
- {
- child->parent = ch;
- listnode_add_sort (ch->sources, child);
+ struct pim_interface *pim_ifp = ch->interface->info;
+ struct pim_ifchannel *child;
+ struct listnode *ch_node;
+
+ // Basic Sanity that we are not being silly
+ if ((ch->sg.src.s_addr != INADDR_ANY)
+ && (ch->sg.grp.s_addr != INADDR_ANY))
+ return;
+
+ if ((ch->sg.src.s_addr == INADDR_ANY)
+ && (ch->sg.grp.s_addr == INADDR_ANY))
+ return;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node,
+ child)) {
+ if ((ch->sg.grp.s_addr != INADDR_ANY)
+ && (child->sg.grp.s_addr == ch->sg.grp.s_addr)
+ && (child != ch)) {
+ child->parent = ch;
+ listnode_add_sort(ch->sources, child);
+ }
}
- }
}
void pim_ifchannel_free(struct pim_ifchannel *ch)
{
- XFREE(MTYPE_PIM_IFCHANNEL, ch);
+ XFREE(MTYPE_PIM_IFCHANNEL, ch);
}
void pim_ifchannel_delete(struct pim_ifchannel *ch)
{
- struct pim_interface *pim_ifp;
-
- pim_ifp = ch->interface->info;
-
- if (ch->upstream->channel_oil)
- {
- uint32_t mask = PIM_OIF_FLAG_PROTO_PIM;
- if (ch->upstream->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
- mask = PIM_OIF_FLAG_PROTO_IGMP;
-
- /* SGRpt entry could have empty oil */
- if (ch->upstream->channel_oil)
- pim_channel_del_oif (ch->upstream->channel_oil, ch->interface, mask);
- /*
- * Do we have any S,G's that are inheriting?
- * Nuke from on high too.
- */
- if (ch->upstream->sources)
- {
- struct pim_upstream *child;
- struct listnode *up_node;
-
- for (ALL_LIST_ELEMENTS_RO (ch->upstream->sources, up_node, child))
- pim_channel_del_oif (child->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
+ struct pim_interface *pim_ifp;
+
+ pim_ifp = ch->interface->info;
+
+ if (ch->upstream->channel_oil) {
+ uint32_t mask = PIM_OIF_FLAG_PROTO_PIM;
+ if (ch->upstream->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
+ mask = PIM_OIF_FLAG_PROTO_IGMP;
+
+ /* SGRpt entry could have empty oil */
+ if (ch->upstream->channel_oil)
+ pim_channel_del_oif(ch->upstream->channel_oil,
+ ch->interface, mask);
+ /*
+ * Do we have any S,G's that are inheriting?
+ * Nuke from on high too.
+ */
+ if (ch->upstream->sources) {
+ struct pim_upstream *child;
+ struct listnode *up_node;
+
+ for (ALL_LIST_ELEMENTS_RO(ch->upstream->sources,
+ up_node, child))
+ pim_channel_del_oif(child->channel_oil,
+ ch->interface,
+ PIM_OIF_FLAG_PROTO_STAR);
+ }
+ }
+
+ /*
+ * When this channel is removed
+ * we need to find all our children
+ * and make sure our pointers are fixed
+ */
+ pim_ifchannel_remove_children(ch);
+
+ if (ch->sources)
+ list_delete(ch->sources);
+
+ listnode_delete(ch->upstream->ifchannels, ch);
+
+ if (ch->ifjoin_state != PIM_IFJOIN_NOINFO) {
+ pim_upstream_update_join_desired(ch->upstream);
}
- }
-
- /*
- * When this channel is removed
- * we need to find all our children
- * and make sure our pointers are fixed
- */
- pim_ifchannel_remove_children (ch);
-
- if (ch->sources)
- list_delete (ch->sources);
-
- listnode_delete(ch->upstream->ifchannels, ch);
-
- if (ch->ifjoin_state != PIM_IFJOIN_NOINFO) {
- pim_upstream_update_join_desired(ch->upstream);
- }
-
- /* upstream is common across ifchannels, check if upstream's
- ifchannel list is empty before deleting upstream_del
- ref count will take care of it.
- */
- pim_upstream_del(ch->upstream, __PRETTY_FUNCTION__);
- ch->upstream = NULL;
-
- THREAD_OFF(ch->t_ifjoin_expiry_timer);
- THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
- THREAD_OFF(ch->t_ifassert_timer);
-
- if (ch->parent)
- {
- listnode_delete (ch->parent->sources, ch);
- ch->parent = NULL;
- }
- /*
- notice that listnode_delete() can't be moved
- into pim_ifchannel_free() because the later is
- called by list_delete_all_node()
- */
- listnode_delete(pim_ifp->pim_ifchannel_list, ch);
- hash_release(pim_ifp->pim_ifchannel_hash, ch);
- listnode_delete(pim_ifchannel_list, ch);
-
- if (PIM_DEBUG_PIM_TRACE)
- zlog_debug ("%s: ifchannel entry %s is deleted ", __PRETTY_FUNCTION__, ch->sg_str);
-
- pim_ifchannel_free(ch);
+
+ /* upstream is common across ifchannels, check if upstream's
+ ifchannel list is empty before deleting upstream_del
+ ref count will take care of it.
+ */
+ pim_upstream_del(ch->upstream, __PRETTY_FUNCTION__);
+ ch->upstream = NULL;
+
+ THREAD_OFF(ch->t_ifjoin_expiry_timer);
+ THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
+ THREAD_OFF(ch->t_ifassert_timer);
+
+ if (ch->parent) {
+ listnode_delete(ch->parent->sources, ch);
+ ch->parent = NULL;
+ }
+ /*
+ notice that listnode_delete() can't be moved
+ into pim_ifchannel_free() because the later is
+ called by list_delete_all_node()
+ */
+ listnode_delete(pim_ifp->pim_ifchannel_list, ch);
+ hash_release(pim_ifp->pim_ifchannel_hash, ch);
+ listnode_delete(pim_ifchannel_list, ch);
+
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug("%s: ifchannel entry %s is deleted ",
+ __PRETTY_FUNCTION__, ch->sg_str);
+
+ pim_ifchannel_free(ch);
}
-void
-pim_ifchannel_delete_all (struct interface *ifp)
+void pim_ifchannel_delete_all(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
- struct listnode *ifchannel_node;
- struct listnode *ifchannel_nextnode;
- struct pim_ifchannel *ifchannel;
-
- pim_ifp = ifp->info;
- if (!pim_ifp)
- return;
-
- for (ALL_LIST_ELEMENTS (pim_ifp->pim_ifchannel_list, ifchannel_node,
- ifchannel_nextnode, ifchannel))
- {
- pim_ifchannel_delete (ifchannel);
- }
+ struct pim_interface *pim_ifp;
+ struct listnode *ifchannel_node;
+ struct listnode *ifchannel_nextnode;
+ struct pim_ifchannel *ifchannel;
+
+ pim_ifp = ifp->info;
+ if (!pim_ifp)
+ return;
+
+ for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, ifchannel_node,
+ ifchannel_nextnode, ifchannel)) {
+ pim_ifchannel_delete(ifchannel);
+ }
}
-
+
static void delete_on_noinfo(struct pim_ifchannel *ch)
{
- if (ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO &&
- ch->ifjoin_state == PIM_IFJOIN_NOINFO &&
- ch->t_ifjoin_expiry_timer == NULL)
- pim_ifchannel_delete(ch);
-
+ if (ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO
+ && ch->ifjoin_state == PIM_IFJOIN_NOINFO
+ && ch->t_ifjoin_expiry_timer == NULL)
+ pim_ifchannel_delete(ch);
}
-void pim_ifchannel_ifjoin_switch(const char *caller,
- struct pim_ifchannel *ch,
+void pim_ifchannel_ifjoin_switch(const char *caller, struct pim_ifchannel *ch,
enum pim_ifjoin_state new_state)
{
- enum pim_ifjoin_state old_state = ch->ifjoin_state;
-
- if (PIM_DEBUG_PIM_EVENTS)
- zlog_debug ("PIM_IFCHANNEL(%s): %s is switching from %s to %s",
- ch->interface->name,
- ch->sg_str,
- pim_ifchannel_ifjoin_name (ch->ifjoin_state, ch->flags),
- pim_ifchannel_ifjoin_name (new_state, 0));
-
-
- if (old_state == new_state) {
- if (PIM_DEBUG_PIM_EVENTS) {
- zlog_debug("%s calledby %s: non-transition on state %d (%s)",
- __PRETTY_FUNCTION__, caller, new_state,
- pim_ifchannel_ifjoin_name(new_state, 0));
- }
- return;
- }
-
- ch->ifjoin_state = new_state;
-
- if (ch->sg.src.s_addr == INADDR_ANY)
- {
- struct pim_upstream *up = ch->upstream;
- struct pim_upstream *child;
- struct listnode *up_node;
-
- if (up)
- {
- if (ch->ifjoin_state == PIM_IFJOIN_NOINFO)
- {
- for (ALL_LIST_ELEMENTS_RO (up->sources, up_node, child))
- {
- struct channel_oil *c_oil = child->channel_oil;
- struct pim_interface *pim_ifp = ch->interface->info;
-
- if (PIM_DEBUG_PIM_TRACE)
- zlog_debug("%s %s: Prune(S,G)=%s from %s",
- __FILE__, __PRETTY_FUNCTION__,
- child->sg_str, up->sg_str);
- if (!c_oil)
- continue;
-
- if (!pim_upstream_evaluate_join_desired (child))
- {
- pim_channel_del_oif (c_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
- pim_upstream_update_join_desired (child);
- }
-
- /*
- * If the S,G has no if channel and the c_oil still
- * has output here then the *,G was supplying the implied
- * if channel. So remove it.
- * I think this is dead code now. is it?
- */
- if (!ch && c_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index])
- pim_channel_del_oif (c_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
+ enum pim_ifjoin_state old_state = ch->ifjoin_state;
+
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_debug(
+ "PIM_IFCHANNEL(%s): %s is switching from %s to %s",
+ ch->interface->name, ch->sg_str,
+ pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags),
+ pim_ifchannel_ifjoin_name(new_state, 0));
+
+
+ if (old_state == new_state) {
+ if (PIM_DEBUG_PIM_EVENTS) {
+ zlog_debug(
+ "%s calledby %s: non-transition on state %d (%s)",
+ __PRETTY_FUNCTION__, caller, new_state,
+ pim_ifchannel_ifjoin_name(new_state, 0));
}
- }
- if (ch->ifjoin_state == PIM_IFJOIN_JOIN)
- {
- for (ALL_LIST_ELEMENTS_RO (up->sources, up_node, child))
- {
- if (PIM_DEBUG_PIM_TRACE)
- zlog_debug("%s %s: Join(S,G)=%s from %s",
- __FILE__, __PRETTY_FUNCTION__,
- child->sg_str, up->sg_str);
-
- if (pim_upstream_evaluate_join_desired (child))
- {
- pim_channel_add_oif (child->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
- pim_upstream_update_join_desired (child);
- }
+ return;
+ }
+
+ ch->ifjoin_state = new_state;
+
+ if (ch->sg.src.s_addr == INADDR_ANY) {
+ struct pim_upstream *up = ch->upstream;
+ struct pim_upstream *child;
+ struct listnode *up_node;
+
+ if (up) {
+ if (ch->ifjoin_state == PIM_IFJOIN_NOINFO) {
+ for (ALL_LIST_ELEMENTS_RO(up->sources, up_node,
+ child)) {
+ struct channel_oil *c_oil =
+ child->channel_oil;
+ struct pim_interface *pim_ifp =
+ ch->interface->info;
+
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug(
+ "%s %s: Prune(S,G)=%s from %s",
+ __FILE__,
+ __PRETTY_FUNCTION__,
+ child->sg_str,
+ up->sg_str);
+ if (!c_oil)
+ continue;
+
+ if (!pim_upstream_evaluate_join_desired(
+ child)) {
+ pim_channel_del_oif(
+ c_oil, ch->interface,
+ PIM_OIF_FLAG_PROTO_STAR);
+ pim_upstream_update_join_desired(
+ child);
+ }
+
+ /*
+ * If the S,G has no if channel and the
+ * c_oil still
+ * has output here then the *,G was
+ * supplying the implied
+ * if channel. So remove it.
+ * I think this is dead code now. is it?
+ */
+ if (!ch
+ && c_oil->oil.mfcc_ttls
+ [pim_ifp->mroute_vif_index])
+ pim_channel_del_oif(
+ c_oil, ch->interface,
+ PIM_OIF_FLAG_PROTO_STAR);
+ }
+ }
+ if (ch->ifjoin_state == PIM_IFJOIN_JOIN) {
+ for (ALL_LIST_ELEMENTS_RO(up->sources, up_node,
+ child)) {
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug(
+ "%s %s: Join(S,G)=%s from %s",
+ __FILE__,
+ __PRETTY_FUNCTION__,
+ child->sg_str,
+ up->sg_str);
+
+ if (pim_upstream_evaluate_join_desired(
+ child)) {
+ pim_channel_add_oif(
+ child->channel_oil,
+ ch->interface,
+ PIM_OIF_FLAG_PROTO_STAR);
+ pim_upstream_update_join_desired(
+ child);
+ }
+ }
+ }
}
- }
}
- }
- /* Transition to/from NOINFO ? */
- if ((old_state == PIM_IFJOIN_NOINFO) ||
- (new_state == PIM_IFJOIN_NOINFO)) {
-
- if (PIM_DEBUG_PIM_EVENTS) {
- zlog_debug("PIM_IFCHANNEL_%s: (S,G)=%s on interface %s",
- ((new_state == PIM_IFJOIN_NOINFO) ? "DOWN" : "UP"),
- ch->sg_str, ch->interface->name);
- }
-
- /*
- Record uptime of state transition to/from NOINFO
- */
- ch->ifjoin_creation = pim_time_monotonic_sec();
-
- pim_upstream_update_join_desired(ch->upstream);
- pim_ifchannel_update_could_assert(ch);
- pim_ifchannel_update_assert_tracking_desired(ch);
- }
+ /* Transition to/from NOINFO ? */
+ if ((old_state == PIM_IFJOIN_NOINFO)
+ || (new_state == PIM_IFJOIN_NOINFO)) {
+
+ if (PIM_DEBUG_PIM_EVENTS) {
+ zlog_debug("PIM_IFCHANNEL_%s: (S,G)=%s on interface %s",
+ ((new_state == PIM_IFJOIN_NOINFO) ? "DOWN"
+ : "UP"),
+ ch->sg_str, ch->interface->name);
+ }
+
+ /*
+ Record uptime of state transition to/from NOINFO
+ */
+ ch->ifjoin_creation = pim_time_monotonic_sec();
+
+ pim_upstream_update_join_desired(ch->upstream);
+ pim_ifchannel_update_could_assert(ch);
+ pim_ifchannel_update_assert_tracking_desired(ch);
+ }
}
const char *pim_ifchannel_ifjoin_name(enum pim_ifjoin_state ifjoin_state,
- int flags)
+ int flags)
{
- switch (ifjoin_state) {
- case PIM_IFJOIN_NOINFO:
- if (PIM_IF_FLAG_TEST_S_G_RPT(flags))
- return "SGRpt";
- else
- return "NOINFO";
- break;
- case PIM_IFJOIN_JOIN:
- return "JOIN";
- break;
- case PIM_IFJOIN_PRUNE:
- return "PRUNE";
- break;
- case PIM_IFJOIN_PRUNE_PENDING:
- return "PRUNEP";
- break;
- case PIM_IFJOIN_PRUNE_TMP:
- return "PRUNET";
- break;
- case PIM_IFJOIN_PRUNE_PENDING_TMP:
- return "PRUNEPT";
- break;
- }
-
- return "ifjoin_bad_state";
+ switch (ifjoin_state) {
+ case PIM_IFJOIN_NOINFO:
+ if (PIM_IF_FLAG_TEST_S_G_RPT(flags))
+ return "SGRpt";
+ else
+ return "NOINFO";
+ break;
+ case PIM_IFJOIN_JOIN:
+ return "JOIN";
+ break;
+ case PIM_IFJOIN_PRUNE:
+ return "PRUNE";
+ break;
+ case PIM_IFJOIN_PRUNE_PENDING:
+ return "PRUNEP";
+ break;
+ case PIM_IFJOIN_PRUNE_TMP:
+ return "PRUNET";
+ break;
+ case PIM_IFJOIN_PRUNE_PENDING_TMP:
+ return "PRUNEPT";
+ break;
+ }
+
+ return "ifjoin_bad_state";
}
const char *pim_ifchannel_ifassert_name(enum pim_ifassert_state ifassert_state)
{
- switch (ifassert_state) {
- case PIM_IFASSERT_NOINFO: return "NOINFO";
- case PIM_IFASSERT_I_AM_WINNER: return "WINNER";
- case PIM_IFASSERT_I_AM_LOSER: return "LOSER";
- }
+ switch (ifassert_state) {
+ case PIM_IFASSERT_NOINFO:
+ return "NOINFO";
+ case PIM_IFASSERT_I_AM_WINNER:
+ return "WINNER";
+ case PIM_IFASSERT_I_AM_LOSER:
+ return "LOSER";
+ }
- return "ifassert_bad_state";
+ return "ifassert_bad_state";
}
/*
@@ -387,88 +402,85 @@ const char *pim_ifchannel_ifassert_name(enum pim_ifassert_state ifassert_state)
*/
void reset_ifassert_state(struct pim_ifchannel *ch)
{
- struct in_addr any = { .s_addr = INADDR_ANY };
+ struct in_addr any = {.s_addr = INADDR_ANY};
- THREAD_OFF(ch->t_ifassert_timer);
+ THREAD_OFF(ch->t_ifassert_timer);
- pim_ifassert_winner_set(ch,
- PIM_IFASSERT_NOINFO,
- any,
- qpim_infinite_assert_metric);
+ pim_ifassert_winner_set(ch, PIM_IFASSERT_NOINFO, any,
+ qpim_infinite_assert_metric);
}
struct pim_ifchannel *pim_ifchannel_find(struct interface *ifp,
struct prefix_sg *sg)
{
- struct pim_interface *pim_ifp;
- struct pim_ifchannel *ch;
- struct pim_ifchannel lookup;
+ struct pim_interface *pim_ifp;
+ struct pim_ifchannel *ch;
+ struct pim_ifchannel lookup;
- pim_ifp = ifp->info;
+ pim_ifp = ifp->info;
- if (!pim_ifp) {
- zlog_warn("%s: (S,G)=%s: multicast not enabled on interface %s",
- __PRETTY_FUNCTION__,
- pim_str_sg_dump (sg),
- ifp->name);
- return NULL;
- }
+ if (!pim_ifp) {
+ zlog_warn("%s: (S,G)=%s: multicast not enabled on interface %s",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(sg), ifp->name);
+ return NULL;
+ }
- lookup.sg = *sg;
- ch = hash_lookup (pim_ifp->pim_ifchannel_hash, &lookup);
+ lookup.sg = *sg;
+ ch = hash_lookup(pim_ifp->pim_ifchannel_hash, &lookup);
- return ch;
+ return ch;
}
static void ifmembership_set(struct pim_ifchannel *ch,
enum pim_ifmembership membership)
{
- if (ch->local_ifmembership == membership)
- return;
-
- if (PIM_DEBUG_PIM_EVENTS) {
- zlog_debug("%s: (S,G)=%s membership now is %s on interface %s",
- __PRETTY_FUNCTION__,
- ch->sg_str,
- membership == PIM_IFMEMBERSHIP_INCLUDE ? "INCLUDE" : "NOINFO",
- ch->interface->name);
- }
-
- ch->local_ifmembership = membership;
-
- pim_upstream_update_join_desired(ch->upstream);
- pim_ifchannel_update_could_assert(ch);
- pim_ifchannel_update_assert_tracking_desired(ch);
+ if (ch->local_ifmembership == membership)
+ return;
+
+ if (PIM_DEBUG_PIM_EVENTS) {
+ zlog_debug("%s: (S,G)=%s membership now is %s on interface %s",
+ __PRETTY_FUNCTION__, ch->sg_str,
+ membership == PIM_IFMEMBERSHIP_INCLUDE ? "INCLUDE"
+ : "NOINFO",
+ ch->interface->name);
+ }
+
+ ch->local_ifmembership = membership;
+
+ pim_upstream_update_join_desired(ch->upstream);
+ pim_ifchannel_update_could_assert(ch);
+ pim_ifchannel_update_assert_tracking_desired(ch);
}
void pim_ifchannel_membership_clear(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
- struct listnode *ch_node;
- struct pim_ifchannel *ch;
+ struct pim_interface *pim_ifp;
+ struct listnode *ch_node;
+ struct pim_ifchannel *ch;
- pim_ifp = ifp->info;
- zassert(pim_ifp);
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
- ifmembership_set(ch, PIM_IFMEMBERSHIP_NOINFO);
- }
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
+ ifmembership_set(ch, PIM_IFMEMBERSHIP_NOINFO);
+ }
}
void pim_ifchannel_delete_on_noinfo(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
- struct listnode *node;
- struct listnode *next_node;
- struct pim_ifchannel *ch;
+ struct pim_interface *pim_ifp;
+ struct listnode *node;
+ struct listnode *next_node;
+ struct pim_ifchannel *ch;
- pim_ifp = ifp->info;
- zassert(pim_ifp);
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
- for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, node, next_node, ch)) {
- delete_on_noinfo(ch);
- }
+ for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, node, next_node,
+ ch)) {
+ delete_on_noinfo(ch);
+ }
}
/*
@@ -477,682 +489,687 @@ void pim_ifchannel_delete_on_noinfo(struct interface *ifp)
* If we are passed a *,G, find the *,* ifchannel
* if we have it.
*/
-static struct pim_ifchannel *
-pim_ifchannel_find_parent (struct pim_ifchannel *ch)
+static struct pim_ifchannel *pim_ifchannel_find_parent(struct pim_ifchannel *ch)
{
- struct prefix_sg parent_sg = ch->sg;
- struct pim_ifchannel *parent = NULL;
-
- // (S,G)
- if ((parent_sg.src.s_addr != INADDR_ANY) &&
- (parent_sg.grp.s_addr != INADDR_ANY))
- {
- parent_sg.src.s_addr = INADDR_ANY;
- parent = pim_ifchannel_find (ch->interface, &parent_sg);
-
- if (parent)
- listnode_add (parent->sources, ch);
- return parent;
- }
-
- return NULL;
+ struct prefix_sg parent_sg = ch->sg;
+ struct pim_ifchannel *parent = NULL;
+
+ // (S,G)
+ if ((parent_sg.src.s_addr != INADDR_ANY)
+ && (parent_sg.grp.s_addr != INADDR_ANY)) {
+ parent_sg.src.s_addr = INADDR_ANY;
+ parent = pim_ifchannel_find(ch->interface, &parent_sg);
+
+ if (parent)
+ listnode_add(parent->sources, ch);
+ return parent;
+ }
+
+ return NULL;
}
-struct pim_ifchannel *
-pim_ifchannel_add(struct interface *ifp,
- struct prefix_sg *sg, int flags)
+struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp,
+ struct prefix_sg *sg, int flags)
{
- struct pim_interface *pim_ifp;
- struct pim_ifchannel *ch;
- struct pim_upstream *up;
-
- ch = pim_ifchannel_find(ifp, sg);
- if (ch)
- return ch;
-
- pim_ifp = ifp->info;
-
- up = pim_upstream_add(sg, NULL, flags, __PRETTY_FUNCTION__);
- if (!up) {
- zlog_err("%s: could not attach upstream (S,G)=%s on interface %s",
- __PRETTY_FUNCTION__,
- pim_str_sg_dump (sg), ifp->name);
- return NULL;
- }
-
- ch = XCALLOC(MTYPE_PIM_IFCHANNEL, sizeof(*ch));
- if (!ch) {
- zlog_warn("%s: pim_ifchannel_new() failure for (S,G)=%s on interface %s",
- __PRETTY_FUNCTION__,
- up->sg_str, ifp->name);
-
- pim_upstream_del (up, __PRETTY_FUNCTION__);
- return NULL;
- }
-
- ch->flags = 0;
- ch->upstream = up;
- ch->interface = ifp;
- ch->sg = *sg;
- pim_str_sg_set (sg, ch->sg_str);
- ch->parent = pim_ifchannel_find_parent (ch);
- if (ch->sg.src.s_addr == INADDR_ANY)
- {
- ch->sources = list_new ();
- ch->sources->cmp = (int (*)(void *, void *))pim_ifchannel_compare;
- }
- else
- ch->sources = NULL;
-
- pim_ifchannel_find_new_children (ch);
- ch->local_ifmembership = PIM_IFMEMBERSHIP_NOINFO;
-
- ch->ifjoin_state = PIM_IFJOIN_NOINFO;
- ch->t_ifjoin_expiry_timer = NULL;
- ch->t_ifjoin_prune_pending_timer = NULL;
- ch->ifjoin_creation = 0;
-
- ch->ifassert_my_metric = pim_macro_ch_my_assert_metric_eval(ch);
- ch->ifassert_winner_metric = pim_macro_ch_my_assert_metric_eval (ch);
-
- ch->ifassert_winner.s_addr = 0;
-
- /* Assert state */
- ch->t_ifassert_timer = NULL;
- ch->ifassert_state = PIM_IFASSERT_NOINFO;
- reset_ifassert_state(ch);
- if (pim_macro_ch_could_assert_eval(ch))
- PIM_IF_FLAG_SET_COULD_ASSERT(ch->flags);
- else
- PIM_IF_FLAG_UNSET_COULD_ASSERT(ch->flags);
-
- if (pim_macro_assert_tracking_desired_eval(ch))
- PIM_IF_FLAG_SET_ASSERT_TRACKING_DESIRED(ch->flags);
- else
- PIM_IF_FLAG_UNSET_ASSERT_TRACKING_DESIRED(ch->flags);
-
- /* Attach to list */
- listnode_add_sort(pim_ifp->pim_ifchannel_list, ch);
- ch = hash_get (pim_ifp->pim_ifchannel_hash, ch, hash_alloc_intern);
- listnode_add_sort(pim_ifchannel_list, ch);
-
- listnode_add_sort(up->ifchannels, ch);
-
- if (PIM_DEBUG_PIM_TRACE)
- zlog_debug ("%s: ifchannel %s is created ", __PRETTY_FUNCTION__, ch->sg_str);
-
- return ch;
+ struct pim_interface *pim_ifp;
+ struct pim_ifchannel *ch;
+ struct pim_upstream *up;
+
+ ch = pim_ifchannel_find(ifp, sg);
+ if (ch)
+ return ch;
+
+ pim_ifp = ifp->info;
+
+ up = pim_upstream_add(sg, NULL, flags, __PRETTY_FUNCTION__);
+ if (!up) {
+ zlog_err(
+ "%s: could not attach upstream (S,G)=%s on interface %s",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(sg), ifp->name);
+ return NULL;
+ }
+
+ ch = XCALLOC(MTYPE_PIM_IFCHANNEL, sizeof(*ch));
+ if (!ch) {
+ zlog_warn(
+ "%s: pim_ifchannel_new() failure for (S,G)=%s on interface %s",
+ __PRETTY_FUNCTION__, up->sg_str, ifp->name);
+
+ pim_upstream_del(up, __PRETTY_FUNCTION__);
+ return NULL;
+ }
+
+ ch->flags = 0;
+ ch->upstream = up;
+ ch->interface = ifp;
+ ch->sg = *sg;
+ pim_str_sg_set(sg, ch->sg_str);
+ ch->parent = pim_ifchannel_find_parent(ch);
+ if (ch->sg.src.s_addr == INADDR_ANY) {
+ ch->sources = list_new();
+ ch->sources->cmp =
+ (int (*)(void *, void *))pim_ifchannel_compare;
+ } else
+ ch->sources = NULL;
+
+ pim_ifchannel_find_new_children(ch);
+ ch->local_ifmembership = PIM_IFMEMBERSHIP_NOINFO;
+
+ ch->ifjoin_state = PIM_IFJOIN_NOINFO;
+ ch->t_ifjoin_expiry_timer = NULL;
+ ch->t_ifjoin_prune_pending_timer = NULL;
+ ch->ifjoin_creation = 0;
+
+ ch->ifassert_my_metric = pim_macro_ch_my_assert_metric_eval(ch);
+ ch->ifassert_winner_metric = pim_macro_ch_my_assert_metric_eval(ch);
+
+ ch->ifassert_winner.s_addr = 0;
+
+ /* Assert state */
+ ch->t_ifassert_timer = NULL;
+ ch->ifassert_state = PIM_IFASSERT_NOINFO;
+ reset_ifassert_state(ch);
+ if (pim_macro_ch_could_assert_eval(ch))
+ PIM_IF_FLAG_SET_COULD_ASSERT(ch->flags);
+ else
+ PIM_IF_FLAG_UNSET_COULD_ASSERT(ch->flags);
+
+ if (pim_macro_assert_tracking_desired_eval(ch))
+ PIM_IF_FLAG_SET_ASSERT_TRACKING_DESIRED(ch->flags);
+ else
+ PIM_IF_FLAG_UNSET_ASSERT_TRACKING_DESIRED(ch->flags);
+
+ /* Attach to list */
+ listnode_add_sort(pim_ifp->pim_ifchannel_list, ch);
+ ch = hash_get(pim_ifp->pim_ifchannel_hash, ch, hash_alloc_intern);
+ listnode_add_sort(pim_ifchannel_list, ch);
+
+ listnode_add_sort(up->ifchannels, ch);
+
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug("%s: ifchannel %s is created ", __PRETTY_FUNCTION__,
+ ch->sg_str);
+
+ return ch;
}
static void ifjoin_to_noinfo(struct pim_ifchannel *ch, bool ch_del)
{
- pim_forward_stop(ch);
- pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_NOINFO);
- if (ch_del)
- delete_on_noinfo(ch);
+ pim_forward_stop(ch);
+ pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_NOINFO);
+ if (ch_del)
+ delete_on_noinfo(ch);
}
static int on_ifjoin_expiry_timer(struct thread *t)
{
- struct pim_ifchannel *ch;
+ struct pim_ifchannel *ch;
- ch = THREAD_ARG(t);
+ ch = THREAD_ARG(t);
- ifjoin_to_noinfo(ch, true);
- /* ch may have been deleted */
+ ifjoin_to_noinfo(ch, true);
+ /* ch may have been deleted */
- return 0;
+ return 0;
}
static int on_ifjoin_prune_pending_timer(struct thread *t)
{
- struct pim_ifchannel *ch;
- int send_prune_echo; /* boolean */
- struct interface *ifp;
- struct pim_interface *pim_ifp;
-
- ch = THREAD_ARG(t);
-
- if (ch->ifjoin_state == PIM_IFJOIN_PRUNE_PENDING)
- {
- /* Send PruneEcho(S,G) ? */
- ifp = ch->interface;
- pim_ifp = ifp->info;
- send_prune_echo = (listcount(pim_ifp->pim_neighbor_list) > 1);
-
- if (send_prune_echo)
- {
- struct pim_rpf rpf;
-
- rpf.source_nexthop.interface = ifp;
- rpf.rpf_addr.u.prefix4 = pim_ifp->primary_address;
- pim_jp_agg_single_upstream_send(&rpf, ch->upstream, 0);
- }
- /* If SGRpt flag is set on ifchannel, Trigger SGRpt
- message on RP path upon prune timer expiry.
- */
- if (PIM_IF_FLAG_TEST_S_G_RPT (ch->flags))
- {
- if (ch->upstream)
- pim_upstream_update_join_desired(ch->upstream);
- /*
- ch->ifjoin_state transition to NOINFO state
- ch_del is set to 0 for not deleteing from here.
- Holdtime expiry (ch_del set to 1) delete the entry.
- */
- ifjoin_to_noinfo(ch, false);
- }
- else
- ifjoin_to_noinfo(ch, true);
- /* from here ch may have been deleted */
- }
- else
- {
- zlog_warn("%s: IFCHANNEL%s Prune Pending Timer Popped while in %s state",
- __PRETTY_FUNCTION__, pim_str_sg_dump (&ch->sg),
- pim_ifchannel_ifjoin_name (ch->ifjoin_state, ch->flags));
- }
-
- return 0;
+ struct pim_ifchannel *ch;
+ int send_prune_echo; /* boolean */
+ struct interface *ifp;
+ struct pim_interface *pim_ifp;
+
+ ch = THREAD_ARG(t);
+
+ if (ch->ifjoin_state == PIM_IFJOIN_PRUNE_PENDING) {
+ /* Send PruneEcho(S,G) ? */
+ ifp = ch->interface;
+ pim_ifp = ifp->info;
+ send_prune_echo = (listcount(pim_ifp->pim_neighbor_list) > 1);
+
+ if (send_prune_echo) {
+ struct pim_rpf rpf;
+
+ rpf.source_nexthop.interface = ifp;
+ rpf.rpf_addr.u.prefix4 = pim_ifp->primary_address;
+ pim_jp_agg_single_upstream_send(&rpf, ch->upstream, 0);
+ }
+ /* If SGRpt flag is set on ifchannel, Trigger SGRpt
+ message on RP path upon prune timer expiry.
+ */
+ if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags)) {
+ if (ch->upstream)
+ pim_upstream_update_join_desired(ch->upstream);
+ /*
+ ch->ifjoin_state transition to NOINFO state
+ ch_del is set to 0 for not deleteing from here.
+ Holdtime expiry (ch_del set to 1) delete the entry.
+ */
+ ifjoin_to_noinfo(ch, false);
+ } else
+ ifjoin_to_noinfo(ch, true);
+ /* from here ch may have been deleted */
+ } else {
+ zlog_warn(
+ "%s: IFCHANNEL%s Prune Pending Timer Popped while in %s state",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(&ch->sg),
+ pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags));
+ }
+
+ return 0;
}
-static void check_recv_upstream(int is_join,
- struct interface *recv_ifp,
- struct in_addr upstream,
- struct prefix_sg *sg,
- uint8_t source_flags,
- int holdtime)
+static void check_recv_upstream(int is_join, struct interface *recv_ifp,
+ struct in_addr upstream, struct prefix_sg *sg,
+ uint8_t source_flags, int holdtime)
{
- struct pim_upstream *up;
-
- /* Upstream (S,G) in Joined state ? */
- up = pim_upstream_find(sg);
- if (!up)
- return;
- if (up->join_state != PIM_UPSTREAM_JOINED)
- return;
-
- /* Upstream (S,G) in Joined state */
-
- if (pim_rpf_addr_is_inaddr_any(&up->rpf)) {
- /* RPF'(S,G) not found */
- zlog_warn("%s %s: RPF'%s not found",
- __FILE__, __PRETTY_FUNCTION__,
- up->sg_str);
- return;
- }
-
- /* upstream directed to RPF'(S,G) ? */
- if (upstream.s_addr != up->rpf.rpf_addr.u.prefix4.s_addr) {
- char up_str[INET_ADDRSTRLEN];
- char rpf_str[PREFIX_STRLEN];
- pim_inet4_dump("<up?>", upstream, up_str, sizeof(up_str));
- pim_addr_dump("<rpf?>", &up->rpf.rpf_addr, rpf_str, sizeof(rpf_str));
- zlog_warn("%s %s: (S,G)=%s upstream=%s not directed to RPF'(S,G)=%s on interface %s",
- __FILE__, __PRETTY_FUNCTION__,
- up->sg_str,
- up_str, rpf_str, recv_ifp->name);
- return;
- }
- /* upstream directed to RPF'(S,G) */
-
- if (is_join) {
- /* Join(S,G) to RPF'(S,G) */
- pim_upstream_join_suppress(up, up->rpf.rpf_addr.u.prefix4, holdtime);
- return;
- }
-
- /* Prune to RPF'(S,G) */
-
- if (source_flags & PIM_RPT_BIT_MASK) {
- if (source_flags & PIM_WILDCARD_BIT_MASK) {
- /* Prune(*,G) to RPF'(S,G) */
- pim_upstream_join_timer_decrease_to_t_override("Prune(*,G)", up);
- return;
- }
-
- /* Prune(S,G,rpt) to RPF'(S,G) */
- pim_upstream_join_timer_decrease_to_t_override("Prune(S,G,rpt)", up);
- return;
- }
-
- /* Prune(S,G) to RPF'(S,G) */
- pim_upstream_join_timer_decrease_to_t_override("Prune(S,G)", up);
+ struct pim_upstream *up;
+
+ /* Upstream (S,G) in Joined state ? */
+ up = pim_upstream_find(sg);
+ if (!up)
+ return;
+ if (up->join_state != PIM_UPSTREAM_JOINED)
+ return;
+
+ /* Upstream (S,G) in Joined state */
+
+ if (pim_rpf_addr_is_inaddr_any(&up->rpf)) {
+ /* RPF'(S,G) not found */
+ zlog_warn("%s %s: RPF'%s not found", __FILE__,
+ __PRETTY_FUNCTION__, up->sg_str);
+ return;
+ }
+
+ /* upstream directed to RPF'(S,G) ? */
+ if (upstream.s_addr != up->rpf.rpf_addr.u.prefix4.s_addr) {
+ char up_str[INET_ADDRSTRLEN];
+ char rpf_str[PREFIX_STRLEN];
+ pim_inet4_dump("<up?>", upstream, up_str, sizeof(up_str));
+ pim_addr_dump("<rpf?>", &up->rpf.rpf_addr, rpf_str,
+ sizeof(rpf_str));
+ zlog_warn(
+ "%s %s: (S,G)=%s upstream=%s not directed to RPF'(S,G)=%s on interface %s",
+ __FILE__, __PRETTY_FUNCTION__, up->sg_str, up_str,
+ rpf_str, recv_ifp->name);
+ return;
+ }
+ /* upstream directed to RPF'(S,G) */
+
+ if (is_join) {
+ /* Join(S,G) to RPF'(S,G) */
+ pim_upstream_join_suppress(up, up->rpf.rpf_addr.u.prefix4,
+ holdtime);
+ return;
+ }
+
+ /* Prune to RPF'(S,G) */
+
+ if (source_flags & PIM_RPT_BIT_MASK) {
+ if (source_flags & PIM_WILDCARD_BIT_MASK) {
+ /* Prune(*,G) to RPF'(S,G) */
+ pim_upstream_join_timer_decrease_to_t_override(
+ "Prune(*,G)", up);
+ return;
+ }
+
+ /* Prune(S,G,rpt) to RPF'(S,G) */
+ pim_upstream_join_timer_decrease_to_t_override("Prune(S,G,rpt)",
+ up);
+ return;
+ }
+
+ /* Prune(S,G) to RPF'(S,G) */
+ pim_upstream_join_timer_decrease_to_t_override("Prune(S,G)", up);
}
-static int
-nonlocal_upstream(int is_join,
- struct interface *recv_ifp,
- struct in_addr upstream,
- struct prefix_sg *sg,
- uint8_t source_flags,
- uint16_t holdtime)
+static int nonlocal_upstream(int is_join, struct interface *recv_ifp,
+ struct in_addr upstream, struct prefix_sg *sg,
+ uint8_t source_flags, uint16_t holdtime)
{
- struct pim_interface *recv_pim_ifp;
- int is_local; /* boolean */
-
- recv_pim_ifp = recv_ifp->info;
- zassert(recv_pim_ifp);
-
- is_local = (upstream.s_addr == recv_pim_ifp->primary_address.s_addr);
-
- if (is_local)
- return 0;
-
- if (PIM_DEBUG_PIM_TRACE_DETAIL) {
- char up_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<upstream?>", upstream, up_str, sizeof(up_str));
- zlog_warn("%s: recv %s (S,G)=%s to non-local upstream=%s on %s",
- __PRETTY_FUNCTION__,
- is_join ? "join" : "prune",
- pim_str_sg_dump (sg),
- up_str, recv_ifp->name);
- }
-
- /*
- * Since recv upstream addr was not directed to our primary
- * address, check if we should react to it in any way.
- */
- check_recv_upstream(is_join, recv_ifp, upstream, sg,
- source_flags, holdtime);
-
- return 1; /* non-local */
+ struct pim_interface *recv_pim_ifp;
+ int is_local; /* boolean */
+
+ recv_pim_ifp = recv_ifp->info;
+ zassert(recv_pim_ifp);
+
+ is_local = (upstream.s_addr == recv_pim_ifp->primary_address.s_addr);
+
+ if (is_local)
+ return 0;
+
+ if (PIM_DEBUG_PIM_TRACE_DETAIL) {
+ char up_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<upstream?>", upstream, up_str, sizeof(up_str));
+ zlog_warn("%s: recv %s (S,G)=%s to non-local upstream=%s on %s",
+ __PRETTY_FUNCTION__, is_join ? "join" : "prune",
+ pim_str_sg_dump(sg), up_str, recv_ifp->name);
+ }
+
+ /*
+ * Since recv upstream addr was not directed to our primary
+ * address, check if we should react to it in any way.
+ */
+ check_recv_upstream(is_join, recv_ifp, upstream, sg, source_flags,
+ holdtime);
+
+ return 1; /* non-local */
}
-void pim_ifchannel_join_add(struct interface *ifp,
- struct in_addr neigh_addr,
- struct in_addr upstream,
- struct prefix_sg *sg,
- uint8_t source_flags,
- uint16_t holdtime)
+void pim_ifchannel_join_add(struct interface *ifp, struct in_addr neigh_addr,
+ struct in_addr upstream, struct prefix_sg *sg,
+ uint8_t source_flags, uint16_t holdtime)
{
- struct pim_interface *pim_ifp;
- struct pim_ifchannel *ch;
-
- if (nonlocal_upstream(1 /* join */, ifp, upstream,
- sg, source_flags, holdtime)) {
- return;
- }
-
- ch = pim_ifchannel_add(ifp, sg, PIM_UPSTREAM_FLAG_MASK_SRC_PIM);
- if (!ch)
- return;
-
- /*
- RFC 4601: 4.6.1. (S,G) Assert Message State Machine
-
- Transitions from "I am Assert Loser" State
-
- Receive Join(S,G) on Interface I
-
- We receive a Join(S,G) that has the Upstream Neighbor Address
- field set to my primary IP address on interface I. The action is
- to transition to NoInfo state, delete this (S,G) assert state
- (Actions A5 below), and allow the normal PIM Join/Prune mechanisms
- to operate.
-
- Notice: The nonlocal_upstream() test above ensures the upstream
- address of the join message is our primary address.
- */
- if (ch->ifassert_state == PIM_IFASSERT_I_AM_LOSER) {
- char neigh_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<neigh?>", neigh_addr, neigh_str, sizeof(neigh_str));
- zlog_warn("%s: Assert Loser recv Join%s from %s on %s",
- __PRETTY_FUNCTION__,
- ch->sg_str, neigh_str, ifp->name);
-
- assert_action_a5(ch);
- }
-
- pim_ifp = ifp->info;
- zassert(pim_ifp);
-
- switch (ch->ifjoin_state) {
- case PIM_IFJOIN_NOINFO:
- pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_JOIN);
- if (pim_macro_chisin_oiflist(ch)) {
- pim_upstream_inherited_olist (ch->upstream);
- pim_forward_start(ch);
- }
- /*
- * If we are going to be a LHR, we need to note it
- */
- if (ch->upstream->parent &&
- (ch->upstream->parent->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP) &&
- !(ch->upstream->flags & PIM_UPSTREAM_FLAG_MASK_SRC_LHR))
- {
- pim_upstream_ref (ch->upstream, PIM_UPSTREAM_FLAG_MASK_SRC_LHR, __PRETTY_FUNCTION__);
- pim_upstream_keep_alive_timer_start (ch->upstream, qpim_keep_alive_time);
- }
- break;
- case PIM_IFJOIN_JOIN:
- zassert(!ch->t_ifjoin_prune_pending_timer);
-
- /*
- In the JOIN state ch->t_ifjoin_expiry_timer may be NULL due to a
- previously received join message with holdtime=0xFFFF.
- */
- if (ch->t_ifjoin_expiry_timer) {
- unsigned long remain =
- thread_timer_remain_second(ch->t_ifjoin_expiry_timer);
- if (remain > holdtime) {
+ struct pim_interface *pim_ifp;
+ struct pim_ifchannel *ch;
+
+ if (nonlocal_upstream(1 /* join */, ifp, upstream, sg, source_flags,
+ holdtime)) {
+ return;
+ }
+
+ ch = pim_ifchannel_add(ifp, sg, PIM_UPSTREAM_FLAG_MASK_SRC_PIM);
+ if (!ch)
+ return;
+
/*
- RFC 4601: 4.5.3. Receiving (S,G) Join/Prune Messages
+ RFC 4601: 4.6.1. (S,G) Assert Message State Machine
+
+ Transitions from "I am Assert Loser" State
- Transitions from Join State
+ Receive Join(S,G) on Interface I
- The (S,G) downstream state machine on interface I remains in
- Join state, and the Expiry Timer (ET) is restarted, set to
- maximum of its current value and the HoldTime from the
- triggering Join/Prune message.
+ We receive a Join(S,G) that has the Upstream Neighbor Address
+ field set to my primary IP address on interface I. The action is
+ to transition to NoInfo state, delete this (S,G) assert state
+ (Actions A5 below), and allow the normal PIM Join/Prune mechanisms
+ to operate.
- Conclusion: Do not change the ET if the current value is
- higher than the received join holdtime.
+ Notice: The nonlocal_upstream() test above ensures the upstream
+ address of the join message is our primary address.
*/
- return;
- }
- }
- THREAD_OFF(ch->t_ifjoin_expiry_timer);
- break;
- case PIM_IFJOIN_PRUNE:
- if (source_flags & PIM_ENCODE_RPT_BIT)
- pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_NOINFO);
- break;
- case PIM_IFJOIN_PRUNE_PENDING:
- THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
- if (source_flags & PIM_ENCODE_RPT_BIT)
- {
- THREAD_OFF(ch->t_ifjoin_expiry_timer);
- pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_NOINFO);
- }
- else
- pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_JOIN);
- break;
- case PIM_IFJOIN_PRUNE_TMP:
- break;
- case PIM_IFJOIN_PRUNE_PENDING_TMP:
- break;
- }
-
- if (holdtime != 0xFFFF) {
- thread_add_timer(master, on_ifjoin_expiry_timer, ch, holdtime,
- &ch->t_ifjoin_expiry_timer);
- }
+ if (ch->ifassert_state == PIM_IFASSERT_I_AM_LOSER) {
+ char neigh_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<neigh?>", neigh_addr, neigh_str,
+ sizeof(neigh_str));
+ zlog_warn("%s: Assert Loser recv Join%s from %s on %s",
+ __PRETTY_FUNCTION__, ch->sg_str, neigh_str,
+ ifp->name);
+
+ assert_action_a5(ch);
+ }
+
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+
+ switch (ch->ifjoin_state) {
+ case PIM_IFJOIN_NOINFO:
+ pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch,
+ PIM_IFJOIN_JOIN);
+ if (pim_macro_chisin_oiflist(ch)) {
+ pim_upstream_inherited_olist(ch->upstream);
+ pim_forward_start(ch);
+ }
+ /*
+ * If we are going to be a LHR, we need to note it
+ */
+ if (ch->upstream->parent && (ch->upstream->parent->flags
+ & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
+ && !(ch->upstream->flags
+ & PIM_UPSTREAM_FLAG_MASK_SRC_LHR)) {
+ pim_upstream_ref(ch->upstream,
+ PIM_UPSTREAM_FLAG_MASK_SRC_LHR,
+ __PRETTY_FUNCTION__);
+ pim_upstream_keep_alive_timer_start(
+ ch->upstream, qpim_keep_alive_time);
+ }
+ break;
+ case PIM_IFJOIN_JOIN:
+ zassert(!ch->t_ifjoin_prune_pending_timer);
+
+ /*
+ In the JOIN state ch->t_ifjoin_expiry_timer may be NULL due to
+ a
+ previously received join message with holdtime=0xFFFF.
+ */
+ if (ch->t_ifjoin_expiry_timer) {
+ unsigned long remain = thread_timer_remain_second(
+ ch->t_ifjoin_expiry_timer);
+ if (remain > holdtime) {
+ /*
+ RFC 4601: 4.5.3. Receiving (S,G) Join/Prune
+ Messages
+
+ Transitions from Join State
+
+ The (S,G) downstream state machine on
+ interface I remains in
+ Join state, and the Expiry Timer (ET) is
+ restarted, set to
+ maximum of its current value and the HoldTime
+ from the
+ triggering Join/Prune message.
+
+ Conclusion: Do not change the ET if the
+ current value is
+ higher than the received join holdtime.
+ */
+ return;
+ }
+ }
+ THREAD_OFF(ch->t_ifjoin_expiry_timer);
+ break;
+ case PIM_IFJOIN_PRUNE:
+ if (source_flags & PIM_ENCODE_RPT_BIT)
+ pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch,
+ PIM_IFJOIN_NOINFO);
+ break;
+ case PIM_IFJOIN_PRUNE_PENDING:
+ THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
+ if (source_flags & PIM_ENCODE_RPT_BIT) {
+ THREAD_OFF(ch->t_ifjoin_expiry_timer);
+ pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch,
+ PIM_IFJOIN_NOINFO);
+ } else
+ pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch,
+ PIM_IFJOIN_JOIN);
+ break;
+ case PIM_IFJOIN_PRUNE_TMP:
+ break;
+ case PIM_IFJOIN_PRUNE_PENDING_TMP:
+ break;
+ }
+
+ if (holdtime != 0xFFFF) {
+ thread_add_timer(master, on_ifjoin_expiry_timer, ch, holdtime,
+ &ch->t_ifjoin_expiry_timer);
+ }
}
-void pim_ifchannel_prune(struct interface *ifp,
- struct in_addr upstream,
- struct prefix_sg *sg,
- uint8_t source_flags,
+void pim_ifchannel_prune(struct interface *ifp, struct in_addr upstream,
+ struct prefix_sg *sg, uint8_t source_flags,
uint16_t holdtime)
{
- struct pim_ifchannel *ch;
- struct pim_interface *pim_ifp;
- int jp_override_interval_msec;
-
- if (nonlocal_upstream(0 /* prune */, ifp, upstream,
- sg, source_flags, holdtime)) {
- return;
- }
-
- ch = pim_ifchannel_find (ifp, sg);
- if (!ch && !(source_flags & PIM_ENCODE_RPT_BIT))
- {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: Received prune with no relevant ifchannel %s(%s) state: %d",
- __PRETTY_FUNCTION__, ifp->name, pim_str_sg_dump (sg), source_flags);
- return;
- }
-
- ch = pim_ifchannel_add(ifp, sg, PIM_UPSTREAM_FLAG_MASK_SRC_PIM);
- if (!ch)
- return;
-
- pim_ifp = ifp->info;
-
- switch (ch->ifjoin_state) {
- case PIM_IFJOIN_NOINFO:
- if (source_flags & PIM_ENCODE_RPT_BIT)
- {
- if (!(source_flags & PIM_ENCODE_WC_BIT))
- PIM_IF_FLAG_SET_S_G_RPT(ch->flags);
-
- ch->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING;
- if (listcount(pim_ifp->pim_neighbor_list) > 1)
- jp_override_interval_msec = pim_if_jp_override_interval_msec(ifp);
- else
- jp_override_interval_msec = 0; /* schedule to expire immediately */
- /* If we called ifjoin_prune() directly instead, care should
- be taken not to use "ch" afterwards since it would be
- deleted. */
+ struct pim_ifchannel *ch;
+ struct pim_interface *pim_ifp;
+ int jp_override_interval_msec;
- THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
- THREAD_OFF(ch->t_ifjoin_expiry_timer);
- thread_add_timer_msec(master, on_ifjoin_prune_pending_timer, ch,
- jp_override_interval_msec,
- &ch->t_ifjoin_prune_pending_timer);
- thread_add_timer(master, on_ifjoin_expiry_timer, ch, holdtime,
- &ch->t_ifjoin_expiry_timer);
- pim_upstream_update_join_desired(ch->upstream);
- }
- break;
- case PIM_IFJOIN_PRUNE_PENDING:
- /* nothing to do */
- break;
- case PIM_IFJOIN_JOIN:
- THREAD_OFF(ch->t_ifjoin_expiry_timer);
-
- pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_PRUNE_PENDING);
-
- if (listcount(pim_ifp->pim_neighbor_list) > 1)
- jp_override_interval_msec = pim_if_jp_override_interval_msec(ifp);
- else
- jp_override_interval_msec = 0; /* schedule to expire immediately */
- /* If we called ifjoin_prune() directly instead, care should
- be taken not to use "ch" afterwards since it would be
- deleted. */
- THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
- thread_add_timer_msec(master, on_ifjoin_prune_pending_timer, ch,
- jp_override_interval_msec,
- &ch->t_ifjoin_prune_pending_timer);
- break;
- case PIM_IFJOIN_PRUNE:
- if (source_flags & PIM_ENCODE_RPT_BIT)
- {
- THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
- thread_add_timer(master, on_ifjoin_expiry_timer, ch, holdtime,
- &ch->t_ifjoin_expiry_timer);
- }
- break;
- case PIM_IFJOIN_PRUNE_TMP:
- if (source_flags & PIM_ENCODE_RPT_BIT)
- {
- ch->ifjoin_state = PIM_IFJOIN_PRUNE;
- THREAD_OFF(ch->t_ifjoin_expiry_timer);
- thread_add_timer(master, on_ifjoin_expiry_timer, ch, holdtime,
- &ch->t_ifjoin_expiry_timer);
- }
- break;
- case PIM_IFJOIN_PRUNE_PENDING_TMP:
- if (source_flags & PIM_ENCODE_RPT_BIT)
- {
- ch->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING;
- THREAD_OFF(ch->t_ifjoin_expiry_timer);
- thread_add_timer(master, on_ifjoin_expiry_timer, ch, holdtime,
- &ch->t_ifjoin_expiry_timer);
- }
- break;
- }
+ if (nonlocal_upstream(0 /* prune */, ifp, upstream, sg, source_flags,
+ holdtime)) {
+ return;
+ }
+
+ ch = pim_ifchannel_find(ifp, sg);
+ if (!ch && !(source_flags & PIM_ENCODE_RPT_BIT)) {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug(
+ "%s: Received prune with no relevant ifchannel %s(%s) state: %d",
+ __PRETTY_FUNCTION__, ifp->name,
+ pim_str_sg_dump(sg), source_flags);
+ return;
+ }
+
+ ch = pim_ifchannel_add(ifp, sg, PIM_UPSTREAM_FLAG_MASK_SRC_PIM);
+ if (!ch)
+ return;
+
+ pim_ifp = ifp->info;
+
+ switch (ch->ifjoin_state) {
+ case PIM_IFJOIN_NOINFO:
+ if (source_flags & PIM_ENCODE_RPT_BIT) {
+ if (!(source_flags & PIM_ENCODE_WC_BIT))
+ PIM_IF_FLAG_SET_S_G_RPT(ch->flags);
+
+ ch->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING;
+ if (listcount(pim_ifp->pim_neighbor_list) > 1)
+ jp_override_interval_msec =
+ pim_if_jp_override_interval_msec(ifp);
+ else
+ jp_override_interval_msec =
+ 0; /* schedule to expire immediately */
+ /* If we called ifjoin_prune() directly instead, care
+ should
+ be taken not to use "ch" afterwards since it would be
+ deleted. */
+
+ THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
+ THREAD_OFF(ch->t_ifjoin_expiry_timer);
+ thread_add_timer_msec(
+ master, on_ifjoin_prune_pending_timer, ch,
+ jp_override_interval_msec,
+ &ch->t_ifjoin_prune_pending_timer);
+ thread_add_timer(master, on_ifjoin_expiry_timer, ch,
+ holdtime, &ch->t_ifjoin_expiry_timer);
+ pim_upstream_update_join_desired(ch->upstream);
+ }
+ break;
+ case PIM_IFJOIN_PRUNE_PENDING:
+ /* nothing to do */
+ break;
+ case PIM_IFJOIN_JOIN:
+ THREAD_OFF(ch->t_ifjoin_expiry_timer);
+
+ pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch,
+ PIM_IFJOIN_PRUNE_PENDING);
+
+ if (listcount(pim_ifp->pim_neighbor_list) > 1)
+ jp_override_interval_msec =
+ pim_if_jp_override_interval_msec(ifp);
+ else
+ jp_override_interval_msec =
+ 0; /* schedule to expire immediately */
+ /* If we called ifjoin_prune() directly instead, care should
+ be taken not to use "ch" afterwards since it would be
+ deleted. */
+ THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
+ thread_add_timer_msec(master, on_ifjoin_prune_pending_timer, ch,
+ jp_override_interval_msec,
+ &ch->t_ifjoin_prune_pending_timer);
+ break;
+ case PIM_IFJOIN_PRUNE:
+ if (source_flags & PIM_ENCODE_RPT_BIT) {
+ THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
+ thread_add_timer(master, on_ifjoin_expiry_timer, ch,
+ holdtime, &ch->t_ifjoin_expiry_timer);
+ }
+ break;
+ case PIM_IFJOIN_PRUNE_TMP:
+ if (source_flags & PIM_ENCODE_RPT_BIT) {
+ ch->ifjoin_state = PIM_IFJOIN_PRUNE;
+ THREAD_OFF(ch->t_ifjoin_expiry_timer);
+ thread_add_timer(master, on_ifjoin_expiry_timer, ch,
+ holdtime, &ch->t_ifjoin_expiry_timer);
+ }
+ break;
+ case PIM_IFJOIN_PRUNE_PENDING_TMP:
+ if (source_flags & PIM_ENCODE_RPT_BIT) {
+ ch->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING;
+ THREAD_OFF(ch->t_ifjoin_expiry_timer);
+ thread_add_timer(master, on_ifjoin_expiry_timer, ch,
+ holdtime, &ch->t_ifjoin_expiry_timer);
+ }
+ break;
+ }
}
-int
-pim_ifchannel_local_membership_add(struct interface *ifp,
- struct prefix_sg *sg)
+int pim_ifchannel_local_membership_add(struct interface *ifp,
+ struct prefix_sg *sg)
{
- struct pim_ifchannel *ch, *starch;
- struct pim_interface *pim_ifp;
-
- /* PIM enabled on interface? */
- pim_ifp = ifp->info;
- if (!pim_ifp)
- return 0;
- if (!PIM_IF_TEST_PIM(pim_ifp->options))
- return 0;
-
- /* skip (*,G) ch creation if G is of type SSM */
- if (sg->src.s_addr == INADDR_ANY)
- {
- if (pim_is_grp_ssm (sg->grp))
- {
- if (PIM_DEBUG_PIM_EVENTS)
- zlog_debug("%s: local membership (S,G)=%s ignored as group is SSM",
- __PRETTY_FUNCTION__, pim_str_sg_dump (sg));
- return 1;
- }
- }
-
- ch = pim_ifchannel_add(ifp, sg, PIM_UPSTREAM_FLAG_MASK_SRC_IGMP);
- if (!ch) {
- return 0;
- }
-
- ifmembership_set(ch, PIM_IFMEMBERSHIP_INCLUDE);
-
- if (sg->src.s_addr == INADDR_ANY)
- {
- struct pim_upstream *up = pim_upstream_find (sg);
- struct pim_upstream *child;
- struct listnode *up_node;
-
- starch = ch;
-
- for (ALL_LIST_ELEMENTS_RO (up->sources, up_node, child))
- {
- if (PIM_DEBUG_EVENTS)
- zlog_debug("%s %s: IGMP (S,G)=%s(%s) from %s",
- __FILE__, __PRETTY_FUNCTION__,
- child->sg_str, ifp->name, up->sg_str);
-
- ch = pim_ifchannel_find (ifp, &child->sg);
- if (pim_upstream_evaluate_join_desired_interface (child, ch, starch))
- {
- pim_channel_add_oif (child->channel_oil, ifp, PIM_OIF_FLAG_PROTO_STAR);
- pim_upstream_switch (child, PIM_UPSTREAM_JOINED);
- }
- }
-
- if (pimg->spt.switchover == PIM_SPT_INFINITY)
- {
- if (pimg->spt.plist)
- {
- struct prefix_list *plist = prefix_list_lookup (AFI_IP, pimg->spt.plist);
- struct prefix g;
- g.family = AF_INET;
- g.prefixlen = IPV4_MAX_PREFIXLEN;
- g.u.prefix4 = up->sg.grp;
-
- if (prefix_list_apply (plist, &g) == PREFIX_DENY)
- {
- pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP);
- }
- }
- }
- else
- pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP);
- }
-
- return 1;
+ struct pim_ifchannel *ch, *starch;
+ struct pim_interface *pim_ifp;
+
+ /* PIM enabled on interface? */
+ pim_ifp = ifp->info;
+ if (!pim_ifp)
+ return 0;
+ if (!PIM_IF_TEST_PIM(pim_ifp->options))
+ return 0;
+
+ /* skip (*,G) ch creation if G is of type SSM */
+ if (sg->src.s_addr == INADDR_ANY) {
+ if (pim_is_grp_ssm(sg->grp)) {
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_debug(
+ "%s: local membership (S,G)=%s ignored as group is SSM",
+ __PRETTY_FUNCTION__,
+ pim_str_sg_dump(sg));
+ return 1;
+ }
+ }
+
+ ch = pim_ifchannel_add(ifp, sg, PIM_UPSTREAM_FLAG_MASK_SRC_IGMP);
+ if (!ch) {
+ return 0;
+ }
+
+ ifmembership_set(ch, PIM_IFMEMBERSHIP_INCLUDE);
+
+ if (sg->src.s_addr == INADDR_ANY) {
+ struct pim_upstream *up = pim_upstream_find(sg);
+ struct pim_upstream *child;
+ struct listnode *up_node;
+
+ starch = ch;
+
+ for (ALL_LIST_ELEMENTS_RO(up->sources, up_node, child)) {
+ if (PIM_DEBUG_EVENTS)
+ zlog_debug("%s %s: IGMP (S,G)=%s(%s) from %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ child->sg_str, ifp->name,
+ up->sg_str);
+
+ ch = pim_ifchannel_find(ifp, &child->sg);
+ if (pim_upstream_evaluate_join_desired_interface(
+ child, ch, starch)) {
+ pim_channel_add_oif(child->channel_oil, ifp,
+ PIM_OIF_FLAG_PROTO_STAR);
+ pim_upstream_switch(child, PIM_UPSTREAM_JOINED);
+ }
+ }
+
+ if (pimg->spt.switchover == PIM_SPT_INFINITY) {
+ if (pimg->spt.plist) {
+ struct prefix_list *plist = prefix_list_lookup(
+ AFI_IP, pimg->spt.plist);
+ struct prefix g;
+ g.family = AF_INET;
+ g.prefixlen = IPV4_MAX_PREFIXLEN;
+ g.u.prefix4 = up->sg.grp;
+
+ if (prefix_list_apply(plist, &g)
+ == PREFIX_DENY) {
+ pim_channel_add_oif(
+ up->channel_oil, pim_regiface,
+ PIM_OIF_FLAG_PROTO_IGMP);
+ }
+ }
+ } else
+ pim_channel_add_oif(up->channel_oil, pim_regiface,
+ PIM_OIF_FLAG_PROTO_IGMP);
+ }
+
+ return 1;
}
void pim_ifchannel_local_membership_del(struct interface *ifp,
struct prefix_sg *sg)
{
- struct pim_ifchannel *starch, *ch, *orig;
- struct pim_interface *pim_ifp;
-
- /* PIM enabled on interface? */
- pim_ifp = ifp->info;
- if (!pim_ifp)
- return;
- if (!PIM_IF_TEST_PIM(pim_ifp->options))
- return;
-
- orig = ch = pim_ifchannel_find(ifp, sg);
- if (!ch)
- return;
-
- ifmembership_set(ch, PIM_IFMEMBERSHIP_NOINFO);
-
- if (sg->src.s_addr == INADDR_ANY)
- {
- struct pim_upstream *up = pim_upstream_find (sg);
- struct pim_upstream *child;
- struct listnode *up_node, *up_nnode;
-
- starch = ch;
-
- for (ALL_LIST_ELEMENTS (up->sources, up_node, up_nnode, child))
- {
- struct channel_oil *c_oil = child->channel_oil;
- struct pim_ifchannel *chchannel = pim_ifchannel_find (ifp, &child->sg);
- struct pim_interface *pim_ifp = ifp->info;
-
- if (PIM_DEBUG_EVENTS)
- zlog_debug("%s %s: Prune(S,G)=%s(%s) from %s",
- __FILE__, __PRETTY_FUNCTION__,
- up->sg_str, ifp->name, child->sg_str);
-
- ch = pim_ifchannel_find (ifp, &child->sg);
- if (c_oil && !pim_upstream_evaluate_join_desired_interface (child, ch, starch))
- pim_channel_del_oif (c_oil, ifp, PIM_OIF_FLAG_PROTO_STAR);
-
- /*
- * If the S,G has no if channel and the c_oil still
- * has output here then the *,G was supplying the implied
- * if channel. So remove it.
- */
- if (!chchannel && c_oil && c_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index])
- pim_channel_del_oif (c_oil, ifp, PIM_OIF_FLAG_PROTO_STAR);
-
- /* Child node removal/ref count-- will happen as part of parent' delete_no_info */
- }
- }
- delete_on_noinfo(orig);
+ struct pim_ifchannel *starch, *ch, *orig;
+ struct pim_interface *pim_ifp;
+
+ /* PIM enabled on interface? */
+ pim_ifp = ifp->info;
+ if (!pim_ifp)
+ return;
+ if (!PIM_IF_TEST_PIM(pim_ifp->options))
+ return;
+
+ orig = ch = pim_ifchannel_find(ifp, sg);
+ if (!ch)
+ return;
+
+ ifmembership_set(ch, PIM_IFMEMBERSHIP_NOINFO);
+
+ if (sg->src.s_addr == INADDR_ANY) {
+ struct pim_upstream *up = pim_upstream_find(sg);
+ struct pim_upstream *child;
+ struct listnode *up_node, *up_nnode;
+
+ starch = ch;
+
+ for (ALL_LIST_ELEMENTS(up->sources, up_node, up_nnode, child)) {
+ struct channel_oil *c_oil = child->channel_oil;
+ struct pim_ifchannel *chchannel =
+ pim_ifchannel_find(ifp, &child->sg);
+ struct pim_interface *pim_ifp = ifp->info;
+
+ if (PIM_DEBUG_EVENTS)
+ zlog_debug("%s %s: Prune(S,G)=%s(%s) from %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ up->sg_str, ifp->name,
+ child->sg_str);
+
+ ch = pim_ifchannel_find(ifp, &child->sg);
+ if (c_oil
+ && !pim_upstream_evaluate_join_desired_interface(
+ child, ch, starch))
+ pim_channel_del_oif(c_oil, ifp,
+ PIM_OIF_FLAG_PROTO_STAR);
+
+ /*
+ * If the S,G has no if channel and the c_oil still
+ * has output here then the *,G was supplying the
+ * implied
+ * if channel. So remove it.
+ */
+ if (!chchannel && c_oil
+ && c_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index])
+ pim_channel_del_oif(c_oil, ifp,
+ PIM_OIF_FLAG_PROTO_STAR);
+
+ /* Child node removal/ref count-- will happen as part of
+ * parent' delete_no_info */
+ }
+ }
+ delete_on_noinfo(orig);
}
void pim_ifchannel_update_could_assert(struct pim_ifchannel *ch)
{
- int old_couldassert = PIM_FORCE_BOOLEAN(PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags));
- int new_couldassert = PIM_FORCE_BOOLEAN(pim_macro_ch_could_assert_eval(ch));
-
- if (new_couldassert == old_couldassert)
- return;
-
- if (PIM_DEBUG_PIM_EVENTS) {
- char src_str[INET_ADDRSTRLEN];
- char grp_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", ch->sg.src, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->sg.grp, grp_str, sizeof(grp_str));
- zlog_debug("%s: CouldAssert(%s,%s,%s) changed from %d to %d",
- __PRETTY_FUNCTION__,
- src_str, grp_str, ch->interface->name,
- old_couldassert, new_couldassert);
- }
-
- if (new_couldassert) {
- /* CouldAssert(S,G,I) switched from FALSE to TRUE */
- PIM_IF_FLAG_SET_COULD_ASSERT(ch->flags);
- }
- else {
- /* CouldAssert(S,G,I) switched from TRUE to FALSE */
- PIM_IF_FLAG_UNSET_COULD_ASSERT(ch->flags);
-
- if (ch->ifassert_state == PIM_IFASSERT_I_AM_WINNER) {
- assert_action_a4(ch);
- }
- }
-
- pim_ifchannel_update_my_assert_metric(ch);
+ int old_couldassert =
+ PIM_FORCE_BOOLEAN(PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags));
+ int new_couldassert =
+ PIM_FORCE_BOOLEAN(pim_macro_ch_could_assert_eval(ch));
+
+ if (new_couldassert == old_couldassert)
+ return;
+
+ if (PIM_DEBUG_PIM_EVENTS) {
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", ch->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", ch->sg.grp, grp_str, sizeof(grp_str));
+ zlog_debug("%s: CouldAssert(%s,%s,%s) changed from %d to %d",
+ __PRETTY_FUNCTION__, src_str, grp_str,
+ ch->interface->name, old_couldassert,
+ new_couldassert);
+ }
+
+ if (new_couldassert) {
+ /* CouldAssert(S,G,I) switched from FALSE to TRUE */
+ PIM_IF_FLAG_SET_COULD_ASSERT(ch->flags);
+ } else {
+ /* CouldAssert(S,G,I) switched from TRUE to FALSE */
+ PIM_IF_FLAG_UNSET_COULD_ASSERT(ch->flags);
+
+ if (ch->ifassert_state == PIM_IFASSERT_I_AM_WINNER) {
+ assert_action_a4(ch);
+ }
+ }
+
+ pim_ifchannel_update_my_assert_metric(ch);
}
/*
@@ -1165,72 +1182,75 @@ void pim_ifchannel_update_could_assert(struct pim_ifchannel *ch)
*/
void pim_ifchannel_update_my_assert_metric(struct pim_ifchannel *ch)
{
- struct pim_assert_metric my_metric_new = pim_macro_ch_my_assert_metric_eval(ch);
-
- if (pim_assert_metric_match(&my_metric_new, &ch->ifassert_my_metric))
- return;
-
- if (PIM_DEBUG_PIM_EVENTS) {
- char src_str[INET_ADDRSTRLEN];
- char grp_str[INET_ADDRSTRLEN];
- char old_addr_str[INET_ADDRSTRLEN];
- char new_addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", ch->sg.src, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->sg.grp, grp_str, sizeof(grp_str));
- pim_inet4_dump("<old_addr?>", ch->ifassert_my_metric.ip_address, old_addr_str, sizeof(old_addr_str));
- pim_inet4_dump("<new_addr?>", my_metric_new.ip_address, new_addr_str, sizeof(new_addr_str));
- zlog_debug("%s: my_assert_metric(%s,%s,%s) changed from %u,%u,%u,%s to %u,%u,%u,%s",
- __PRETTY_FUNCTION__,
- src_str, grp_str, ch->interface->name,
- ch->ifassert_my_metric.rpt_bit_flag,
- ch->ifassert_my_metric.metric_preference,
- ch->ifassert_my_metric.route_metric,
- old_addr_str,
- my_metric_new.rpt_bit_flag,
- my_metric_new.metric_preference,
- my_metric_new.route_metric,
- new_addr_str);
- }
-
- ch->ifassert_my_metric = my_metric_new;
-
- if (pim_assert_metric_better(&ch->ifassert_my_metric,
- &ch->ifassert_winner_metric)) {
- assert_action_a5(ch);
- }
+ struct pim_assert_metric my_metric_new =
+ pim_macro_ch_my_assert_metric_eval(ch);
+
+ if (pim_assert_metric_match(&my_metric_new, &ch->ifassert_my_metric))
+ return;
+
+ if (PIM_DEBUG_PIM_EVENTS) {
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ char old_addr_str[INET_ADDRSTRLEN];
+ char new_addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", ch->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", ch->sg.grp, grp_str, sizeof(grp_str));
+ pim_inet4_dump("<old_addr?>", ch->ifassert_my_metric.ip_address,
+ old_addr_str, sizeof(old_addr_str));
+ pim_inet4_dump("<new_addr?>", my_metric_new.ip_address,
+ new_addr_str, sizeof(new_addr_str));
+ zlog_debug(
+ "%s: my_assert_metric(%s,%s,%s) changed from %u,%u,%u,%s to %u,%u,%u,%s",
+ __PRETTY_FUNCTION__, src_str, grp_str,
+ ch->interface->name,
+ ch->ifassert_my_metric.rpt_bit_flag,
+ ch->ifassert_my_metric.metric_preference,
+ ch->ifassert_my_metric.route_metric, old_addr_str,
+ my_metric_new.rpt_bit_flag,
+ my_metric_new.metric_preference,
+ my_metric_new.route_metric, new_addr_str);
+ }
+
+ ch->ifassert_my_metric = my_metric_new;
+
+ if (pim_assert_metric_better(&ch->ifassert_my_metric,
+ &ch->ifassert_winner_metric)) {
+ assert_action_a5(ch);
+ }
}
void pim_ifchannel_update_assert_tracking_desired(struct pim_ifchannel *ch)
{
- int old_atd = PIM_FORCE_BOOLEAN(PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags));
- int new_atd = PIM_FORCE_BOOLEAN(pim_macro_assert_tracking_desired_eval(ch));
-
- if (new_atd == old_atd)
- return;
-
- if (PIM_DEBUG_PIM_EVENTS) {
- char src_str[INET_ADDRSTRLEN];
- char grp_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", ch->sg.src, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ch->sg.grp, grp_str, sizeof(grp_str));
- zlog_debug("%s: AssertTrackingDesired(%s,%s,%s) changed from %d to %d",
- __PRETTY_FUNCTION__,
- src_str, grp_str, ch->interface->name,
- old_atd, new_atd);
- }
-
- if (new_atd) {
- /* AssertTrackingDesired(S,G,I) switched from FALSE to TRUE */
- PIM_IF_FLAG_SET_ASSERT_TRACKING_DESIRED(ch->flags);
- }
- else {
- /* AssertTrackingDesired(S,G,I) switched from TRUE to FALSE */
- PIM_IF_FLAG_UNSET_ASSERT_TRACKING_DESIRED(ch->flags);
-
- if (ch->ifassert_state == PIM_IFASSERT_I_AM_LOSER) {
- assert_action_a5(ch);
- }
- }
+ int old_atd = PIM_FORCE_BOOLEAN(
+ PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags));
+ int new_atd =
+ PIM_FORCE_BOOLEAN(pim_macro_assert_tracking_desired_eval(ch));
+
+ if (new_atd == old_atd)
+ return;
+
+ if (PIM_DEBUG_PIM_EVENTS) {
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", ch->sg.src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", ch->sg.grp, grp_str, sizeof(grp_str));
+ zlog_debug(
+ "%s: AssertTrackingDesired(%s,%s,%s) changed from %d to %d",
+ __PRETTY_FUNCTION__, src_str, grp_str,
+ ch->interface->name, old_atd, new_atd);
+ }
+
+ if (new_atd) {
+ /* AssertTrackingDesired(S,G,I) switched from FALSE to TRUE */
+ PIM_IF_FLAG_SET_ASSERT_TRACKING_DESIRED(ch->flags);
+ } else {
+ /* AssertTrackingDesired(S,G,I) switched from TRUE to FALSE */
+ PIM_IF_FLAG_UNSET_ASSERT_TRACKING_DESIRED(ch->flags);
+
+ if (ch->ifassert_state == PIM_IFASSERT_I_AM_LOSER) {
+ assert_action_a5(ch);
+ }
+ }
}
/*
@@ -1239,36 +1259,34 @@ void pim_ifchannel_update_assert_tracking_desired(struct pim_ifchannel *ch)
* their upstream out that way and turn on forwarding
* for that ifchannel then.
*/
-void
-pim_ifchannel_scan_forward_start (struct interface *new_ifp)
+void pim_ifchannel_scan_forward_start(struct interface *new_ifp)
{
- struct listnode *ifnode;
- struct interface *ifp;
- struct pim_interface *new_pim_ifp = new_ifp->info;
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp))
- {
- struct pim_interface *loop_pim_ifp = ifp->info;
- struct listnode *ch_node;
- struct pim_ifchannel *ch;
-
- if (!loop_pim_ifp)
- continue;
-
- if (new_pim_ifp == loop_pim_ifp)
- continue;
-
- for (ALL_LIST_ELEMENTS_RO (loop_pim_ifp->pim_ifchannel_list, ch_node, ch))
- {
- if (ch->ifjoin_state == PIM_IFJOIN_JOIN)
- {
- struct pim_upstream *up = ch->upstream;
- if ((!up->channel_oil) &&
- (up->rpf.source_nexthop.interface == new_ifp))
- pim_forward_start (ch);
- }
- }
- }
+ struct listnode *ifnode;
+ struct interface *ifp;
+ struct pim_interface *new_pim_ifp = new_ifp->info;
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), ifnode, ifp)) {
+ struct pim_interface *loop_pim_ifp = ifp->info;
+ struct listnode *ch_node;
+ struct pim_ifchannel *ch;
+
+ if (!loop_pim_ifp)
+ continue;
+
+ if (new_pim_ifp == loop_pim_ifp)
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(loop_pim_ifp->pim_ifchannel_list,
+ ch_node, ch)) {
+ if (ch->ifjoin_state == PIM_IFJOIN_JOIN) {
+ struct pim_upstream *up = ch->upstream;
+ if ((!up->channel_oil)
+ && (up->rpf.source_nexthop
+ .interface == new_ifp))
+ pim_forward_start(ch);
+ }
+ }
+ }
}
/*
@@ -1278,87 +1296,89 @@ pim_ifchannel_scan_forward_start (struct interface *new_ifp)
* reception of a *,G join as well, when
* we get End of Message
*/
-void
-pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom, uint8_t source_flags, uint8_t join, uint8_t starg_alone)
+void pim_ifchannel_set_star_g_join_state(struct pim_ifchannel *ch, int eom,
+ uint8_t source_flags, uint8_t join,
+ uint8_t starg_alone)
{
- struct pim_ifchannel *child;
- struct listnode *ch_node;
-
- if (PIM_DEBUG_PIM_TRACE)
- zlog_debug ("%s: %s %s eom: %d join %u", __PRETTY_FUNCTION__,
- pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags),
- ch->sg_str, eom, join);
- if (!ch->sources)
- return;
-
- for (ALL_LIST_ELEMENTS_RO (ch->sources, ch_node, child))
- {
- /* Only *,G Join received and no (SG-RPT) prune.
- eom = 1, only (W,G) join_alone is true, WC and RPT are set.
- Scan all S,G associated to G and if any SG-RPT
- remove the SG-RPT flag.
- */
- if (eom && starg_alone && (source_flags & PIM_RPT_BIT_MASK) &&
- (source_flags & PIM_WILDCARD_BIT_MASK))
- {
- if (PIM_IF_FLAG_TEST_S_G_RPT(child->flags))
- {
- struct pim_upstream *up = child->upstream;
-
- PIM_IF_FLAG_UNSET_S_G_RPT(child->flags);
- if (up)
- {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: SGRpt flag is cleared, add inherit oif to up %s",
- __PRETTY_FUNCTION__, up->sg_str);
- pim_channel_add_oif (up->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
- pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, child, PIM_IFJOIN_JOIN);
- }
- }
- }
-
- if (!PIM_IF_FLAG_TEST_S_G_RPT(child->flags))
- continue;
-
- switch (child->ifjoin_state)
- {
- case PIM_IFJOIN_NOINFO:
- case PIM_IFJOIN_JOIN:
- break;
- case PIM_IFJOIN_PRUNE:
- if (!eom)
- child->ifjoin_state = PIM_IFJOIN_PRUNE_TMP;
- break;
- case PIM_IFJOIN_PRUNE_PENDING:
- if (!eom)
- child->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING_TMP;
- break;
- case PIM_IFJOIN_PRUNE_TMP:
- case PIM_IFJOIN_PRUNE_PENDING_TMP:
- if (eom)
- child->ifjoin_state = PIM_IFJOIN_NOINFO;
- break;
+ struct pim_ifchannel *child;
+ struct listnode *ch_node;
+
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug(
+ "%s: %s %s eom: %d join %u", __PRETTY_FUNCTION__,
+ pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags),
+ ch->sg_str, eom, join);
+ if (!ch->sources)
+ return;
+
+ for (ALL_LIST_ELEMENTS_RO(ch->sources, ch_node, child)) {
+ /* Only *,G Join received and no (SG-RPT) prune.
+ eom = 1, only (W,G) join_alone is true, WC and RPT are set.
+ Scan all S,G associated to G and if any SG-RPT
+ remove the SG-RPT flag.
+ */
+ if (eom && starg_alone && (source_flags & PIM_RPT_BIT_MASK)
+ && (source_flags & PIM_WILDCARD_BIT_MASK)) {
+ if (PIM_IF_FLAG_TEST_S_G_RPT(child->flags)) {
+ struct pim_upstream *up = child->upstream;
+
+ PIM_IF_FLAG_UNSET_S_G_RPT(child->flags);
+ if (up) {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug(
+ "%s: SGRpt flag is cleared, add inherit oif to up %s",
+ __PRETTY_FUNCTION__,
+ up->sg_str);
+ pim_channel_add_oif(
+ up->channel_oil, ch->interface,
+ PIM_OIF_FLAG_PROTO_STAR);
+ pim_ifchannel_ifjoin_switch(
+ __PRETTY_FUNCTION__, child,
+ PIM_IFJOIN_JOIN);
+ }
+ }
+ }
+
+ if (!PIM_IF_FLAG_TEST_S_G_RPT(child->flags))
+ continue;
+
+ switch (child->ifjoin_state) {
+ case PIM_IFJOIN_NOINFO:
+ case PIM_IFJOIN_JOIN:
+ break;
+ case PIM_IFJOIN_PRUNE:
+ if (!eom)
+ child->ifjoin_state = PIM_IFJOIN_PRUNE_TMP;
+ break;
+ case PIM_IFJOIN_PRUNE_PENDING:
+ if (!eom)
+ child->ifjoin_state =
+ PIM_IFJOIN_PRUNE_PENDING_TMP;
+ break;
+ case PIM_IFJOIN_PRUNE_TMP:
+ case PIM_IFJOIN_PRUNE_PENDING_TMP:
+ if (eom)
+ child->ifjoin_state = PIM_IFJOIN_NOINFO;
+ break;
+ }
}
- }
}
-unsigned int
-pim_ifchannel_hash_key (void *arg)
+unsigned int pim_ifchannel_hash_key(void *arg)
{
- struct pim_ifchannel *ch = (struct pim_ifchannel *)arg;
+ struct pim_ifchannel *ch = (struct pim_ifchannel *)arg;
- return jhash_2words (ch->sg.src.s_addr, ch->sg.grp.s_addr, 0);
+ return jhash_2words(ch->sg.src.s_addr, ch->sg.grp.s_addr, 0);
}
-int
-pim_ifchannel_equal (const void *arg1, const void *arg2)
+int pim_ifchannel_equal(const void *arg1, const void *arg2)
{
- const struct pim_ifchannel *ch1 = (const struct pim_ifchannel *)arg1;
- const struct pim_ifchannel *ch2 = (const struct pim_ifchannel *)arg2;
+ const struct pim_ifchannel *ch1 = (const struct pim_ifchannel *)arg1;
+ const struct pim_ifchannel *ch2 = (const struct pim_ifchannel *)arg2;
- if ((ch1->sg.grp.s_addr == ch2->sg.grp.s_addr) &&
- (ch1->sg.src.s_addr == ch2->sg.src.s_addr))
- return 1;
+ if ((ch1->sg.grp.s_addr == ch2->sg.grp.s_addr)
+ && (ch1->sg.src.s_addr == ch2->sg.src.s_addr))
+ return 1;
- return 0;
+ return 0;
}
diff --git a/pimd/pim_ifchannel.h b/pimd/pim_ifchannel.h
index 455493a5b..2260fd451 100644
--- a/pimd/pim_ifchannel.h
+++ b/pimd/pim_ifchannel.h
@@ -28,31 +28,29 @@
struct pim_ifchannel;
#include "pim_upstream.h"
-enum pim_ifmembership {
- PIM_IFMEMBERSHIP_NOINFO,
- PIM_IFMEMBERSHIP_INCLUDE
-};
+enum pim_ifmembership { PIM_IFMEMBERSHIP_NOINFO, PIM_IFMEMBERSHIP_INCLUDE };
enum pim_ifjoin_state {
- PIM_IFJOIN_NOINFO,
- PIM_IFJOIN_JOIN,
- PIM_IFJOIN_PRUNE,
- PIM_IFJOIN_PRUNE_PENDING,
- PIM_IFJOIN_PRUNE_TMP,
- PIM_IFJOIN_PRUNE_PENDING_TMP,
+ PIM_IFJOIN_NOINFO,
+ PIM_IFJOIN_JOIN,
+ PIM_IFJOIN_PRUNE,
+ PIM_IFJOIN_PRUNE_PENDING,
+ PIM_IFJOIN_PRUNE_TMP,
+ PIM_IFJOIN_PRUNE_PENDING_TMP,
};
enum pim_ifassert_state {
- PIM_IFASSERT_NOINFO,
- PIM_IFASSERT_I_AM_WINNER,
- PIM_IFASSERT_I_AM_LOSER
+ PIM_IFASSERT_NOINFO,
+ PIM_IFASSERT_I_AM_WINNER,
+ PIM_IFASSERT_I_AM_LOSER
};
struct pim_assert_metric {
- uint32_t rpt_bit_flag;
- uint32_t metric_preference;
- uint32_t route_metric;
- struct in_addr ip_address; /* neighbor router that sourced the Assert message */
+ uint32_t rpt_bit_flag;
+ uint32_t metric_preference;
+ uint32_t route_metric;
+ struct in_addr ip_address; /* neighbor router that sourced the Assert
+ message */
};
/*
@@ -82,63 +80,58 @@ struct pim_assert_metric {
Per-interface (S,G) state
*/
struct pim_ifchannel {
- struct pim_ifchannel *parent;
- struct list *sources;
- struct prefix_sg sg;
- char sg_str[PIM_SG_LEN];
- struct interface *interface; /* backpointer to interface */
- uint32_t flags;
-
- /* IGMPv3 determined interface has local members for (S,G) ? */
- enum pim_ifmembership local_ifmembership;
-
- /* Per-interface (S,G) Join/Prune State (Section 4.1.4 of RFC4601) */
- enum pim_ifjoin_state ifjoin_state;
- struct thread *t_ifjoin_expiry_timer;
- struct thread *t_ifjoin_prune_pending_timer;
- int64_t ifjoin_creation; /* Record uptime of ifjoin state */
-
- /* Per-interface (S,G) Assert State (Section 4.6.1 of RFC4601) */
- enum pim_ifassert_state ifassert_state;
- struct thread *t_ifassert_timer;
- struct in_addr ifassert_winner;
- struct pim_assert_metric ifassert_winner_metric;
- int64_t ifassert_creation; /* Record uptime of ifassert state */
- struct pim_assert_metric ifassert_my_metric;
-
- /* Upstream (S,G) state */
- struct pim_upstream *upstream;
+ struct pim_ifchannel *parent;
+ struct list *sources;
+ struct prefix_sg sg;
+ char sg_str[PIM_SG_LEN];
+ struct interface *interface; /* backpointer to interface */
+ uint32_t flags;
+
+ /* IGMPv3 determined interface has local members for (S,G) ? */
+ enum pim_ifmembership local_ifmembership;
+
+ /* Per-interface (S,G) Join/Prune State (Section 4.1.4 of RFC4601) */
+ enum pim_ifjoin_state ifjoin_state;
+ struct thread *t_ifjoin_expiry_timer;
+ struct thread *t_ifjoin_prune_pending_timer;
+ int64_t ifjoin_creation; /* Record uptime of ifjoin state */
+
+ /* Per-interface (S,G) Assert State (Section 4.6.1 of RFC4601) */
+ enum pim_ifassert_state ifassert_state;
+ struct thread *t_ifassert_timer;
+ struct in_addr ifassert_winner;
+ struct pim_assert_metric ifassert_winner_metric;
+ int64_t ifassert_creation; /* Record uptime of ifassert state */
+ struct pim_assert_metric ifassert_my_metric;
+
+ /* Upstream (S,G) state */
+ struct pim_upstream *upstream;
};
void pim_ifchannel_free(struct pim_ifchannel *ch);
void pim_ifchannel_delete(struct pim_ifchannel *ch);
-void pim_ifchannel_delete_all (struct interface *ifp);
+void pim_ifchannel_delete_all(struct interface *ifp);
void pim_ifchannel_membership_clear(struct interface *ifp);
void pim_ifchannel_delete_on_noinfo(struct interface *ifp);
struct pim_ifchannel *pim_ifchannel_find(struct interface *ifp,
struct prefix_sg *sg);
struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp,
struct prefix_sg *sg, int flags);
-void pim_ifchannel_join_add(struct interface *ifp,
- struct in_addr neigh_addr,
- struct in_addr upstream,
- struct prefix_sg *sg,
- uint8_t source_flags,
- uint16_t holdtime);
-void pim_ifchannel_prune(struct interface *ifp,
- struct in_addr upstream,
- struct prefix_sg *sg,
- uint8_t source_flags,
+void pim_ifchannel_join_add(struct interface *ifp, struct in_addr neigh_addr,
+ struct in_addr upstream, struct prefix_sg *sg,
+ uint8_t source_flags, uint16_t holdtime);
+void pim_ifchannel_prune(struct interface *ifp, struct in_addr upstream,
+ struct prefix_sg *sg, uint8_t source_flags,
uint16_t holdtime);
int pim_ifchannel_local_membership_add(struct interface *ifp,
struct prefix_sg *sg);
void pim_ifchannel_local_membership_del(struct interface *ifp,
struct prefix_sg *sg);
-void pim_ifchannel_ifjoin_switch(const char *caller,
- struct pim_ifchannel *ch,
+void pim_ifchannel_ifjoin_switch(const char *caller, struct pim_ifchannel *ch,
enum pim_ifjoin_state new_state);
-const char *pim_ifchannel_ifjoin_name(enum pim_ifjoin_state ifjoin_state, int flags);
+const char *pim_ifchannel_ifjoin_name(enum pim_ifjoin_state ifjoin_state,
+ int flags);
const char *pim_ifchannel_ifassert_name(enum pim_ifassert_state ifassert_state);
int pim_ifchannel_isin_oiflist(struct pim_ifchannel *ch);
@@ -149,11 +142,13 @@ void pim_ifchannel_update_could_assert(struct pim_ifchannel *ch);
void pim_ifchannel_update_my_assert_metric(struct pim_ifchannel *ch);
void pim_ifchannel_update_assert_tracking_desired(struct pim_ifchannel *ch);
-void pim_ifchannel_scan_forward_start (struct interface *new_ifp);
-void pim_ifchannel_set_star_g_join_state (struct pim_ifchannel *ch, int eom, uint8_t source_flags, uint8_t join, uint8_t starg_alone);
+void pim_ifchannel_scan_forward_start(struct interface *new_ifp);
+void pim_ifchannel_set_star_g_join_state(struct pim_ifchannel *ch, int eom,
+ uint8_t source_flags, uint8_t join,
+ uint8_t starg_alone);
-int pim_ifchannel_compare (struct pim_ifchannel *ch1, struct pim_ifchannel *ch2);
+int pim_ifchannel_compare(struct pim_ifchannel *ch1, struct pim_ifchannel *ch2);
-unsigned int pim_ifchannel_hash_key (void *arg);
-int pim_ifchannel_equal (const void *arg1, const void *arg2);
+unsigned int pim_ifchannel_hash_key(void *arg);
+int pim_ifchannel_equal(const void *arg1, const void *arg2);
#endif /* PIM_IFCHANNEL_H */
diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c
index ae5f365b8..c693f30ac 100644
--- a/pimd/pim_igmp.c
+++ b/pimd/pim_igmp.c
@@ -43,62 +43,66 @@ static int pim_igmp_general_query(struct thread *t);
/* This socket is used for TXing IGMP packets only, IGMP RX happens
* in pim_mroute_msg()
*/
-static int igmp_sock_open(struct in_addr ifaddr, struct interface *ifp, uint32_t pim_options)
+static int igmp_sock_open(struct in_addr ifaddr, struct interface *ifp,
+ uint32_t pim_options)
{
- int fd;
- int join = 0;
- struct in_addr group;
-
- fd = pim_socket_mcast(IPPROTO_IGMP, ifaddr, ifp, 1);
-
- if (fd < 0)
- return -1;
-
- if (PIM_IF_TEST_IGMP_LISTEN_ALLROUTERS(pim_options)) {
- if (inet_aton(PIM_ALL_ROUTERS, &group)) {
- if (!pim_socket_join(fd, group, ifaddr, ifp->ifindex))
- ++join;
- }
- else {
- zlog_warn("%s %s: IGMP socket fd=%d interface %s: could not solve %s to group address: errno=%d: %s",
- __FILE__, __PRETTY_FUNCTION__, fd, inet_ntoa(ifaddr),
- PIM_ALL_ROUTERS, errno, safe_strerror(errno));
- }
- }
-
- /*
- IGMP routers periodically send IGMP general queries to AllSystems=224.0.0.1
- IGMP routers must receive general queries for querier election.
- */
- if (inet_aton(PIM_ALL_SYSTEMS, &group)) {
- if (!pim_socket_join(fd, group, ifaddr, ifp->ifindex))
- ++join;
- }
- else {
- zlog_warn("%s %s: IGMP socket fd=%d interface %s: could not solve %s to group address: errno=%d: %s",
- __FILE__, __PRETTY_FUNCTION__, fd, inet_ntoa(ifaddr),
- PIM_ALL_SYSTEMS, errno, safe_strerror(errno));
- }
-
- if (inet_aton(PIM_ALL_IGMP_ROUTERS, &group)) {
- if (!pim_socket_join(fd, group, ifaddr, ifp->ifindex)) {
- ++join;
- }
- }
- else {
- zlog_warn("%s %s: IGMP socket fd=%d interface %s: could not solve %s to group address: errno=%d: %s",
- __FILE__, __PRETTY_FUNCTION__, fd, inet_ntoa(ifaddr),
- PIM_ALL_IGMP_ROUTERS, errno, safe_strerror(errno));
- }
-
- if (!join) {
- zlog_err("IGMP socket fd=%d could not join any group on interface address %s",
- fd, inet_ntoa(ifaddr));
- close(fd);
- fd = -1;
- }
-
- return fd;
+ int fd;
+ int join = 0;
+ struct in_addr group;
+
+ fd = pim_socket_mcast(IPPROTO_IGMP, ifaddr, ifp, 1);
+
+ if (fd < 0)
+ return -1;
+
+ if (PIM_IF_TEST_IGMP_LISTEN_ALLROUTERS(pim_options)) {
+ if (inet_aton(PIM_ALL_ROUTERS, &group)) {
+ if (!pim_socket_join(fd, group, ifaddr, ifp->ifindex))
+ ++join;
+ } else {
+ zlog_warn(
+ "%s %s: IGMP socket fd=%d interface %s: could not solve %s to group address: errno=%d: %s",
+ __FILE__, __PRETTY_FUNCTION__, fd,
+ inet_ntoa(ifaddr), PIM_ALL_ROUTERS, errno,
+ safe_strerror(errno));
+ }
+ }
+
+ /*
+ IGMP routers periodically send IGMP general queries to
+ AllSystems=224.0.0.1
+ IGMP routers must receive general queries for querier election.
+ */
+ if (inet_aton(PIM_ALL_SYSTEMS, &group)) {
+ if (!pim_socket_join(fd, group, ifaddr, ifp->ifindex))
+ ++join;
+ } else {
+ zlog_warn(
+ "%s %s: IGMP socket fd=%d interface %s: could not solve %s to group address: errno=%d: %s",
+ __FILE__, __PRETTY_FUNCTION__, fd, inet_ntoa(ifaddr),
+ PIM_ALL_SYSTEMS, errno, safe_strerror(errno));
+ }
+
+ if (inet_aton(PIM_ALL_IGMP_ROUTERS, &group)) {
+ if (!pim_socket_join(fd, group, ifaddr, ifp->ifindex)) {
+ ++join;
+ }
+ } else {
+ zlog_warn(
+ "%s %s: IGMP socket fd=%d interface %s: could not solve %s to group address: errno=%d: %s",
+ __FILE__, __PRETTY_FUNCTION__, fd, inet_ntoa(ifaddr),
+ PIM_ALL_IGMP_ROUTERS, errno, safe_strerror(errno));
+ }
+
+ if (!join) {
+ zlog_err(
+ "IGMP socket fd=%d could not join any group on interface address %s",
+ fd, inet_ntoa(ifaddr));
+ close(fd);
+ fd = -1;
+ }
+
+ return fd;
}
#undef IGMP_SOCK_DUMP
@@ -106,828 +110,834 @@ static int igmp_sock_open(struct in_addr ifaddr, struct interface *ifp, uint32_t
#ifdef IGMP_SOCK_DUMP
static void igmp_sock_dump(array_t *igmp_sock_array)
{
- int size = array_size(igmp_sock_array);
- for (int i = 0; i < size; ++i) {
-
- struct igmp_sock *igmp = array_get(igmp_sock_array, i);
-
- zlog_debug("%s %s: [%d/%d] igmp_addr=%s fd=%d",
- __FILE__, __PRETTY_FUNCTION__,
- i, size,
- inet_ntoa(igmp->ifaddr),
- igmp->fd);
- }
+ int size = array_size(igmp_sock_array);
+ for (int i = 0; i < size; ++i) {
+
+ struct igmp_sock *igmp = array_get(igmp_sock_array, i);
+
+ zlog_debug("%s %s: [%d/%d] igmp_addr=%s fd=%d", __FILE__,
+ __PRETTY_FUNCTION__, i, size,
+ inet_ntoa(igmp->ifaddr), igmp->fd);
+ }
}
#endif
struct igmp_sock *pim_igmp_sock_lookup_ifaddr(struct list *igmp_sock_list,
struct in_addr ifaddr)
{
- struct listnode *sock_node;
- struct igmp_sock *igmp;
+ struct listnode *sock_node;
+ struct igmp_sock *igmp;
#ifdef IGMP_SOCK_DUMP
- igmp_sock_dump(igmp_sock_list);
+ igmp_sock_dump(igmp_sock_list);
#endif
- for (ALL_LIST_ELEMENTS_RO(igmp_sock_list, sock_node, igmp))
- if (ifaddr.s_addr == igmp->ifaddr.s_addr)
- return igmp;
+ for (ALL_LIST_ELEMENTS_RO(igmp_sock_list, sock_node, igmp))
+ if (ifaddr.s_addr == igmp->ifaddr.s_addr)
+ return igmp;
- return 0;
+ return 0;
}
-struct igmp_sock *igmp_sock_lookup_by_fd(struct list *igmp_sock_list,
- int fd)
+struct igmp_sock *igmp_sock_lookup_by_fd(struct list *igmp_sock_list, int fd)
{
- struct listnode *sock_node;
- struct igmp_sock *igmp;
+ struct listnode *sock_node;
+ struct igmp_sock *igmp;
- for (ALL_LIST_ELEMENTS_RO(igmp_sock_list, sock_node, igmp))
- if (fd == igmp->fd)
- return igmp;
+ for (ALL_LIST_ELEMENTS_RO(igmp_sock_list, sock_node, igmp))
+ if (fd == igmp->fd)
+ return igmp;
- return 0;
+ return 0;
}
static int pim_igmp_other_querier_expire(struct thread *t)
{
- struct igmp_sock *igmp;
-
- igmp = THREAD_ARG(t);
-
- zassert(!igmp->t_igmp_query_timer);
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char ifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
- zlog_debug("%s: Querier %s resuming",
- __PRETTY_FUNCTION__,
- ifaddr_str);
- }
-
- /*
- We are the current querier, then
- re-start sending general queries.
- RFC 2236 - sec 7 Other Querier
- present timer expired (Send General
- Query, Set Gen. Query. timer)
- */
- pim_igmp_general_query(t);
-
- return 0;
+ struct igmp_sock *igmp;
+
+ igmp = THREAD_ARG(t);
+
+ zassert(!igmp->t_igmp_query_timer);
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char ifaddr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
+ sizeof(ifaddr_str));
+ zlog_debug("%s: Querier %s resuming", __PRETTY_FUNCTION__,
+ ifaddr_str);
+ }
+
+ /*
+ We are the current querier, then
+ re-start sending general queries.
+ RFC 2236 - sec 7 Other Querier
+ present timer expired (Send General
+ Query, Set Gen. Query. timer)
+ */
+ pim_igmp_general_query(t);
+
+ return 0;
}
void pim_igmp_other_querier_timer_on(struct igmp_sock *igmp)
{
- long other_querier_present_interval_msec;
- struct pim_interface *pim_ifp;
-
- zassert(igmp);
- zassert(igmp->interface);
- zassert(igmp->interface->info);
-
- pim_ifp = igmp->interface->info;
-
- if (igmp->t_other_querier_timer) {
- /*
- There is other querier present already,
- then reset the other-querier-present timer.
- */
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char ifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
- zlog_debug("Querier %s resetting TIMER event for Other-Querier-Present",
- ifaddr_str);
- }
- THREAD_OFF(igmp->t_other_querier_timer);
- }
- else {
- /*
- We are the current querier, then stop sending general queries:
- igmp->t_igmp_query_timer = NULL;
- */
- pim_igmp_general_query_off(igmp);
- }
-
- /*
- Since this socket is starting the other-querier-present timer,
- there should not be periodic query timer for this socket.
- */
- zassert(!igmp->t_igmp_query_timer);
-
- /*
- RFC 3376: 8.5. Other Querier Present Interval
-
- The Other Querier Present Interval is the length of time that must
- pass before a multicast router decides that there is no longer
- another multicast router which should be the querier. This value
- MUST be ((the Robustness Variable) times (the Query Interval)) plus
- (one half of one Query Response Interval).
-
- other_querier_present_interval_msec = \
- igmp->querier_robustness_variable * \
- 1000 * igmp->querier_query_interval + \
- 100 * (pim_ifp->query_max_response_time_dsec >> 1);
- */
- other_querier_present_interval_msec =
- PIM_IGMP_OQPI_MSEC(igmp->querier_robustness_variable,
- igmp->querier_query_interval,
- pim_ifp->igmp_query_max_response_time_dsec);
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char ifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
- zlog_debug("Querier %s scheduling %ld.%03ld sec TIMER event for Other-Querier-Present",
- ifaddr_str,
- other_querier_present_interval_msec / 1000,
- other_querier_present_interval_msec % 1000);
- }
-
- thread_add_timer_msec(master, pim_igmp_other_querier_expire, igmp,
- other_querier_present_interval_msec,
- &igmp->t_other_querier_timer);
+ long other_querier_present_interval_msec;
+ struct pim_interface *pim_ifp;
+
+ zassert(igmp);
+ zassert(igmp->interface);
+ zassert(igmp->interface->info);
+
+ pim_ifp = igmp->interface->info;
+
+ if (igmp->t_other_querier_timer) {
+ /*
+ There is other querier present already,
+ then reset the other-querier-present timer.
+ */
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char ifaddr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
+ sizeof(ifaddr_str));
+ zlog_debug(
+ "Querier %s resetting TIMER event for Other-Querier-Present",
+ ifaddr_str);
+ }
+ THREAD_OFF(igmp->t_other_querier_timer);
+ } else {
+ /*
+ We are the current querier, then stop sending general queries:
+ igmp->t_igmp_query_timer = NULL;
+ */
+ pim_igmp_general_query_off(igmp);
+ }
+
+ /*
+ Since this socket is starting the other-querier-present timer,
+ there should not be periodic query timer for this socket.
+ */
+ zassert(!igmp->t_igmp_query_timer);
+
+ /*
+ RFC 3376: 8.5. Other Querier Present Interval
+
+ The Other Querier Present Interval is the length of time that must
+ pass before a multicast router decides that there is no longer
+ another multicast router which should be the querier. This value
+ MUST be ((the Robustness Variable) times (the Query Interval)) plus
+ (one half of one Query Response Interval).
+
+ other_querier_present_interval_msec = \
+ igmp->querier_robustness_variable * \
+ 1000 * igmp->querier_query_interval + \
+ 100 * (pim_ifp->query_max_response_time_dsec >> 1);
+ */
+ other_querier_present_interval_msec = PIM_IGMP_OQPI_MSEC(
+ igmp->querier_robustness_variable, igmp->querier_query_interval,
+ pim_ifp->igmp_query_max_response_time_dsec);
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char ifaddr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
+ sizeof(ifaddr_str));
+ zlog_debug(
+ "Querier %s scheduling %ld.%03ld sec TIMER event for Other-Querier-Present",
+ ifaddr_str, other_querier_present_interval_msec / 1000,
+ other_querier_present_interval_msec % 1000);
+ }
+
+ thread_add_timer_msec(master, pim_igmp_other_querier_expire, igmp,
+ other_querier_present_interval_msec,
+ &igmp->t_other_querier_timer);
}
void pim_igmp_other_querier_timer_off(struct igmp_sock *igmp)
{
- zassert(igmp);
-
- if (PIM_DEBUG_IGMP_TRACE) {
- if (igmp->t_other_querier_timer) {
- char ifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
- zlog_debug("IGMP querier %s fd=%d cancelling other-querier-present TIMER event on %s",
- ifaddr_str, igmp->fd, igmp->interface->name);
- }
- }
- THREAD_OFF(igmp->t_other_querier_timer);
+ zassert(igmp);
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ if (igmp->t_other_querier_timer) {
+ char ifaddr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
+ sizeof(ifaddr_str));
+ zlog_debug(
+ "IGMP querier %s fd=%d cancelling other-querier-present TIMER event on %s",
+ ifaddr_str, igmp->fd, igmp->interface->name);
+ }
+ }
+ THREAD_OFF(igmp->t_other_querier_timer);
}
-static int
-igmp_recv_query(struct igmp_sock *igmp, int query_version,
- int max_resp_code,
- struct in_addr from, const char *from_str,
- char *igmp_msg, int igmp_msg_len)
+static int igmp_recv_query(struct igmp_sock *igmp, int query_version,
+ int max_resp_code, struct in_addr from,
+ const char *from_str, char *igmp_msg,
+ int igmp_msg_len)
{
- struct interface *ifp;
- struct pim_interface *pim_ifp;
- struct in_addr group_addr;
- uint16_t recv_checksum;
- uint16_t checksum;
-
- memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
-
- ifp = igmp->interface;
- pim_ifp = ifp->info;
-
- recv_checksum = *(uint16_t *) (igmp_msg + IGMP_CHECKSUM_OFFSET);
-
- /* for computing checksum */
- *(uint16_t *) (igmp_msg + IGMP_CHECKSUM_OFFSET) = 0;
-
- checksum = in_cksum(igmp_msg, igmp_msg_len);
- if (checksum != recv_checksum) {
- zlog_warn("Recv IGMP query v%d from %s on %s: checksum mismatch: received=%x computed=%x",
- query_version, from_str, ifp->name, recv_checksum, checksum);
- return -1;
- }
-
- /* RFC 3376 defines some guidelines on operating in backwards compatibility
- * with older versions of IGMP but there are some gaps in the logic:
- *
- * - once we drop from say version 3 to version 2 we will never go back to
- * version 3 even if the node that TXed an IGMP v2 query upgrades to v3
- *
- * - The node with the lowest IP is the querier so we will only know to drop
- * from v3 to v2 if the node that is the querier is also the one that is
- * running igmp v2. If a non-querier only supports igmp v2 we will have
- * no way of knowing.
- *
- * For now we will simplify things and inform the user that they need to
- * configure all PIM routers to use the same version of IGMP.
- */
- if (query_version != pim_ifp->igmp_version) {
- zlog_warn("Recv IGMP query v%d from %s on %s but we are using v%d, please "
- "configure all PIM routers on this subnet to use the same "
- "IGMP version",
- query_version, from_str, ifp->name, pim_ifp->igmp_version);
- return 0;
- }
-
- if (PIM_DEBUG_IGMP_PACKETS) {
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", group_addr, group_str, sizeof(group_str));
- zlog_debug("Recv IGMP query v%d from %s on %s for group %s",
- query_version, from_str, ifp->name, group_str);
- }
-
- /*
- RFC 3376: 6.6.2. Querier Election
-
- When a router receives a query with a lower IP address, it sets
- the Other-Querier-Present timer to Other Querier Present Interval
- and ceases to send queries on the network if it was the previously
- elected querier.
- */
- if (ntohl(from.s_addr) < ntohl(igmp->ifaddr.s_addr)) {
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char ifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
- zlog_debug("%s: local address %s (%u) lost querier election to %s (%u)",
- ifp->name,
- ifaddr_str, ntohl(igmp->ifaddr.s_addr),
- from_str, ntohl(from.s_addr));
- }
-
- pim_igmp_other_querier_timer_on(igmp);
- }
-
- /* IGMP version 3 is the only one where we process the RXed query */
- if (query_version == 3) {
- igmp_v3_recv_query(igmp, from_str, igmp_msg);
- }
-
- return 0;
+ struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ struct in_addr group_addr;
+ uint16_t recv_checksum;
+ uint16_t checksum;
+
+ memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
+
+ ifp = igmp->interface;
+ pim_ifp = ifp->info;
+
+ recv_checksum = *(uint16_t *)(igmp_msg + IGMP_CHECKSUM_OFFSET);
+
+ /* for computing checksum */
+ *(uint16_t *)(igmp_msg + IGMP_CHECKSUM_OFFSET) = 0;
+
+ checksum = in_cksum(igmp_msg, igmp_msg_len);
+ if (checksum != recv_checksum) {
+ zlog_warn(
+ "Recv IGMP query v%d from %s on %s: checksum mismatch: received=%x computed=%x",
+ query_version, from_str, ifp->name, recv_checksum,
+ checksum);
+ return -1;
+ }
+
+ /* RFC 3376 defines some guidelines on operating in backwards
+ * compatibility
+ * with older versions of IGMP but there are some gaps in the logic:
+ *
+ * - once we drop from say version 3 to version 2 we will never go back
+ * to
+ * version 3 even if the node that TXed an IGMP v2 query upgrades to
+ * v3
+ *
+ * - The node with the lowest IP is the querier so we will only know to
+ * drop
+ * from v3 to v2 if the node that is the querier is also the one that
+ * is
+ * running igmp v2. If a non-querier only supports igmp v2 we will
+ * have
+ * no way of knowing.
+ *
+ * For now we will simplify things and inform the user that they need to
+ * configure all PIM routers to use the same version of IGMP.
+ */
+ if (query_version != pim_ifp->igmp_version) {
+ zlog_warn(
+ "Recv IGMP query v%d from %s on %s but we are using v%d, please "
+ "configure all PIM routers on this subnet to use the same "
+ "IGMP version",
+ query_version, from_str, ifp->name,
+ pim_ifp->igmp_version);
+ return 0;
+ }
+
+ if (PIM_DEBUG_IGMP_PACKETS) {
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group_addr, group_str,
+ sizeof(group_str));
+ zlog_debug("Recv IGMP query v%d from %s on %s for group %s",
+ query_version, from_str, ifp->name, group_str);
+ }
+
+ /*
+ RFC 3376: 6.6.2. Querier Election
+
+ When a router receives a query with a lower IP address, it sets
+ the Other-Querier-Present timer to Other Querier Present Interval
+ and ceases to send queries on the network if it was the previously
+ elected querier.
+ */
+ if (ntohl(from.s_addr) < ntohl(igmp->ifaddr.s_addr)) {
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char ifaddr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
+ sizeof(ifaddr_str));
+ zlog_debug(
+ "%s: local address %s (%u) lost querier election to %s (%u)",
+ ifp->name, ifaddr_str,
+ ntohl(igmp->ifaddr.s_addr), from_str,
+ ntohl(from.s_addr));
+ }
+
+ pim_igmp_other_querier_timer_on(igmp);
+ }
+
+ /* IGMP version 3 is the only one where we process the RXed query */
+ if (query_version == 3) {
+ igmp_v3_recv_query(igmp, from_str, igmp_msg);
+ }
+
+ return 0;
}
-static void on_trace(const char *label,
- struct interface *ifp, struct in_addr from)
+static void on_trace(const char *label, struct interface *ifp,
+ struct in_addr from)
{
- if (PIM_DEBUG_IGMP_TRACE) {
- char from_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<from?>", from, from_str, sizeof(from_str));
- zlog_debug("%s: from %s on %s",
- label, from_str, ifp->name);
- }
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char from_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<from?>", from, from_str, sizeof(from_str));
+ zlog_debug("%s: from %s on %s", label, from_str, ifp->name);
+ }
}
-static int
-igmp_v1_recv_report (struct igmp_sock *igmp,
- struct in_addr from, const char *from_str,
- char *igmp_msg, int igmp_msg_len)
+static int igmp_v1_recv_report(struct igmp_sock *igmp, struct in_addr from,
+ const char *from_str, char *igmp_msg,
+ int igmp_msg_len)
{
- struct interface *ifp = igmp->interface;
- struct igmp_group *group;
- struct in_addr group_addr;
+ struct interface *ifp = igmp->interface;
+ struct igmp_group *group;
+ struct in_addr group_addr;
- on_trace(__PRETTY_FUNCTION__, igmp->interface, from);
+ on_trace(__PRETTY_FUNCTION__, igmp->interface, from);
- if (igmp_msg_len != IGMP_V12_MSG_SIZE) {
- zlog_warn("Recv IGMP report v1 from %s on %s: size=%d other than correct=%d",
- from_str, ifp->name, igmp_msg_len, IGMP_V12_MSG_SIZE);
- return -1;
- }
+ if (igmp_msg_len != IGMP_V12_MSG_SIZE) {
+ zlog_warn(
+ "Recv IGMP report v1 from %s on %s: size=%d other than correct=%d",
+ from_str, ifp->name, igmp_msg_len, IGMP_V12_MSG_SIZE);
+ return -1;
+ }
- if (PIM_DEBUG_IGMP_TRACE) {
- zlog_warn("%s %s: FIXME WRITEME",
- __FILE__, __PRETTY_FUNCTION__);
- }
+ if (PIM_DEBUG_IGMP_TRACE) {
+ zlog_warn("%s %s: FIXME WRITEME", __FILE__,
+ __PRETTY_FUNCTION__);
+ }
- memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
+ memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
- /* non-existant group is created as INCLUDE {empty} */
- group = igmp_add_group_by_addr(igmp, group_addr);
- if (!group) {
- return -1;
- }
+ /* non-existant group is created as INCLUDE {empty} */
+ group = igmp_add_group_by_addr(igmp, group_addr);
+ if (!group) {
+ return -1;
+ }
- group->last_igmp_v1_report_dsec = pim_time_monotonic_dsec();
+ group->last_igmp_v1_report_dsec = pim_time_monotonic_dsec();
- return 0;
+ return 0;
}
int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len)
{
- struct ip *ip_hdr;
- size_t ip_hlen; /* ip header length in bytes */
- char *igmp_msg;
- int igmp_msg_len;
- int msg_type;
- char from_str[INET_ADDRSTRLEN];
- char to_str[INET_ADDRSTRLEN];
-
- if (len < sizeof(*ip_hdr)) {
- zlog_warn("IGMP packet size=%zu shorter than minimum=%zu",
- len, sizeof(*ip_hdr));
- return -1;
- }
-
- ip_hdr = (struct ip *) buf;
-
- pim_inet4_dump("<src?>", ip_hdr->ip_src, from_str , sizeof(from_str));
- pim_inet4_dump("<dst?>", ip_hdr->ip_dst, to_str , sizeof(to_str));
-
- ip_hlen = ip_hdr->ip_hl << 2; /* ip_hl gives length in 4-byte words */
-
- if (PIM_DEBUG_IGMP_PACKETS) {
- zlog_debug("Recv IP packet from %s to %s on %s: size=%zu ip_header_size=%zu ip_proto=%d",
- from_str, to_str, igmp->interface->name, len, ip_hlen, ip_hdr->ip_p);
- }
-
- igmp_msg = buf + ip_hlen;
- msg_type = *igmp_msg;
- igmp_msg_len = len - ip_hlen;
-
- if (PIM_DEBUG_IGMP_PACKETS) {
- zlog_debug("Recv IGMP packet from %s to %s on %s: ttl=%d msg_type=%d msg_size=%d",
- from_str, to_str, igmp->interface->name, ip_hdr->ip_ttl, msg_type,
- igmp_msg_len);
- }
-
- if (igmp_msg_len < PIM_IGMP_MIN_LEN) {
- zlog_warn("IGMP message size=%d shorter than minimum=%d",
- igmp_msg_len, PIM_IGMP_MIN_LEN);
- return -1;
- }
-
- switch (msg_type) {
- case PIM_IGMP_MEMBERSHIP_QUERY:
- {
- int max_resp_code = igmp_msg[1];
- int query_version;
-
- /*
- RFC 3376: 7.1. Query Version Distinctions
- IGMPv1 Query: length = 8 octets AND Max Resp Code field is zero
- IGMPv2 Query: length = 8 octets AND Max Resp Code field is non-zero
- IGMPv3 Query: length >= 12 octets
- */
-
- if (igmp_msg_len == 8) {
- query_version = max_resp_code ? 2 : 1;
- }
- else if (igmp_msg_len >= 12) {
- query_version = 3;
- }
- else {
- zlog_warn("Unknown IGMP query version");
- return -1;
- }
+ struct ip *ip_hdr;
+ size_t ip_hlen; /* ip header length in bytes */
+ char *igmp_msg;
+ int igmp_msg_len;
+ int msg_type;
+ char from_str[INET_ADDRSTRLEN];
+ char to_str[INET_ADDRSTRLEN];
+
+ if (len < sizeof(*ip_hdr)) {
+ zlog_warn("IGMP packet size=%zu shorter than minimum=%zu", len,
+ sizeof(*ip_hdr));
+ return -1;
+ }
+
+ ip_hdr = (struct ip *)buf;
+
+ pim_inet4_dump("<src?>", ip_hdr->ip_src, from_str, sizeof(from_str));
+ pim_inet4_dump("<dst?>", ip_hdr->ip_dst, to_str, sizeof(to_str));
+
+ ip_hlen = ip_hdr->ip_hl << 2; /* ip_hl gives length in 4-byte words */
- return igmp_recv_query(igmp, query_version, max_resp_code,
- ip_hdr->ip_src, from_str,
- igmp_msg, igmp_msg_len);
- }
+ if (PIM_DEBUG_IGMP_PACKETS) {
+ zlog_debug(
+ "Recv IP packet from %s to %s on %s: size=%zu ip_header_size=%zu ip_proto=%d",
+ from_str, to_str, igmp->interface->name, len, ip_hlen,
+ ip_hdr->ip_p);
+ }
+
+ igmp_msg = buf + ip_hlen;
+ msg_type = *igmp_msg;
+ igmp_msg_len = len - ip_hlen;
+
+ if (PIM_DEBUG_IGMP_PACKETS) {
+ zlog_debug(
+ "Recv IGMP packet from %s to %s on %s: ttl=%d msg_type=%d msg_size=%d",
+ from_str, to_str, igmp->interface->name, ip_hdr->ip_ttl,
+ msg_type, igmp_msg_len);
+ }
- case PIM_IGMP_V3_MEMBERSHIP_REPORT:
- return igmp_v3_recv_report(igmp, ip_hdr->ip_src, from_str,
- igmp_msg, igmp_msg_len);
+ if (igmp_msg_len < PIM_IGMP_MIN_LEN) {
+ zlog_warn("IGMP message size=%d shorter than minimum=%d",
+ igmp_msg_len, PIM_IGMP_MIN_LEN);
+ return -1;
+ }
+
+ switch (msg_type) {
+ case PIM_IGMP_MEMBERSHIP_QUERY: {
+ int max_resp_code = igmp_msg[1];
+ int query_version;
+
+ /*
+ RFC 3376: 7.1. Query Version Distinctions
+ IGMPv1 Query: length = 8 octets AND Max Resp Code field is
+ zero
+ IGMPv2 Query: length = 8 octets AND Max Resp Code field is
+ non-zero
+ IGMPv3 Query: length >= 12 octets
+ */
+
+ if (igmp_msg_len == 8) {
+ query_version = max_resp_code ? 2 : 1;
+ } else if (igmp_msg_len >= 12) {
+ query_version = 3;
+ } else {
+ zlog_warn("Unknown IGMP query version");
+ return -1;
+ }
+
+ return igmp_recv_query(igmp, query_version, max_resp_code,
+ ip_hdr->ip_src, from_str, igmp_msg,
+ igmp_msg_len);
+ }
- case PIM_IGMP_V2_MEMBERSHIP_REPORT:
- return igmp_v2_recv_report(igmp, ip_hdr->ip_src, from_str,
- igmp_msg, igmp_msg_len);
+ case PIM_IGMP_V3_MEMBERSHIP_REPORT:
+ return igmp_v3_recv_report(igmp, ip_hdr->ip_src, from_str,
+ igmp_msg, igmp_msg_len);
- case PIM_IGMP_V1_MEMBERSHIP_REPORT:
- return igmp_v1_recv_report(igmp, ip_hdr->ip_src, from_str,
- igmp_msg, igmp_msg_len);
+ case PIM_IGMP_V2_MEMBERSHIP_REPORT:
+ return igmp_v2_recv_report(igmp, ip_hdr->ip_src, from_str,
+ igmp_msg, igmp_msg_len);
- case PIM_IGMP_V2_LEAVE_GROUP:
- return igmp_v2_recv_leave(igmp, ip_hdr->ip_src, from_str,
- igmp_msg, igmp_msg_len);
- }
+ case PIM_IGMP_V1_MEMBERSHIP_REPORT:
+ return igmp_v1_recv_report(igmp, ip_hdr->ip_src, from_str,
+ igmp_msg, igmp_msg_len);
- zlog_warn("Ignoring unsupported IGMP message type: %d", msg_type);
+ case PIM_IGMP_V2_LEAVE_GROUP:
+ return igmp_v2_recv_leave(igmp, ip_hdr->ip_src, from_str,
+ igmp_msg, igmp_msg_len);
+ }
- return -1;
+ zlog_warn("Ignoring unsupported IGMP message type: %d", msg_type);
+
+ return -1;
}
void pim_igmp_general_query_on(struct igmp_sock *igmp)
{
- struct pim_interface *pim_ifp;
- int startup_mode;
- int query_interval;
-
- /*
- Since this socket is starting as querier,
- there should not exist a timer for other-querier-present.
- */
- zassert(!igmp->t_other_querier_timer);
- pim_ifp = igmp->interface->info;
- zassert(pim_ifp);
-
- /*
- RFC 3376: 8.6. Startup Query Interval
-
- The Startup Query Interval is the interval between General Queries
- sent by a Querier on startup. Default: 1/4 the Query Interval.
- The first one should be sent out immediately instead of 125/4
- seconds from now.
- */
- startup_mode = igmp->startup_query_count > 0;
- if (startup_mode) {
- /*
- * If this is the first time we are sending a query on a
- * newly configured igmp interface send it out in 1 second
- * just to give the entire world a tiny bit of time to settle
- * else the query interval is:
- * query_interval = pim_ifp->igmp_default_query_interval >> 2;
- */
- if (igmp->startup_query_count == igmp->querier_robustness_variable)
- query_interval = 1;
- else
- query_interval = PIM_IGMP_SQI(pim_ifp->igmp_default_query_interval);
-
- --igmp->startup_query_count;
- }
- else {
- query_interval = igmp->querier_query_interval;
- }
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char ifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
- zlog_debug("Querier %s scheduling %d-second (%s) TIMER event for IGMP query on fd=%d",
- ifaddr_str,
- query_interval,
- startup_mode ? "startup" : "non-startup",
- igmp->fd);
- }
- igmp->t_igmp_query_timer = NULL;
- thread_add_timer(master, pim_igmp_general_query, igmp, query_interval,
- &igmp->t_igmp_query_timer);
+ struct pim_interface *pim_ifp;
+ int startup_mode;
+ int query_interval;
+
+ /*
+ Since this socket is starting as querier,
+ there should not exist a timer for other-querier-present.
+ */
+ zassert(!igmp->t_other_querier_timer);
+ pim_ifp = igmp->interface->info;
+ zassert(pim_ifp);
+
+ /*
+ RFC 3376: 8.6. Startup Query Interval
+
+ The Startup Query Interval is the interval between General Queries
+ sent by a Querier on startup. Default: 1/4 the Query Interval.
+ The first one should be sent out immediately instead of 125/4
+ seconds from now.
+ */
+ startup_mode = igmp->startup_query_count > 0;
+ if (startup_mode) {
+ /*
+ * If this is the first time we are sending a query on a
+ * newly configured igmp interface send it out in 1 second
+ * just to give the entire world a tiny bit of time to settle
+ * else the query interval is:
+ * query_interval = pim_ifp->igmp_default_query_interval >> 2;
+ */
+ if (igmp->startup_query_count
+ == igmp->querier_robustness_variable)
+ query_interval = 1;
+ else
+ query_interval = PIM_IGMP_SQI(
+ pim_ifp->igmp_default_query_interval);
+
+ --igmp->startup_query_count;
+ } else {
+ query_interval = igmp->querier_query_interval;
+ }
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char ifaddr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
+ sizeof(ifaddr_str));
+ zlog_debug(
+ "Querier %s scheduling %d-second (%s) TIMER event for IGMP query on fd=%d",
+ ifaddr_str, query_interval,
+ startup_mode ? "startup" : "non-startup", igmp->fd);
+ }
+ igmp->t_igmp_query_timer = NULL;
+ thread_add_timer(master, pim_igmp_general_query, igmp, query_interval,
+ &igmp->t_igmp_query_timer);
}
void pim_igmp_general_query_off(struct igmp_sock *igmp)
{
- zassert(igmp);
-
- if (PIM_DEBUG_IGMP_TRACE) {
- if (igmp->t_igmp_query_timer) {
- char ifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
- zlog_debug("IGMP querier %s fd=%d cancelling query TIMER event on %s",
- ifaddr_str, igmp->fd, igmp->interface->name);
- }
- }
- THREAD_OFF(igmp->t_igmp_query_timer);
+ zassert(igmp);
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ if (igmp->t_igmp_query_timer) {
+ char ifaddr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
+ sizeof(ifaddr_str));
+ zlog_debug(
+ "IGMP querier %s fd=%d cancelling query TIMER event on %s",
+ ifaddr_str, igmp->fd, igmp->interface->name);
+ }
+ }
+ THREAD_OFF(igmp->t_igmp_query_timer);
}
/* Issue IGMP general query */
static int pim_igmp_general_query(struct thread *t)
{
- struct igmp_sock *igmp;
- struct in_addr dst_addr;
- struct in_addr group_addr;
- struct pim_interface *pim_ifp;
- int query_buf_size;
-
- igmp = THREAD_ARG(t);
-
- zassert(igmp->interface);
- zassert(igmp->interface->info);
-
- pim_ifp = igmp->interface->info;
-
- if (pim_ifp->igmp_version == 3) {
- query_buf_size = PIM_IGMP_BUFSIZE_WRITE;
- } else {
- query_buf_size = IGMP_V12_MSG_SIZE;
- }
-
- char query_buf[query_buf_size];
-
- /*
- RFC3376: 4.1.12. IP Destination Addresses for Queries
-
- In IGMPv3, General Queries are sent with an IP destination address
- of 224.0.0.1, the all-systems multicast address. Group-Specific
- and Group-and-Source-Specific Queries are sent with an IP
- destination address equal to the multicast address of interest.
- */
-
- dst_addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
- group_addr.s_addr = PIM_NET_INADDR_ANY;
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char querier_str[INET_ADDRSTRLEN];
- char dst_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<querier?>", igmp->ifaddr, querier_str,
- sizeof(querier_str));
- pim_inet4_dump("<dst?>", dst_addr, dst_str, sizeof(dst_str));
- zlog_debug("Querier %s issuing IGMP general query to %s on %s",
- querier_str, dst_str, igmp->interface->name);
- }
-
- igmp_send_query (pim_ifp->igmp_version,
- 0 /* igmp_group */,
- igmp->fd,
- igmp->interface->name,
- query_buf,
- sizeof(query_buf),
- 0 /* num_sources */,
- dst_addr,
- group_addr,
- pim_ifp->igmp_query_max_response_time_dsec,
- 1 /* s_flag: always set for general queries */,
- igmp->querier_robustness_variable,
- igmp->querier_query_interval);
-
- pim_igmp_general_query_on(igmp);
-
- return 0;
+ struct igmp_sock *igmp;
+ struct in_addr dst_addr;
+ struct in_addr group_addr;
+ struct pim_interface *pim_ifp;
+ int query_buf_size;
+
+ igmp = THREAD_ARG(t);
+
+ zassert(igmp->interface);
+ zassert(igmp->interface->info);
+
+ pim_ifp = igmp->interface->info;
+
+ if (pim_ifp->igmp_version == 3) {
+ query_buf_size = PIM_IGMP_BUFSIZE_WRITE;
+ } else {
+ query_buf_size = IGMP_V12_MSG_SIZE;
+ }
+
+ char query_buf[query_buf_size];
+
+ /*
+ RFC3376: 4.1.12. IP Destination Addresses for Queries
+
+ In IGMPv3, General Queries are sent with an IP destination address
+ of 224.0.0.1, the all-systems multicast address. Group-Specific
+ and Group-and-Source-Specific Queries are sent with an IP
+ destination address equal to the multicast address of interest.
+ */
+
+ dst_addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
+ group_addr.s_addr = PIM_NET_INADDR_ANY;
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char querier_str[INET_ADDRSTRLEN];
+ char dst_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<querier?>", igmp->ifaddr, querier_str,
+ sizeof(querier_str));
+ pim_inet4_dump("<dst?>", dst_addr, dst_str, sizeof(dst_str));
+ zlog_debug("Querier %s issuing IGMP general query to %s on %s",
+ querier_str, dst_str, igmp->interface->name);
+ }
+
+ igmp_send_query(pim_ifp->igmp_version, 0 /* igmp_group */, igmp->fd,
+ igmp->interface->name, query_buf, sizeof(query_buf),
+ 0 /* num_sources */, dst_addr, group_addr,
+ pim_ifp->igmp_query_max_response_time_dsec,
+ 1 /* s_flag: always set for general queries */,
+ igmp->querier_robustness_variable,
+ igmp->querier_query_interval);
+
+ pim_igmp_general_query_on(igmp);
+
+ return 0;
}
static void sock_close(struct igmp_sock *igmp)
{
- pim_igmp_other_querier_timer_off(igmp);
- pim_igmp_general_query_off(igmp);
-
- if (PIM_DEBUG_IGMP_TRACE_DETAIL) {
- if (igmp->t_igmp_read) {
- zlog_debug("Cancelling READ event on IGMP socket %s fd=%d on interface %s",
- inet_ntoa(igmp->ifaddr), igmp->fd,
- igmp->interface->name);
- }
- }
- THREAD_OFF(igmp->t_igmp_read);
-
- if (close(igmp->fd)) {
- zlog_err("Failure closing IGMP socket %s fd=%d on interface %s: errno=%d: %s",
- inet_ntoa(igmp->ifaddr), igmp->fd, igmp->interface->name,
- errno, safe_strerror(errno));
- }
-
- if (PIM_DEBUG_IGMP_TRACE_DETAIL) {
- zlog_debug("Deleted IGMP socket %s fd=%d on interface %s",
- inet_ntoa(igmp->ifaddr), igmp->fd, igmp->interface->name);
- }
+ pim_igmp_other_querier_timer_off(igmp);
+ pim_igmp_general_query_off(igmp);
+
+ if (PIM_DEBUG_IGMP_TRACE_DETAIL) {
+ if (igmp->t_igmp_read) {
+ zlog_debug(
+ "Cancelling READ event on IGMP socket %s fd=%d on interface %s",
+ inet_ntoa(igmp->ifaddr), igmp->fd,
+ igmp->interface->name);
+ }
+ }
+ THREAD_OFF(igmp->t_igmp_read);
+
+ if (close(igmp->fd)) {
+ zlog_err(
+ "Failure closing IGMP socket %s fd=%d on interface %s: errno=%d: %s",
+ inet_ntoa(igmp->ifaddr), igmp->fd,
+ igmp->interface->name, errno, safe_strerror(errno));
+ }
+
+ if (PIM_DEBUG_IGMP_TRACE_DETAIL) {
+ zlog_debug("Deleted IGMP socket %s fd=%d on interface %s",
+ inet_ntoa(igmp->ifaddr), igmp->fd,
+ igmp->interface->name);
+ }
}
void igmp_startup_mode_on(struct igmp_sock *igmp)
{
- struct pim_interface *pim_ifp;
+ struct pim_interface *pim_ifp;
- pim_ifp = igmp->interface->info;
+ pim_ifp = igmp->interface->info;
- /*
- RFC 3376: 8.7. Startup Query Count
+ /*
+ RFC 3376: 8.7. Startup Query Count
- The Startup Query Count is the number of Queries sent out on
- startup, separated by the Startup Query Interval. Default: the
- Robustness Variable.
- */
- igmp->startup_query_count = igmp->querier_robustness_variable;
+ The Startup Query Count is the number of Queries sent out on
+ startup, separated by the Startup Query Interval. Default: the
+ Robustness Variable.
+ */
+ igmp->startup_query_count = igmp->querier_robustness_variable;
- /*
- Since we're (re)starting, reset QQI to default Query Interval
- */
- igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
+ /*
+ Since we're (re)starting, reset QQI to default Query Interval
+ */
+ igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
}
static void igmp_group_free(struct igmp_group *group)
{
- list_free(group->group_source_list);
+ list_free(group->group_source_list);
- XFREE(MTYPE_PIM_IGMP_GROUP, group);
+ XFREE(MTYPE_PIM_IGMP_GROUP, group);
}
static void igmp_group_delete(struct igmp_group *group)
{
- struct listnode *src_node;
- struct listnode *src_nextnode;
- struct igmp_source *src;
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- zlog_debug("Deleting IGMP group %s from socket %d interface %s",
- group_str,
- group->group_igmp_sock->fd,
- group->group_igmp_sock->interface->name);
- }
-
- for (ALL_LIST_ELEMENTS(group->group_source_list, src_node, src_nextnode, src)) {
- igmp_source_delete(src);
- }
-
- if (group->t_group_query_retransmit_timer) {
- THREAD_OFF(group->t_group_query_retransmit_timer);
- }
-
- group_timer_off(group);
- listnode_delete(group->group_igmp_sock->igmp_group_list, group);
- hash_release (group->group_igmp_sock->igmp_group_hash, group);
-
- igmp_group_free(group);
+ struct listnode *src_node;
+ struct listnode *src_nextnode;
+ struct igmp_source *src;
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group->group_addr, group_str,
+ sizeof(group_str));
+ zlog_debug("Deleting IGMP group %s from socket %d interface %s",
+ group_str, group->group_igmp_sock->fd,
+ group->group_igmp_sock->interface->name);
+ }
+
+ for (ALL_LIST_ELEMENTS(group->group_source_list, src_node, src_nextnode,
+ src)) {
+ igmp_source_delete(src);
+ }
+
+ if (group->t_group_query_retransmit_timer) {
+ THREAD_OFF(group->t_group_query_retransmit_timer);
+ }
+
+ group_timer_off(group);
+ listnode_delete(group->group_igmp_sock->igmp_group_list, group);
+ hash_release(group->group_igmp_sock->igmp_group_hash, group);
+
+ igmp_group_free(group);
}
void igmp_group_delete_empty_include(struct igmp_group *group)
{
- zassert(!group->group_filtermode_isexcl);
- zassert(!listcount(group->group_source_list));
+ zassert(!group->group_filtermode_isexcl);
+ zassert(!listcount(group->group_source_list));
- igmp_group_delete(group);
+ igmp_group_delete(group);
}
void igmp_sock_free(struct igmp_sock *igmp)
{
- zassert(!igmp->t_igmp_read);
- zassert(!igmp->t_igmp_query_timer);
- zassert(!igmp->t_other_querier_timer);
- zassert(igmp->igmp_group_list);
- zassert(!listcount(igmp->igmp_group_list));
+ zassert(!igmp->t_igmp_read);
+ zassert(!igmp->t_igmp_query_timer);
+ zassert(!igmp->t_other_querier_timer);
+ zassert(igmp->igmp_group_list);
+ zassert(!listcount(igmp->igmp_group_list));
- list_free(igmp->igmp_group_list);
- hash_free(igmp->igmp_group_hash);
+ list_free(igmp->igmp_group_list);
+ hash_free(igmp->igmp_group_hash);
- XFREE(MTYPE_PIM_IGMP_SOCKET, igmp);
+ XFREE(MTYPE_PIM_IGMP_SOCKET, igmp);
}
void igmp_sock_delete(struct igmp_sock *igmp)
{
- struct pim_interface *pim_ifp;
- struct listnode *grp_node;
- struct listnode *grp_nextnode;
- struct igmp_group *grp;
-
- for (ALL_LIST_ELEMENTS(igmp->igmp_group_list, grp_node, grp_nextnode, grp)) {
- igmp_group_delete(grp);
- }
+ struct pim_interface *pim_ifp;
+ struct listnode *grp_node;
+ struct listnode *grp_nextnode;
+ struct igmp_group *grp;
+
+ for (ALL_LIST_ELEMENTS(igmp->igmp_group_list, grp_node, grp_nextnode,
+ grp)) {
+ igmp_group_delete(grp);
+ }
- sock_close(igmp);
+ sock_close(igmp);
- pim_ifp = igmp->interface->info;
+ pim_ifp = igmp->interface->info;
- listnode_delete(pim_ifp->igmp_socket_list, igmp);
+ listnode_delete(pim_ifp->igmp_socket_list, igmp);
- igmp_sock_free(igmp);
+ igmp_sock_free(igmp);
}
-void
-igmp_sock_delete_all (struct interface *ifp)
+void igmp_sock_delete_all(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
- struct listnode *igmp_node, *igmp_nextnode;
- struct igmp_sock *igmp;
+ struct pim_interface *pim_ifp;
+ struct listnode *igmp_node, *igmp_nextnode;
+ struct igmp_sock *igmp;
- pim_ifp = ifp->info;
+ pim_ifp = ifp->info;
- for (ALL_LIST_ELEMENTS (pim_ifp->igmp_socket_list, igmp_node,
- igmp_nextnode, igmp))
- {
- igmp_sock_delete(igmp);
- }
+ for (ALL_LIST_ELEMENTS(pim_ifp->igmp_socket_list, igmp_node,
+ igmp_nextnode, igmp)) {
+ igmp_sock_delete(igmp);
+ }
}
-static unsigned int
-igmp_group_hash_key (void *arg)
+static unsigned int igmp_group_hash_key(void *arg)
{
- struct igmp_group *group = (struct igmp_group *)arg;
+ struct igmp_group *group = (struct igmp_group *)arg;
- return jhash_1word(group->group_addr.s_addr, 0);
+ return jhash_1word(group->group_addr.s_addr, 0);
}
-static int
-igmp_group_hash_equal (const void *arg1, const void *arg2)
+static int igmp_group_hash_equal(const void *arg1, const void *arg2)
{
- const struct igmp_group *g1 = (const struct igmp_group *)arg1;
- const struct igmp_group *g2 = (const struct igmp_group *)arg2;
+ const struct igmp_group *g1 = (const struct igmp_group *)arg1;
+ const struct igmp_group *g2 = (const struct igmp_group *)arg2;
- if (g1->group_addr.s_addr == g2->group_addr.s_addr)
- return 1;
+ if (g1->group_addr.s_addr == g2->group_addr.s_addr)
+ return 1;
- return 0;
+ return 0;
}
-static struct igmp_sock *igmp_sock_new(int fd,
- struct in_addr ifaddr,
+static struct igmp_sock *igmp_sock_new(int fd, struct in_addr ifaddr,
struct interface *ifp)
{
- struct pim_interface *pim_ifp;
- struct igmp_sock *igmp;
-
- pim_ifp = ifp->info;
-
- if (PIM_DEBUG_IGMP_TRACE) {
- zlog_debug("Creating IGMP socket fd=%d for address %s on interface %s",
- fd, inet_ntoa(ifaddr), ifp->name);
- }
-
- igmp = XCALLOC(MTYPE_PIM_IGMP_SOCKET, sizeof(*igmp));
- if (!igmp) {
- zlog_warn("%s %s: XCALLOC() failure",
- __FILE__, __PRETTY_FUNCTION__);
- return 0;
- }
-
- igmp->igmp_group_list = list_new();
- if (!igmp->igmp_group_list) {
- zlog_err("%s %s: failure: igmp_group_list = list_new()",
- __FILE__, __PRETTY_FUNCTION__);
- return 0;
- }
- igmp->igmp_group_list->del = (void (*)(void *)) igmp_group_free;
-
- igmp->igmp_group_hash = hash_create (igmp_group_hash_key,
- igmp_group_hash_equal, NULL);
-
- igmp->fd = fd;
- igmp->interface = ifp;
- igmp->ifaddr = ifaddr;
- igmp->t_igmp_read = NULL;
- igmp->t_igmp_query_timer = NULL;
- igmp->t_other_querier_timer = NULL; /* no other querier present */
- igmp->querier_robustness_variable = pim_ifp->igmp_default_robustness_variable;
- igmp->sock_creation = pim_time_monotonic_sec();
-
- /*
- igmp_startup_mode_on() will reset QQI:
-
- igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
- */
- igmp_startup_mode_on(igmp);
- pim_igmp_general_query_on(igmp);
-
- return igmp;
+ struct pim_interface *pim_ifp;
+ struct igmp_sock *igmp;
+
+ pim_ifp = ifp->info;
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ zlog_debug(
+ "Creating IGMP socket fd=%d for address %s on interface %s",
+ fd, inet_ntoa(ifaddr), ifp->name);
+ }
+
+ igmp = XCALLOC(MTYPE_PIM_IGMP_SOCKET, sizeof(*igmp));
+ if (!igmp) {
+ zlog_warn("%s %s: XCALLOC() failure", __FILE__,
+ __PRETTY_FUNCTION__);
+ return 0;
+ }
+
+ igmp->igmp_group_list = list_new();
+ if (!igmp->igmp_group_list) {
+ zlog_err("%s %s: failure: igmp_group_list = list_new()",
+ __FILE__, __PRETTY_FUNCTION__);
+ return 0;
+ }
+ igmp->igmp_group_list->del = (void (*)(void *))igmp_group_free;
+
+ igmp->igmp_group_hash =
+ hash_create(igmp_group_hash_key, igmp_group_hash_equal, NULL);
+
+ igmp->fd = fd;
+ igmp->interface = ifp;
+ igmp->ifaddr = ifaddr;
+ igmp->t_igmp_read = NULL;
+ igmp->t_igmp_query_timer = NULL;
+ igmp->t_other_querier_timer = NULL; /* no other querier present */
+ igmp->querier_robustness_variable =
+ pim_ifp->igmp_default_robustness_variable;
+ igmp->sock_creation = pim_time_monotonic_sec();
+
+ /*
+ igmp_startup_mode_on() will reset QQI:
+
+ igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
+ */
+ igmp_startup_mode_on(igmp);
+ pim_igmp_general_query_on(igmp);
+
+ return igmp;
}
-static void igmp_read_on (struct igmp_sock *igmp);
+static void igmp_read_on(struct igmp_sock *igmp);
-static int
-pim_igmp_read (struct thread *t)
+static int pim_igmp_read(struct thread *t)
{
- uint8_t buf[10000];
- struct igmp_sock *igmp = (struct igmp_sock *)THREAD_ARG(t);
- struct sockaddr_in from;
- struct sockaddr_in to;
- socklen_t fromlen = sizeof(from);
- socklen_t tolen = sizeof(to);
- ifindex_t ifindex = -1;
- int cont = 1;
- int len;
-
- while (cont)
- {
- len = pim_socket_recvfromto(igmp->fd, buf, sizeof(buf),
- &from, &fromlen,
- &to, &tolen,
- &ifindex);
- if (len < 0)
- {
- if (errno == EINTR)
- continue;
- if (errno == EWOULDBLOCK || errno == EAGAIN)
- break;
-
- goto done;
+ uint8_t buf[10000];
+ struct igmp_sock *igmp = (struct igmp_sock *)THREAD_ARG(t);
+ struct sockaddr_in from;
+ struct sockaddr_in to;
+ socklen_t fromlen = sizeof(from);
+ socklen_t tolen = sizeof(to);
+ ifindex_t ifindex = -1;
+ int cont = 1;
+ int len;
+
+ while (cont) {
+ len = pim_socket_recvfromto(igmp->fd, buf, sizeof(buf), &from,
+ &fromlen, &to, &tolen, &ifindex);
+ if (len < 0) {
+ if (errno == EINTR)
+ continue;
+ if (errno == EWOULDBLOCK || errno == EAGAIN)
+ break;
+
+ goto done;
+ }
}
- }
- done:
- igmp_read_on(igmp);
- return 0;
+done:
+ igmp_read_on(igmp);
+ return 0;
}
-static void
-igmp_read_on (struct igmp_sock *igmp)
+static void igmp_read_on(struct igmp_sock *igmp)
{
- if (PIM_DEBUG_IGMP_TRACE_DETAIL) {
- zlog_debug("Scheduling READ event on IGMP socket fd=%d",
- igmp->fd);
- }
- igmp->t_igmp_read = NULL;
- thread_add_read(master, pim_igmp_read, igmp, igmp->fd, &igmp->t_igmp_read);
-
+ if (PIM_DEBUG_IGMP_TRACE_DETAIL) {
+ zlog_debug("Scheduling READ event on IGMP socket fd=%d",
+ igmp->fd);
+ }
+ igmp->t_igmp_read = NULL;
+ thread_add_read(master, pim_igmp_read, igmp, igmp->fd,
+ &igmp->t_igmp_read);
}
struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list,
struct in_addr ifaddr,
struct interface *ifp)
{
- struct pim_interface *pim_ifp;
- struct igmp_sock *igmp;
- int fd;
+ struct pim_interface *pim_ifp;
+ struct igmp_sock *igmp;
+ int fd;
- pim_ifp = ifp->info;
+ pim_ifp = ifp->info;
- fd = igmp_sock_open(ifaddr, ifp, pim_ifp->options);
- if (fd < 0) {
- zlog_warn("Could not open IGMP socket for %s on %s",
- inet_ntoa(ifaddr), ifp->name);
- return 0;
- }
+ fd = igmp_sock_open(ifaddr, ifp, pim_ifp->options);
+ if (fd < 0) {
+ zlog_warn("Could not open IGMP socket for %s on %s",
+ inet_ntoa(ifaddr), ifp->name);
+ return 0;
+ }
- igmp = igmp_sock_new(fd, ifaddr, ifp);
- if (!igmp) {
- zlog_err("%s %s: igmp_sock_new() failure",
- __FILE__, __PRETTY_FUNCTION__);
- close(fd);
- return 0;
- }
+ igmp = igmp_sock_new(fd, ifaddr, ifp);
+ if (!igmp) {
+ zlog_err("%s %s: igmp_sock_new() failure", __FILE__,
+ __PRETTY_FUNCTION__);
+ close(fd);
+ return 0;
+ }
- igmp_read_on (igmp);
+ igmp_read_on(igmp);
- listnode_add(igmp_sock_list, igmp);
+ listnode_add(igmp_sock_list, igmp);
#ifdef IGMP_SOCK_DUMP
- igmp_sock_dump(igmp_sock_array);
+ igmp_sock_dump(igmp_sock_array);
#endif
- return igmp;
+ return igmp;
}
/*
@@ -946,210 +956,203 @@ struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list,
*/
static int igmp_group_timer(struct thread *t)
{
- struct igmp_group *group;
+ struct igmp_group *group;
- group = THREAD_ARG(t);
+ group = THREAD_ARG(t);
- if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- zlog_debug("%s: Timer for group %s on interface %s",
- __PRETTY_FUNCTION__,
- group_str, group->group_igmp_sock->interface->name);
- }
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group->group_addr, group_str,
+ sizeof(group_str));
+ zlog_debug("%s: Timer for group %s on interface %s",
+ __PRETTY_FUNCTION__, group_str,
+ group->group_igmp_sock->interface->name);
+ }
- zassert(group->group_filtermode_isexcl);
+ zassert(group->group_filtermode_isexcl);
- group->group_filtermode_isexcl = 0;
+ group->group_filtermode_isexcl = 0;
- /* Any source (*,G) is forwarded only if mode is EXCLUDE {empty} */
- igmp_anysource_forward_stop(group);
+ /* Any source (*,G) is forwarded only if mode is EXCLUDE {empty} */
+ igmp_anysource_forward_stop(group);
- igmp_source_delete_expired(group->group_source_list);
+ igmp_source_delete_expired(group->group_source_list);
- zassert(!group->group_filtermode_isexcl);
+ zassert(!group->group_filtermode_isexcl);
- /*
- RFC 3376: 6.2.2. Definition of Group Timers
+ /*
+ RFC 3376: 6.2.2. Definition of Group Timers
- If there are no more source records for the group, delete group
- record.
- */
- if (listcount(group->group_source_list) < 1) {
- igmp_group_delete_empty_include(group);
- }
+ If there are no more source records for the group, delete group
+ record.
+ */
+ if (listcount(group->group_source_list) < 1) {
+ igmp_group_delete_empty_include(group);
+ }
- return 0;
+ return 0;
}
static void group_timer_off(struct igmp_group *group)
{
- if (!group->t_group_timer)
- return;
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- zlog_debug("Cancelling TIMER event for group %s on %s",
- group_str, group->group_igmp_sock->interface->name);
- }
- THREAD_OFF(group->t_group_timer);
+ if (!group->t_group_timer)
+ return;
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group->group_addr, group_str,
+ sizeof(group_str));
+ zlog_debug("Cancelling TIMER event for group %s on %s",
+ group_str, group->group_igmp_sock->interface->name);
+ }
+ THREAD_OFF(group->t_group_timer);
}
-void igmp_group_timer_on(struct igmp_group *group,
- long interval_msec, const char *ifname)
+void igmp_group_timer_on(struct igmp_group *group, long interval_msec,
+ const char *ifname)
{
- group_timer_off(group);
-
- if (PIM_DEBUG_IGMP_EVENTS) {
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- zlog_debug("Scheduling %ld.%03ld sec TIMER event for group %s on %s",
- interval_msec / 1000,
- interval_msec % 1000,
- group_str, ifname);
- }
-
- /*
- RFC 3376: 6.2.2. Definition of Group Timers
-
- The group timer is only used when a group is in EXCLUDE mode and
- it represents the time for the *filter-mode* of the group to
- expire and switch to INCLUDE mode.
- */
- zassert(group->group_filtermode_isexcl);
-
- thread_add_timer_msec(master, igmp_group_timer, group, interval_msec,
- &group->t_group_timer);
+ group_timer_off(group);
+
+ if (PIM_DEBUG_IGMP_EVENTS) {
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group->group_addr, group_str,
+ sizeof(group_str));
+ zlog_debug(
+ "Scheduling %ld.%03ld sec TIMER event for group %s on %s",
+ interval_msec / 1000, interval_msec % 1000, group_str,
+ ifname);
+ }
+
+ /*
+ RFC 3376: 6.2.2. Definition of Group Timers
+
+ The group timer is only used when a group is in EXCLUDE mode and
+ it represents the time for the *filter-mode* of the group to
+ expire and switch to INCLUDE mode.
+ */
+ zassert(group->group_filtermode_isexcl);
+
+ thread_add_timer_msec(master, igmp_group_timer, group, interval_msec,
+ &group->t_group_timer);
}
-struct igmp_group *
-find_group_by_addr (struct igmp_sock *igmp,
- struct in_addr group_addr)
+struct igmp_group *find_group_by_addr(struct igmp_sock *igmp,
+ struct in_addr group_addr)
{
- struct igmp_group lookup;
+ struct igmp_group lookup;
- lookup.group_addr.s_addr = group_addr.s_addr;
+ lookup.group_addr.s_addr = group_addr.s_addr;
- return hash_lookup(igmp->igmp_group_hash, &lookup);
+ return hash_lookup(igmp->igmp_group_hash, &lookup);
}
struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp,
struct in_addr group_addr)
{
- struct igmp_group *group;
-
- group = find_group_by_addr(igmp, group_addr);
- if (group) {
- return group;
- }
-
- if (!pim_is_group_224_4 (group_addr))
- {
- zlog_warn("%s: Group Specified is not part of 224.0.0.0/4",
- __PRETTY_FUNCTION__);
- return NULL;
- }
-
- if (pim_is_group_224_0_0_0_24 (group_addr))
- {
- zlog_warn("%s: Group specified is part of 224.0.0.0/24",
- __PRETTY_FUNCTION__);
- return NULL;
- }
- /*
- Non-existant group is created as INCLUDE {empty}:
-
- RFC 3376 - 5.1. Action on Change of Interface State
-
- If no interface state existed for that multicast address before
- the change (i.e., the change consisted of creating a new
- per-interface record), or if no state exists after the change
- (i.e., the change consisted of deleting a per-interface record),
- then the "non-existent" state is considered to have a filter mode
- of INCLUDE and an empty source list.
- */
-
- group = XCALLOC(MTYPE_PIM_IGMP_GROUP, sizeof(*group));
- if (!group) {
- zlog_warn("%s %s: XCALLOC() failure",
- __FILE__, __PRETTY_FUNCTION__);
- return NULL; /* error, not found, could not create */
- }
-
- group->group_source_list = list_new();
- if (!group->group_source_list) {
- zlog_warn("%s %s: list_new() failure",
- __FILE__, __PRETTY_FUNCTION__);
- XFREE(MTYPE_PIM_IGMP_GROUP, group); /* discard group */
- return NULL; /* error, not found, could not initialize */
- }
- group->group_source_list->del = (void (*)(void *)) igmp_source_free;
-
- group->t_group_timer = NULL;
- group->t_group_query_retransmit_timer = NULL;
- group->group_specific_query_retransmit_count = 0;
- group->group_addr = group_addr;
- group->group_igmp_sock = igmp;
- group->last_igmp_v1_report_dsec = -1;
- group->last_igmp_v2_report_dsec = -1;
- group->group_creation = pim_time_monotonic_sec();
- group->igmp_version = IGMP_DEFAULT_VERSION;
-
- /* initialize new group as INCLUDE {empty} */
- group->group_filtermode_isexcl = 0; /* 0=INCLUDE, 1=EXCLUDE */
-
- listnode_add(igmp->igmp_group_list, group);
- group = hash_get (igmp->igmp_group_hash, group, hash_alloc_intern);
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- zlog_debug("Creating new IGMP group %s on socket %d interface %s",
- group_str, igmp->fd, igmp->interface->name);
- }
-
- /*
- RFC 3376: 6.2.2. Definition of Group Timers
-
- The group timer is only used when a group is in EXCLUDE mode and
- it represents the time for the *filter-mode* of the group to
- expire and switch to INCLUDE mode.
- */
- zassert(!group->group_filtermode_isexcl); /* INCLUDE mode */
- zassert(!group->t_group_timer); /* group timer == 0 */
-
- /* Any source (*,G) is forwarded only if mode is EXCLUDE {empty} */
- igmp_anysource_forward_stop(group);
-
- return group;
+ struct igmp_group *group;
+
+ group = find_group_by_addr(igmp, group_addr);
+ if (group) {
+ return group;
+ }
+
+ if (!pim_is_group_224_4(group_addr)) {
+ zlog_warn("%s: Group Specified is not part of 224.0.0.0/4",
+ __PRETTY_FUNCTION__);
+ return NULL;
+ }
+
+ if (pim_is_group_224_0_0_0_24(group_addr)) {
+ zlog_warn("%s: Group specified is part of 224.0.0.0/24",
+ __PRETTY_FUNCTION__);
+ return NULL;
+ }
+ /*
+ Non-existant group is created as INCLUDE {empty}:
+
+ RFC 3376 - 5.1. Action on Change of Interface State
+
+ If no interface state existed for that multicast address before
+ the change (i.e., the change consisted of creating a new
+ per-interface record), or if no state exists after the change
+ (i.e., the change consisted of deleting a per-interface record),
+ then the "non-existent" state is considered to have a filter mode
+ of INCLUDE and an empty source list.
+ */
+
+ group = XCALLOC(MTYPE_PIM_IGMP_GROUP, sizeof(*group));
+ if (!group) {
+ zlog_warn("%s %s: XCALLOC() failure", __FILE__,
+ __PRETTY_FUNCTION__);
+ return NULL; /* error, not found, could not create */
+ }
+
+ group->group_source_list = list_new();
+ if (!group->group_source_list) {
+ zlog_warn("%s %s: list_new() failure", __FILE__,
+ __PRETTY_FUNCTION__);
+ XFREE(MTYPE_PIM_IGMP_GROUP, group); /* discard group */
+ return NULL; /* error, not found, could not initialize */
+ }
+ group->group_source_list->del = (void (*)(void *))igmp_source_free;
+
+ group->t_group_timer = NULL;
+ group->t_group_query_retransmit_timer = NULL;
+ group->group_specific_query_retransmit_count = 0;
+ group->group_addr = group_addr;
+ group->group_igmp_sock = igmp;
+ group->last_igmp_v1_report_dsec = -1;
+ group->last_igmp_v2_report_dsec = -1;
+ group->group_creation = pim_time_monotonic_sec();
+ group->igmp_version = IGMP_DEFAULT_VERSION;
+
+ /* initialize new group as INCLUDE {empty} */
+ group->group_filtermode_isexcl = 0; /* 0=INCLUDE, 1=EXCLUDE */
+
+ listnode_add(igmp->igmp_group_list, group);
+ group = hash_get(igmp->igmp_group_hash, group, hash_alloc_intern);
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group->group_addr, group_str,
+ sizeof(group_str));
+ zlog_debug(
+ "Creating new IGMP group %s on socket %d interface %s",
+ group_str, igmp->fd, igmp->interface->name);
+ }
+
+ /*
+ RFC 3376: 6.2.2. Definition of Group Timers
+
+ The group timer is only used when a group is in EXCLUDE mode and
+ it represents the time for the *filter-mode* of the group to
+ expire and switch to INCLUDE mode.
+ */
+ zassert(!group->group_filtermode_isexcl); /* INCLUDE mode */
+ zassert(!group->t_group_timer); /* group timer == 0 */
+
+ /* Any source (*,G) is forwarded only if mode is EXCLUDE {empty} */
+ igmp_anysource_forward_stop(group);
+
+ return group;
}
-void
-igmp_send_query (int igmp_version,
- struct igmp_group *group,
- int fd,
- const char *ifname,
- char *query_buf,
- int query_buf_size,
- int num_sources,
- struct in_addr dst_addr,
- struct in_addr group_addr,
- int query_max_response_time_dsec,
- uint8_t s_flag,
- uint8_t querier_robustness_variable,
- uint16_t querier_query_interval)
+void igmp_send_query(int igmp_version, struct igmp_group *group, int fd,
+ const char *ifname, char *query_buf, int query_buf_size,
+ int num_sources, struct in_addr dst_addr,
+ struct in_addr group_addr,
+ int query_max_response_time_dsec, uint8_t s_flag,
+ uint8_t querier_robustness_variable,
+ uint16_t querier_query_interval)
{
- if (igmp_version == 3) {
- igmp_v3_send_query (group, fd, ifname, query_buf,
- query_buf_size, num_sources,
- dst_addr, group_addr,
- query_max_response_time_dsec, s_flag,
- querier_robustness_variable,
- querier_query_interval);
- } else if (igmp_version == 2) {
- igmp_v2_send_query (group, fd, ifname, query_buf,
- dst_addr, group_addr,
- query_max_response_time_dsec);
- }
+ if (igmp_version == 3) {
+ igmp_v3_send_query(group, fd, ifname, query_buf, query_buf_size,
+ num_sources, dst_addr, group_addr,
+ query_max_response_time_dsec, s_flag,
+ querier_robustness_variable,
+ querier_query_interval);
+ } else if (igmp_version == 2) {
+ igmp_v2_send_query(group, fd, ifname, query_buf, dst_addr,
+ group_addr, query_max_response_time_dsec);
+ }
}
diff --git a/pimd/pim_igmp.h b/pimd/pim_igmp.h
index 2f36094bd..275f25f63 100644
--- a/pimd/pim_igmp.h
+++ b/pimd/pim_igmp.h
@@ -41,8 +41,8 @@
#define IGMP_V3_REPORT_HEADER_SIZE (8)
#define IGMP_V3_GROUP_RECORD_MIN_SIZE (8)
-#define IGMP_V3_MSG_MIN_SIZE (IGMP_V3_REPORT_HEADER_SIZE + \
- IGMP_V3_GROUP_RECORD_MIN_SIZE)
+#define IGMP_V3_MSG_MIN_SIZE \
+ (IGMP_V3_REPORT_HEADER_SIZE + IGMP_V3_GROUP_RECORD_MIN_SIZE)
#define IGMP_V12_MSG_SIZE (8)
#define IGMP_V3_GROUP_RECORD_TYPE_OFFSET (0)
@@ -67,40 +67,40 @@
#define IGMP_DEFAULT_VERSION (3)
struct igmp_join {
- struct in_addr group_addr;
- struct in_addr source_addr;
- int sock_fd;
- time_t sock_creation;
+ struct in_addr group_addr;
+ struct in_addr source_addr;
+ int sock_fd;
+ time_t sock_creation;
};
struct igmp_sock {
- int fd;
- struct interface *interface;
- struct in_addr ifaddr;
- time_t sock_creation;
-
- struct thread *t_igmp_read; /* read: IGMP sockets */
- struct thread *t_igmp_query_timer; /* timer: issue IGMP general queries */
- struct thread *t_other_querier_timer; /* timer: other querier present */
-
- int querier_query_interval; /* QQI */
- int querier_robustness_variable; /* QRV */
- int startup_query_count;
-
- struct list *igmp_group_list; /* list of struct igmp_group */
- struct hash *igmp_group_hash;
+ int fd;
+ struct interface *interface;
+ struct in_addr ifaddr;
+ time_t sock_creation;
+
+ struct thread *t_igmp_read; /* read: IGMP sockets */
+ struct thread
+ *t_igmp_query_timer; /* timer: issue IGMP general queries */
+ struct thread *t_other_querier_timer; /* timer: other querier present */
+
+ int querier_query_interval; /* QQI */
+ int querier_robustness_variable; /* QRV */
+ int startup_query_count;
+
+ struct list *igmp_group_list; /* list of struct igmp_group */
+ struct hash *igmp_group_hash;
};
struct igmp_sock *pim_igmp_sock_lookup_ifaddr(struct list *igmp_sock_list,
struct in_addr ifaddr);
-struct igmp_sock *igmp_sock_lookup_by_fd(struct list *igmp_sock_list,
- int fd);
+struct igmp_sock *igmp_sock_lookup_by_fd(struct list *igmp_sock_list, int fd);
struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list,
struct in_addr ifaddr,
struct interface *ifp);
void igmp_sock_delete(struct igmp_sock *igmp);
void igmp_sock_free(struct igmp_sock *igmp);
-void igmp_sock_delete_all (struct interface *ifp);
+void igmp_sock_delete_all(struct interface *ifp);
int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len);
void pim_igmp_general_query_on(struct igmp_sock *igmp);
@@ -122,52 +122,53 @@ void pim_igmp_other_querier_timer_off(struct igmp_sock *igmp);
#define IGMP_SOURCE_DONT_SEND(flags) ((flags) &= ~IGMP_SOURCE_MASK_SEND)
struct igmp_source {
- struct in_addr source_addr;
- struct thread *t_source_timer;
- struct igmp_group *source_group; /* back pointer */
- time_t source_creation;
- uint32_t source_flags;
- struct channel_oil *source_channel_oil;
-
- /*
- RFC 3376: 6.6.3.2. Building and Sending Group and Source Specific Queries
- */
- int source_query_retransmit_count;
+ struct in_addr source_addr;
+ struct thread *t_source_timer;
+ struct igmp_group *source_group; /* back pointer */
+ time_t source_creation;
+ uint32_t source_flags;
+ struct channel_oil *source_channel_oil;
+
+ /*
+ RFC 3376: 6.6.3.2. Building and Sending Group and Source Specific
+ Queries
+ */
+ int source_query_retransmit_count;
};
struct igmp_group {
- /*
- RFC 3376: 6.2.2. Definition of Group Timers
-
- The group timer is only used when a group is in EXCLUDE mode and it
- represents the time for the *filter-mode* of the group to expire and
- switch to INCLUDE mode.
- */
- struct thread *t_group_timer;
-
- /* Shared between group-specific and
- group-and-source-specific retransmissions */
- struct thread *t_group_query_retransmit_timer;
-
- /* Counter exclusive for group-specific retransmissions
- (not used by group-and-source-specific retransmissions,
- since sources have their counters) */
- int group_specific_query_retransmit_count;
-
- /* compatibility mode - igmp v1, v2 or v3 */
- int igmp_version;
-
- struct in_addr group_addr;
- int group_filtermode_isexcl; /* 0=INCLUDE, 1=EXCLUDE */
- struct list *group_source_list; /* list of struct igmp_source */
- time_t group_creation;
- struct igmp_sock *group_igmp_sock; /* back pointer */
- int64_t last_igmp_v1_report_dsec;
- int64_t last_igmp_v2_report_dsec;
+ /*
+ RFC 3376: 6.2.2. Definition of Group Timers
+
+ The group timer is only used when a group is in EXCLUDE mode and it
+ represents the time for the *filter-mode* of the group to expire and
+ switch to INCLUDE mode.
+ */
+ struct thread *t_group_timer;
+
+ /* Shared between group-specific and
+ group-and-source-specific retransmissions */
+ struct thread *t_group_query_retransmit_timer;
+
+ /* Counter exclusive for group-specific retransmissions
+ (not used by group-and-source-specific retransmissions,
+ since sources have their counters) */
+ int group_specific_query_retransmit_count;
+
+ /* compatibility mode - igmp v1, v2 or v3 */
+ int igmp_version;
+
+ struct in_addr group_addr;
+ int group_filtermode_isexcl; /* 0=INCLUDE, 1=EXCLUDE */
+ struct list *group_source_list; /* list of struct igmp_source */
+ time_t group_creation;
+ struct igmp_sock *group_igmp_sock; /* back pointer */
+ int64_t last_igmp_v1_report_dsec;
+ int64_t last_igmp_v2_report_dsec;
};
-struct igmp_group *find_group_by_addr (struct igmp_sock *igmp,
- struct in_addr group_addr);
+struct igmp_group *find_group_by_addr(struct igmp_sock *igmp,
+ struct in_addr group_addr);
struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp,
struct in_addr group_addr);
@@ -175,24 +176,17 @@ void igmp_group_delete_empty_include(struct igmp_group *group);
void igmp_startup_mode_on(struct igmp_sock *igmp);
-void igmp_group_timer_on(struct igmp_group *group,
- long interval_msec, const char *ifname);
-
-struct igmp_source *
-source_new (struct igmp_group *group,
- struct in_addr src_addr);
-
-void igmp_send_query(int igmp_version,
- struct igmp_group *group,
- int fd,
- const char *ifname,
- char *query_buf,
- int query_buf_size,
- int num_sources,
- struct in_addr dst_addr,
- struct in_addr group_addr,
- int query_max_response_time_dsec,
- uint8_t s_flag,
- uint8_t querier_robustness_variable,
- uint16_t querier_query_interval);
+void igmp_group_timer_on(struct igmp_group *group, long interval_msec,
+ const char *ifname);
+
+struct igmp_source *source_new(struct igmp_group *group,
+ struct in_addr src_addr);
+
+void igmp_send_query(int igmp_version, struct igmp_group *group, int fd,
+ const char *ifname, char *query_buf, int query_buf_size,
+ int num_sources, struct in_addr dst_addr,
+ struct in_addr group_addr,
+ int query_max_response_time_dsec, uint8_t s_flag,
+ uint8_t querier_robustness_variable,
+ uint16_t querier_query_interval);
#endif /* PIM_IGMP_H */
diff --git a/pimd/pim_igmp_join.h b/pimd/pim_igmp_join.h
index 31fc1b047..abee08006 100644
--- a/pimd/pim_igmp_join.h
+++ b/pimd/pim_igmp_join.h
@@ -28,11 +28,10 @@
#ifndef MCAST_JOIN_SOURCE_GROUP
#define MCAST_JOIN_SOURCE_GROUP 46
-struct group_source_req
-{
- uint32_t gsr_interface;
- struct sockaddr_storage gsr_group;
- struct sockaddr_storage gsr_source;
+struct group_source_req {
+ uint32_t gsr_interface;
+ struct sockaddr_storage gsr_group;
+ struct sockaddr_storage gsr_source;
};
#endif
@@ -40,29 +39,29 @@ static int pim_igmp_join_source(int fd, ifindex_t ifindex,
struct in_addr group_addr,
struct in_addr source_addr)
{
- struct group_source_req req;
- struct sockaddr_in group;
- struct sockaddr_in source;
+ struct group_source_req req;
+ struct sockaddr_in group;
+ struct sockaddr_in source;
- memset(&req, 0, sizeof(req));
- memset(&group, 0, sizeof(group));
- group.sin_family = AF_INET;
- group.sin_addr = group_addr;
- group.sin_port = htons(0);
- memcpy(&req.gsr_group, &group, sizeof(struct sockaddr_in));
+ memset(&req, 0, sizeof(req));
+ memset(&group, 0, sizeof(group));
+ group.sin_family = AF_INET;
+ group.sin_addr = group_addr;
+ group.sin_port = htons(0);
+ memcpy(&req.gsr_group, &group, sizeof(struct sockaddr_in));
- memset(&source, 0, sizeof(source));
- source.sin_family = AF_INET;
- source.sin_addr = source_addr;
- source.sin_port = htons(0);
- memcpy(&req.gsr_source, &source, sizeof(struct sockaddr_in));
+ memset(&source, 0, sizeof(source));
+ source.sin_family = AF_INET;
+ source.sin_addr = source_addr;
+ source.sin_port = htons(0);
+ memcpy(&req.gsr_source, &source, sizeof(struct sockaddr_in));
- req.gsr_interface = ifindex;
+ req.gsr_interface = ifindex;
- return setsockopt(fd, SOL_IP, MCAST_JOIN_SOURCE_GROUP,
- &req, sizeof(req));
+ return setsockopt(fd, SOL_IP, MCAST_JOIN_SOURCE_GROUP, &req,
+ sizeof(req));
- return 0;
+ return 0;
}
#endif /* PIM_IGMP_JOIN_H */
diff --git a/pimd/pim_igmpv2.c b/pimd/pim_igmpv2.c
index d4b3010d3..efa36e618 100644
--- a/pimd/pim_igmpv2.c
+++ b/pimd/pim_igmpv2.c
@@ -29,161 +29,161 @@
#include "pim_util.h"
-static void
-on_trace (const char *label,
- struct interface *ifp, struct in_addr from)
+static void on_trace(const char *label, struct interface *ifp,
+ struct in_addr from)
{
- if (PIM_DEBUG_IGMP_TRACE) {
- char from_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<from?>", from, from_str, sizeof(from_str));
- zlog_debug("%s: from %s on %s",
- label, from_str, ifp->name);
- }
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char from_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<from?>", from, from_str, sizeof(from_str));
+ zlog_debug("%s: from %s on %s", label, from_str, ifp->name);
+ }
}
-void
-igmp_v2_send_query (struct igmp_group *group,
- int fd,
- const char *ifname,
- char *query_buf,
- struct in_addr dst_addr,
- struct in_addr group_addr,
- int query_max_response_time_dsec)
+void igmp_v2_send_query(struct igmp_group *group, int fd, const char *ifname,
+ char *query_buf, struct in_addr dst_addr,
+ struct in_addr group_addr,
+ int query_max_response_time_dsec)
{
- ssize_t msg_size = 8;
- uint8_t max_resp_code;
- ssize_t sent;
- struct sockaddr_in to;
- socklen_t tolen;
- uint16_t checksum;
-
- /* max_resp_code must be non-zero else this will look like an IGMP v1 query */
- max_resp_code = igmp_msg_encode16to8(query_max_response_time_dsec);
- zassert(max_resp_code > 0);
-
- query_buf[0] = PIM_IGMP_MEMBERSHIP_QUERY;
- query_buf[1] = max_resp_code;
- *(uint16_t *)(query_buf + IGMP_CHECKSUM_OFFSET) = 0; /* for computing checksum */
- memcpy(query_buf+4, &group_addr, sizeof(struct in_addr));
-
- checksum = in_cksum(query_buf, msg_size);
- *(uint16_t *)(query_buf + IGMP_CHECKSUM_OFFSET) = checksum;
-
- if (PIM_DEBUG_IGMP_PACKETS) {
- char dst_str[INET_ADDRSTRLEN];
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<dst?>", dst_addr, dst_str, sizeof(dst_str));
- pim_inet4_dump("<group?>", group_addr, group_str, sizeof(group_str));
- zlog_debug("Send IGMPv2 QUERY to %s on %s for group %s",
- dst_str, ifname, group_str);
- }
-
- memset(&to, 0, sizeof(to));
- to.sin_family = AF_INET;
- to.sin_addr = dst_addr;
- tolen = sizeof(to);
-
- sent = sendto(fd, query_buf, msg_size, MSG_DONTWAIT,
- (struct sockaddr *)&to, tolen);
- if (sent != (ssize_t) msg_size) {
- char dst_str[INET_ADDRSTRLEN];
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<dst?>", dst_addr, dst_str, sizeof(dst_str));
- pim_inet4_dump("<group?>", group_addr, group_str, sizeof(group_str));
- if (sent < 0) {
- zlog_warn("Send IGMPv2 QUERY failed due to %s on %s: group=%s msg_size=%zd: errno=%d: %s",
- dst_str, ifname, group_str, msg_size, errno, safe_strerror(errno));
- }
- else {
- zlog_warn("Send IGMPv2 QUERY failed due to %s on %s: group=%s msg_size=%zd: sent=%zd",
- dst_str, ifname, group_str, msg_size, sent);
- }
- return;
- }
+ ssize_t msg_size = 8;
+ uint8_t max_resp_code;
+ ssize_t sent;
+ struct sockaddr_in to;
+ socklen_t tolen;
+ uint16_t checksum;
+
+ /* max_resp_code must be non-zero else this will look like an IGMP v1
+ * query */
+ max_resp_code = igmp_msg_encode16to8(query_max_response_time_dsec);
+ zassert(max_resp_code > 0);
+
+ query_buf[0] = PIM_IGMP_MEMBERSHIP_QUERY;
+ query_buf[1] = max_resp_code;
+ *(uint16_t *)(query_buf + IGMP_CHECKSUM_OFFSET) =
+ 0; /* for computing checksum */
+ memcpy(query_buf + 4, &group_addr, sizeof(struct in_addr));
+
+ checksum = in_cksum(query_buf, msg_size);
+ *(uint16_t *)(query_buf + IGMP_CHECKSUM_OFFSET) = checksum;
+
+ if (PIM_DEBUG_IGMP_PACKETS) {
+ char dst_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<dst?>", dst_addr, dst_str, sizeof(dst_str));
+ pim_inet4_dump("<group?>", group_addr, group_str,
+ sizeof(group_str));
+ zlog_debug("Send IGMPv2 QUERY to %s on %s for group %s",
+ dst_str, ifname, group_str);
+ }
+
+ memset(&to, 0, sizeof(to));
+ to.sin_family = AF_INET;
+ to.sin_addr = dst_addr;
+ tolen = sizeof(to);
+
+ sent = sendto(fd, query_buf, msg_size, MSG_DONTWAIT,
+ (struct sockaddr *)&to, tolen);
+ if (sent != (ssize_t)msg_size) {
+ char dst_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<dst?>", dst_addr, dst_str, sizeof(dst_str));
+ pim_inet4_dump("<group?>", group_addr, group_str,
+ sizeof(group_str));
+ if (sent < 0) {
+ zlog_warn(
+ "Send IGMPv2 QUERY failed due to %s on %s: group=%s msg_size=%zd: errno=%d: %s",
+ dst_str, ifname, group_str, msg_size, errno,
+ safe_strerror(errno));
+ } else {
+ zlog_warn(
+ "Send IGMPv2 QUERY failed due to %s on %s: group=%s msg_size=%zd: sent=%zd",
+ dst_str, ifname, group_str, msg_size, sent);
+ }
+ return;
+ }
}
-int
-igmp_v2_recv_report (struct igmp_sock *igmp,
- struct in_addr from, const char *from_str,
- char *igmp_msg, int igmp_msg_len)
+int igmp_v2_recv_report(struct igmp_sock *igmp, struct in_addr from,
+ const char *from_str, char *igmp_msg, int igmp_msg_len)
{
- struct interface *ifp = igmp->interface;
- struct in_addr group_addr;
- char group_str[INET_ADDRSTRLEN];
-
- on_trace(__PRETTY_FUNCTION__, igmp->interface, from);
-
- if (igmp_msg_len != IGMP_V12_MSG_SIZE) {
- zlog_warn("Recv IGMPv2 REPORT from %s on %s: size=%d other than correct=%d",
- from_str, ifp->name, igmp_msg_len, IGMP_V12_MSG_SIZE);
- return -1;
- }
-
- memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
-
- if (PIM_DEBUG_IGMP_PACKETS) {
- pim_inet4_dump("<dst?>", group_addr, group_str, sizeof(group_str));
- zlog_debug("Recv IGMPv2 REPORT from %s on %s for %s",
- from_str, ifp->name, group_str);
- }
-
- /*
- * RFC 3376
- * 7.3.2. In the Presence of Older Version Group Members
- *
- * When Group Compatibility Mode is IGMPv2, a router internally
- * translates the following IGMPv2 messages for that group to their
- * IGMPv3 equivalents:
- *
- * IGMPv2 Message IGMPv3 Equivalent
- * -------------- -----------------
- * Report IS_EX( {} )
- * Leave TO_IN( {} )
- */
- igmpv3_report_isex (igmp, from, group_addr, 0, NULL, 1);
-
- return 0;
+ struct interface *ifp = igmp->interface;
+ struct in_addr group_addr;
+ char group_str[INET_ADDRSTRLEN];
+
+ on_trace(__PRETTY_FUNCTION__, igmp->interface, from);
+
+ if (igmp_msg_len != IGMP_V12_MSG_SIZE) {
+ zlog_warn(
+ "Recv IGMPv2 REPORT from %s on %s: size=%d other than correct=%d",
+ from_str, ifp->name, igmp_msg_len, IGMP_V12_MSG_SIZE);
+ return -1;
+ }
+
+ memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
+
+ if (PIM_DEBUG_IGMP_PACKETS) {
+ pim_inet4_dump("<dst?>", group_addr, group_str,
+ sizeof(group_str));
+ zlog_debug("Recv IGMPv2 REPORT from %s on %s for %s", from_str,
+ ifp->name, group_str);
+ }
+
+ /*
+ * RFC 3376
+ * 7.3.2. In the Presence of Older Version Group Members
+ *
+ * When Group Compatibility Mode is IGMPv2, a router internally
+ * translates the following IGMPv2 messages for that group to their
+ * IGMPv3 equivalents:
+ *
+ * IGMPv2 Message IGMPv3 Equivalent
+ * -------------- -----------------
+ * Report IS_EX( {} )
+ * Leave TO_IN( {} )
+ */
+ igmpv3_report_isex(igmp, from, group_addr, 0, NULL, 1);
+
+ return 0;
}
-int
-igmp_v2_recv_leave (struct igmp_sock *igmp,
- struct in_addr from, const char *from_str,
- char *igmp_msg, int igmp_msg_len)
+int igmp_v2_recv_leave(struct igmp_sock *igmp, struct in_addr from,
+ const char *from_str, char *igmp_msg, int igmp_msg_len)
{
- struct interface *ifp = igmp->interface;
- struct in_addr group_addr;
- char group_str[INET_ADDRSTRLEN];
-
- on_trace(__PRETTY_FUNCTION__, igmp->interface, from);
-
- if (igmp_msg_len != IGMP_V12_MSG_SIZE) {
- zlog_warn("Recv IGMPv2 LEAVE from %s on %s: size=%d other than correct=%d",
- from_str, ifp->name, igmp_msg_len, IGMP_V12_MSG_SIZE);
- return -1;
- }
-
- memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
-
- if (PIM_DEBUG_IGMP_PACKETS) {
- pim_inet4_dump("<dst?>", group_addr, group_str, sizeof(group_str));
- zlog_debug("Recv IGMPv2 LEAVE from %s on %s for %s",
- from_str, ifp->name, group_str);
- }
-
- /*
- * RFC 3376
- * 7.3.2. In the Presence of Older Version Group Members
- *
- * When Group Compatibility Mode is IGMPv2, a router internally
- * translates the following IGMPv2 messages for that group to their
- * IGMPv3 equivalents:
- *
- * IGMPv2 Message IGMPv3 Equivalent
- * -------------- -----------------
- * Report IS_EX( {} )
- * Leave TO_IN( {} )
- */
- igmpv3_report_toin (igmp, from, group_addr, 0, NULL);
-
- return 0;
+ struct interface *ifp = igmp->interface;
+ struct in_addr group_addr;
+ char group_str[INET_ADDRSTRLEN];
+
+ on_trace(__PRETTY_FUNCTION__, igmp->interface, from);
+
+ if (igmp_msg_len != IGMP_V12_MSG_SIZE) {
+ zlog_warn(
+ "Recv IGMPv2 LEAVE from %s on %s: size=%d other than correct=%d",
+ from_str, ifp->name, igmp_msg_len, IGMP_V12_MSG_SIZE);
+ return -1;
+ }
+
+ memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
+
+ if (PIM_DEBUG_IGMP_PACKETS) {
+ pim_inet4_dump("<dst?>", group_addr, group_str,
+ sizeof(group_str));
+ zlog_debug("Recv IGMPv2 LEAVE from %s on %s for %s", from_str,
+ ifp->name, group_str);
+ }
+
+ /*
+ * RFC 3376
+ * 7.3.2. In the Presence of Older Version Group Members
+ *
+ * When Group Compatibility Mode is IGMPv2, a router internally
+ * translates the following IGMPv2 messages for that group to their
+ * IGMPv3 equivalents:
+ *
+ * IGMPv2 Message IGMPv3 Equivalent
+ * -------------- -----------------
+ * Report IS_EX( {} )
+ * Leave TO_IN( {} )
+ */
+ igmpv3_report_toin(igmp, from, group_addr, 0, NULL);
+
+ return 0;
}
diff --git a/pimd/pim_igmpv2.h b/pimd/pim_igmpv2.h
index fa8d16394..f0a6fdc5f 100644
--- a/pimd/pim_igmpv2.h
+++ b/pimd/pim_igmpv2.h
@@ -21,20 +21,15 @@
#ifndef PIM_IGMPV2_H
#define PIM_IGMPV2_H
-void igmp_v2_send_query (struct igmp_group *group,
- int fd,
- const char *ifname,
- char *query_buf,
- struct in_addr dst_addr,
- struct in_addr group_addr,
- int query_max_response_time_dsec);
+void igmp_v2_send_query(struct igmp_group *group, int fd, const char *ifname,
+ char *query_buf, struct in_addr dst_addr,
+ struct in_addr group_addr,
+ int query_max_response_time_dsec);
-int igmp_v2_recv_report (struct igmp_sock *igmp,
- struct in_addr from, const char *from_str,
- char *igmp_msg, int igmp_msg_len);
+int igmp_v2_recv_report(struct igmp_sock *igmp, struct in_addr from,
+ const char *from_str, char *igmp_msg, int igmp_msg_len);
-int igmp_v2_recv_leave (struct igmp_sock *igmp,
- struct in_addr from, const char *from_str,
- char *igmp_msg, int igmp_msg_len);
+int igmp_v2_recv_leave(struct igmp_sock *igmp, struct in_addr from,
+ const char *from_str, char *igmp_msg, int igmp_msg_len);
#endif /* PIM_IGMPV2_H */
diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c
index ad37ad876..880d840ea 100644
--- a/pimd/pim_igmpv3.c
+++ b/pimd/pim_igmpv3.c
@@ -39,269 +39,270 @@ static void group_query_send(struct igmp_group *group);
static void source_query_send_by_flag(struct igmp_group *group,
int num_sources_tosend);
-static void on_trace(const char *label,
- struct interface *ifp, struct in_addr from,
- struct in_addr group_addr,
+static void on_trace(const char *label, struct interface *ifp,
+ struct in_addr from, struct in_addr group_addr,
int num_sources, struct in_addr *sources)
{
- if (PIM_DEBUG_IGMP_TRACE) {
- char from_str[INET_ADDRSTRLEN];
- char group_str[INET_ADDRSTRLEN];
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char from_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<from?>", from, from_str, sizeof(from_str));
- pim_inet4_dump("<group?>", group_addr, group_str, sizeof(group_str));
+ pim_inet4_dump("<from?>", from, from_str, sizeof(from_str));
+ pim_inet4_dump("<group?>", group_addr, group_str,
+ sizeof(group_str));
- zlog_debug("%s: from %s on %s: group=%s sources=%d",
- label, from_str, ifp->name, group_str, num_sources);
- }
+ zlog_debug("%s: from %s on %s: group=%s sources=%d", label,
+ from_str, ifp->name, group_str, num_sources);
+ }
}
void igmp_group_reset_gmi(struct igmp_group *group)
{
- long group_membership_interval_msec;
- struct pim_interface *pim_ifp;
- struct igmp_sock *igmp;
- struct interface *ifp;
-
- igmp = group->group_igmp_sock;
- ifp = igmp->interface;
- pim_ifp = ifp->info;
-
- /*
- RFC 3376: 8.4. Group Membership Interval
-
- The Group Membership Interval is the amount of time that must pass
- before a multicast router decides there are no more members of a
- group or a particular source on a network.
-
- This value MUST be ((the Robustness Variable) times (the Query
- Interval)) plus (one Query Response Interval).
-
- group_membership_interval_msec = querier_robustness_variable *
- (1000 * querier_query_interval) +
- 100 * query_response_interval_dsec;
- */
- group_membership_interval_msec =
- PIM_IGMP_GMI_MSEC(igmp->querier_robustness_variable,
- igmp->querier_query_interval,
- pim_ifp->igmp_query_max_response_time_dsec);
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- zlog_debug("Resetting group %s timer to GMI=%ld.%03ld sec on %s",
- group_str,
- group_membership_interval_msec / 1000,
- group_membership_interval_msec % 1000,
- ifp->name);
- }
-
- /*
- RFC 3376: 6.2.2. Definition of Group Timers
-
- The group timer is only used when a group is in EXCLUDE mode and
- it represents the time for the *filter-mode* of the group to
- expire and switch to INCLUDE mode.
- */
- zassert(group->group_filtermode_isexcl);
-
- igmp_group_timer_on(group, group_membership_interval_msec, ifp->name);
+ long group_membership_interval_msec;
+ struct pim_interface *pim_ifp;
+ struct igmp_sock *igmp;
+ struct interface *ifp;
+
+ igmp = group->group_igmp_sock;
+ ifp = igmp->interface;
+ pim_ifp = ifp->info;
+
+ /*
+ RFC 3376: 8.4. Group Membership Interval
+
+ The Group Membership Interval is the amount of time that must pass
+ before a multicast router decides there are no more members of a
+ group or a particular source on a network.
+
+ This value MUST be ((the Robustness Variable) times (the Query
+ Interval)) plus (one Query Response Interval).
+
+ group_membership_interval_msec = querier_robustness_variable *
+ (1000 * querier_query_interval) +
+ 100 * query_response_interval_dsec;
+ */
+ group_membership_interval_msec = PIM_IGMP_GMI_MSEC(
+ igmp->querier_robustness_variable, igmp->querier_query_interval,
+ pim_ifp->igmp_query_max_response_time_dsec);
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group->group_addr, group_str,
+ sizeof(group_str));
+ zlog_debug(
+ "Resetting group %s timer to GMI=%ld.%03ld sec on %s",
+ group_str, group_membership_interval_msec / 1000,
+ group_membership_interval_msec % 1000, ifp->name);
+ }
+
+ /*
+ RFC 3376: 6.2.2. Definition of Group Timers
+
+ The group timer is only used when a group is in EXCLUDE mode and
+ it represents the time for the *filter-mode* of the group to
+ expire and switch to INCLUDE mode.
+ */
+ zassert(group->group_filtermode_isexcl);
+
+ igmp_group_timer_on(group, group_membership_interval_msec, ifp->name);
}
static int igmp_source_timer(struct thread *t)
{
- struct igmp_source *source;
- struct igmp_group *group;
-
- source = THREAD_ARG(t);
-
- group = source->source_group;
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
- zlog_debug("%s: Source timer expired for group %s source %s on %s",
- __PRETTY_FUNCTION__,
- group_str, source_str,
- group->group_igmp_sock->interface->name);
- }
-
- /*
- RFC 3376: 6.3. IGMPv3 Source-Specific Forwarding Rules
-
- Group
- Filter-Mode Source Timer Value Action
- ----------- ------------------ ------
- INCLUDE TIMER == 0 Suggest to stop forwarding
- traffic from source and
- remove source record. If
- there are no more source
- records for the group, delete
- group record.
-
- EXCLUDE TIMER == 0 Suggest to not forward
- traffic from source
- (DO NOT remove record)
-
- Source timer switched from (T > 0) to (T == 0): disable forwarding.
- */
-
- if (group->group_filtermode_isexcl) {
- /* EXCLUDE mode */
-
- igmp_source_forward_stop(source);
- }
- else {
- /* INCLUDE mode */
-
- /* igmp_source_delete() will stop forwarding source */
- igmp_source_delete(source);
-
- /*
- If there are no more source records for the group, delete group
- record.
- */
- if (!listcount(group->group_source_list)) {
- igmp_group_delete_empty_include(group);
- }
- }
-
- return 0;
+ struct igmp_source *source;
+ struct igmp_group *group;
+
+ source = THREAD_ARG(t);
+
+ group = source->source_group;
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group->group_addr, group_str,
+ sizeof(group_str));
+ pim_inet4_dump("<source?>", source->source_addr, source_str,
+ sizeof(source_str));
+ zlog_debug(
+ "%s: Source timer expired for group %s source %s on %s",
+ __PRETTY_FUNCTION__, group_str, source_str,
+ group->group_igmp_sock->interface->name);
+ }
+
+ /*
+ RFC 3376: 6.3. IGMPv3 Source-Specific Forwarding Rules
+
+ Group
+ Filter-Mode Source Timer Value Action
+ ----------- ------------------ ------
+ INCLUDE TIMER == 0 Suggest to stop forwarding
+ traffic from source and
+ remove source record. If
+ there are no more source
+ records for the group, delete
+ group record.
+
+ EXCLUDE TIMER == 0 Suggest to not forward
+ traffic from source
+ (DO NOT remove record)
+
+ Source timer switched from (T > 0) to (T == 0): disable forwarding.
+ */
+
+ if (group->group_filtermode_isexcl) {
+ /* EXCLUDE mode */
+
+ igmp_source_forward_stop(source);
+ } else {
+ /* INCLUDE mode */
+
+ /* igmp_source_delete() will stop forwarding source */
+ igmp_source_delete(source);
+
+ /*
+ If there are no more source records for the group, delete
+ group
+ record.
+ */
+ if (!listcount(group->group_source_list)) {
+ igmp_group_delete_empty_include(group);
+ }
+ }
+
+ return 0;
}
static void source_timer_off(struct igmp_group *group,
struct igmp_source *source)
{
- if (!source->t_source_timer)
- return;
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
- zlog_debug("Cancelling TIMER event for group %s source %s on %s",
- group_str, source_str,
- group->group_igmp_sock->interface->name);
- }
-
- THREAD_OFF(source->t_source_timer);
+ if (!source->t_source_timer)
+ return;
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group->group_addr, group_str,
+ sizeof(group_str));
+ pim_inet4_dump("<source?>", source->source_addr, source_str,
+ sizeof(source_str));
+ zlog_debug(
+ "Cancelling TIMER event for group %s source %s on %s",
+ group_str, source_str,
+ group->group_igmp_sock->interface->name);
+ }
+
+ THREAD_OFF(source->t_source_timer);
}
static void igmp_source_timer_on(struct igmp_group *group,
- struct igmp_source *source,
- long interval_msec)
+ struct igmp_source *source, long interval_msec)
{
- source_timer_off(group, source);
-
- if (PIM_DEBUG_IGMP_EVENTS) {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
- zlog_debug("Scheduling %ld.%03ld sec TIMER event for group %s source %s on %s",
- interval_msec / 1000,
- interval_msec % 1000,
- group_str, source_str,
- group->group_igmp_sock->interface->name);
- }
-
- thread_add_timer_msec(master, igmp_source_timer, source, interval_msec,
- &source->t_source_timer);
-
- /*
- RFC 3376: 6.3. IGMPv3 Source-Specific Forwarding Rules
-
- Source timer switched from (T == 0) to (T > 0): enable forwarding.
- */
- igmp_source_forward_start(source);
+ source_timer_off(group, source);
+
+ if (PIM_DEBUG_IGMP_EVENTS) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group->group_addr, group_str,
+ sizeof(group_str));
+ pim_inet4_dump("<source?>", source->source_addr, source_str,
+ sizeof(source_str));
+ zlog_debug(
+ "Scheduling %ld.%03ld sec TIMER event for group %s source %s on %s",
+ interval_msec / 1000, interval_msec % 1000, group_str,
+ source_str, group->group_igmp_sock->interface->name);
+ }
+
+ thread_add_timer_msec(master, igmp_source_timer, source, interval_msec,
+ &source->t_source_timer);
+
+ /*
+ RFC 3376: 6.3. IGMPv3 Source-Specific Forwarding Rules
+
+ Source timer switched from (T == 0) to (T > 0): enable forwarding.
+ */
+ igmp_source_forward_start(source);
}
-void igmp_source_reset_gmi(struct igmp_sock *igmp,
- struct igmp_group *group,
+void igmp_source_reset_gmi(struct igmp_sock *igmp, struct igmp_group *group,
struct igmp_source *source)
{
- long group_membership_interval_msec;
- struct pim_interface *pim_ifp;
- struct interface *ifp;
-
- ifp = igmp->interface;
- pim_ifp = ifp->info;
-
- group_membership_interval_msec =
- PIM_IGMP_GMI_MSEC(igmp->querier_robustness_variable,
- igmp->querier_query_interval,
- pim_ifp->igmp_query_max_response_time_dsec);
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
-
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
-
- zlog_debug("Resetting source %s timer to GMI=%ld.%03ld sec for group %s on %s",
- source_str,
- group_membership_interval_msec / 1000,
- group_membership_interval_msec % 1000,
- group_str,
- ifp->name);
- }
-
- igmp_source_timer_on(group, source,
- group_membership_interval_msec);
+ long group_membership_interval_msec;
+ struct pim_interface *pim_ifp;
+ struct interface *ifp;
+
+ ifp = igmp->interface;
+ pim_ifp = ifp->info;
+
+ group_membership_interval_msec = PIM_IGMP_GMI_MSEC(
+ igmp->querier_robustness_variable, igmp->querier_query_interval,
+ pim_ifp->igmp_query_max_response_time_dsec);
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+
+ pim_inet4_dump("<group?>", group->group_addr, group_str,
+ sizeof(group_str));
+ pim_inet4_dump("<source?>", source->source_addr, source_str,
+ sizeof(source_str));
+
+ zlog_debug(
+ "Resetting source %s timer to GMI=%ld.%03ld sec for group %s on %s",
+ source_str, group_membership_interval_msec / 1000,
+ group_membership_interval_msec % 1000, group_str,
+ ifp->name);
+ }
+
+ igmp_source_timer_on(group, source, group_membership_interval_msec);
}
static void source_mark_delete_flag(struct igmp_group *group)
{
- struct listnode *src_node;
- struct igmp_source *src;
+ struct listnode *src_node;
+ struct igmp_source *src;
- for (ALL_LIST_ELEMENTS_RO (group->group_source_list, src_node, src)) {
- IGMP_SOURCE_DO_DELETE(src->source_flags);
- }
+ for (ALL_LIST_ELEMENTS_RO(group->group_source_list, src_node, src)) {
+ IGMP_SOURCE_DO_DELETE(src->source_flags);
+ }
}
-static void source_mark_send_flag (struct igmp_group *group)
+static void source_mark_send_flag(struct igmp_group *group)
{
- struct listnode *src_node;
- struct igmp_source *src;
+ struct listnode *src_node;
+ struct igmp_source *src;
- for (ALL_LIST_ELEMENTS_RO (group->group_source_list, src_node, src)) {
- IGMP_SOURCE_DO_SEND(src->source_flags);
- }
+ for (ALL_LIST_ELEMENTS_RO(group->group_source_list, src_node, src)) {
+ IGMP_SOURCE_DO_SEND(src->source_flags);
+ }
}
-static int source_mark_send_flag_by_timer (struct igmp_group *group)
+static int source_mark_send_flag_by_timer(struct igmp_group *group)
{
- struct listnode *src_node;
- struct igmp_source *src;
- int num_marked_sources = 0;
-
- for (ALL_LIST_ELEMENTS_RO(group->group_source_list, src_node, src)) {
- /* Is source timer running? */
- if (src->t_source_timer) {
- IGMP_SOURCE_DO_SEND(src->source_flags);
- ++num_marked_sources;
- }
- else {
- IGMP_SOURCE_DONT_SEND(src->source_flags);
- }
- }
-
- return num_marked_sources;
+ struct listnode *src_node;
+ struct igmp_source *src;
+ int num_marked_sources = 0;
+
+ for (ALL_LIST_ELEMENTS_RO(group->group_source_list, src_node, src)) {
+ /* Is source timer running? */
+ if (src->t_source_timer) {
+ IGMP_SOURCE_DO_SEND(src->source_flags);
+ ++num_marked_sources;
+ } else {
+ IGMP_SOURCE_DONT_SEND(src->source_flags);
+ }
+ }
+
+ return num_marked_sources;
}
static void source_clear_send_flag(struct list *source_list)
{
- struct listnode *src_node;
- struct igmp_source *src;
+ struct listnode *src_node;
+ struct igmp_source *src;
- for (ALL_LIST_ELEMENTS_RO(source_list, src_node, src)) {
- IGMP_SOURCE_DONT_SEND(src->source_flags);
- }
+ for (ALL_LIST_ELEMENTS_RO(source_list, src_node, src)) {
+ IGMP_SOURCE_DONT_SEND(src->source_flags);
+ }
}
/*
@@ -309,27 +310,27 @@ static void source_clear_send_flag(struct list *source_list)
*/
static void group_exclude_fwd_anysrc_ifempty(struct igmp_group *group)
{
- zassert(group->group_filtermode_isexcl);
+ zassert(group->group_filtermode_isexcl);
- if (listcount(group->group_source_list) < 1) {
- igmp_anysource_forward_start(group);
- }
+ if (listcount(group->group_source_list) < 1) {
+ igmp_anysource_forward_start(group);
+ }
}
void igmp_source_free(struct igmp_source *source)
{
- /* make sure there is no source timer running */
- zassert(!source->t_source_timer);
+ /* make sure there is no source timer running */
+ zassert(!source->t_source_timer);
- XFREE(MTYPE_PIM_IGMP_GROUP_SOURCE, source);
+ XFREE(MTYPE_PIM_IGMP_GROUP_SOURCE, source);
}
static void source_channel_oil_detach(struct igmp_source *source)
{
- if (source->source_channel_oil) {
- pim_channel_oil_del(source->source_channel_oil);
- source->source_channel_oil = NULL;
- }
+ if (source->source_channel_oil) {
+ pim_channel_oil_del(source->source_channel_oil);
+ source->source_channel_oil = NULL;
+ }
}
/*
@@ -338,662 +339,659 @@ static void source_channel_oil_detach(struct igmp_source *source)
*/
void igmp_source_delete(struct igmp_source *source)
{
- struct igmp_group *group;
- struct in_addr src;
-
- group = source->source_group;
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
- zlog_debug("Deleting IGMP source %s for group %s from socket %d interface %s c_oil ref_count %d",
- source_str, group_str,
- group->group_igmp_sock->fd,
- group->group_igmp_sock->interface->name,
- source->source_channel_oil ? source->source_channel_oil->oil_ref_count : 0);
- }
-
- source_timer_off(group, source);
- igmp_source_forward_stop(source);
-
- /* sanity check that forwarding has been disabled */
- if (IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
- zlog_warn("%s: forwarding=ON(!) IGMP source %s for group %s from socket %d interface %s",
- __PRETTY_FUNCTION__,
- source_str, group_str,
- group->group_igmp_sock->fd,
- group->group_igmp_sock->interface->name);
- /* warning only */
- }
-
- source_channel_oil_detach(source);
-
- /*
- notice that listnode_delete() can't be moved
- into igmp_source_free() because the later is
- called by list_delete_all_node()
- */
- listnode_delete(group->group_source_list, source);
-
- src.s_addr = source->source_addr.s_addr;
- igmp_source_free(source);
-
- /* Group source list is empty and current source is * then
- *,G group going away so do not trigger start */
- if (group->group_filtermode_isexcl &&
- (listcount (group->group_source_list) != 0) &&
- src.s_addr != INADDR_ANY)
- {
- group_exclude_fwd_anysrc_ifempty (group);
- }
+ struct igmp_group *group;
+ struct in_addr src;
+
+ group = source->source_group;
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group->group_addr, group_str,
+ sizeof(group_str));
+ pim_inet4_dump("<source?>", source->source_addr, source_str,
+ sizeof(source_str));
+ zlog_debug(
+ "Deleting IGMP source %s for group %s from socket %d interface %s c_oil ref_count %d",
+ source_str, group_str, group->group_igmp_sock->fd,
+ group->group_igmp_sock->interface->name,
+ source->source_channel_oil
+ ? source->source_channel_oil->oil_ref_count
+ : 0);
+ }
+
+ source_timer_off(group, source);
+ igmp_source_forward_stop(source);
+
+ /* sanity check that forwarding has been disabled */
+ if (IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group->group_addr, group_str,
+ sizeof(group_str));
+ pim_inet4_dump("<source?>", source->source_addr, source_str,
+ sizeof(source_str));
+ zlog_warn(
+ "%s: forwarding=ON(!) IGMP source %s for group %s from socket %d interface %s",
+ __PRETTY_FUNCTION__, source_str, group_str,
+ group->group_igmp_sock->fd,
+ group->group_igmp_sock->interface->name);
+ /* warning only */
+ }
+
+ source_channel_oil_detach(source);
+
+ /*
+ notice that listnode_delete() can't be moved
+ into igmp_source_free() because the later is
+ called by list_delete_all_node()
+ */
+ listnode_delete(group->group_source_list, source);
+
+ src.s_addr = source->source_addr.s_addr;
+ igmp_source_free(source);
+
+ /* Group source list is empty and current source is * then
+ *,G group going away so do not trigger start */
+ if (group->group_filtermode_isexcl
+ && (listcount(group->group_source_list) != 0)
+ && src.s_addr != INADDR_ANY) {
+ group_exclude_fwd_anysrc_ifempty(group);
+ }
}
static void source_delete_by_flag(struct list *source_list)
{
- struct listnode *src_node;
- struct listnode *src_nextnode;
- struct igmp_source *src;
-
- for (ALL_LIST_ELEMENTS(source_list, src_node, src_nextnode, src))
- if (IGMP_SOURCE_TEST_DELETE(src->source_flags))
- igmp_source_delete(src);
+ struct listnode *src_node;
+ struct listnode *src_nextnode;
+ struct igmp_source *src;
+
+ for (ALL_LIST_ELEMENTS(source_list, src_node, src_nextnode, src))
+ if (IGMP_SOURCE_TEST_DELETE(src->source_flags))
+ igmp_source_delete(src);
}
void igmp_source_delete_expired(struct list *source_list)
{
- struct listnode *src_node;
- struct listnode *src_nextnode;
- struct igmp_source *src;
-
- for (ALL_LIST_ELEMENTS(source_list, src_node, src_nextnode, src))
- if (!src->t_source_timer)
- igmp_source_delete(src);
+ struct listnode *src_node;
+ struct listnode *src_nextnode;
+ struct igmp_source *src;
+
+ for (ALL_LIST_ELEMENTS(source_list, src_node, src_nextnode, src))
+ if (!src->t_source_timer)
+ igmp_source_delete(src);
}
struct igmp_source *igmp_find_source_by_addr(struct igmp_group *group,
struct in_addr src_addr)
{
- struct listnode *src_node;
- struct igmp_source *src;
+ struct listnode *src_node;
+ struct igmp_source *src;
- for (ALL_LIST_ELEMENTS_RO(group->group_source_list, src_node, src))
- if (src_addr.s_addr == src->source_addr.s_addr)
- return src;
+ for (ALL_LIST_ELEMENTS_RO(group->group_source_list, src_node, src))
+ if (src_addr.s_addr == src->source_addr.s_addr)
+ return src;
- return 0;
+ return 0;
}
-struct igmp_source *
-source_new (struct igmp_group *group,
- struct in_addr src_addr)
+struct igmp_source *source_new(struct igmp_group *group,
+ struct in_addr src_addr)
{
- struct igmp_source *src;
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", src_addr, source_str, sizeof(source_str));
- zlog_debug("Creating new IGMP source %s for group %s on socket %d interface %s",
- source_str, group_str,
- group->group_igmp_sock->fd,
- group->group_igmp_sock->interface->name);
- }
-
- src = XCALLOC(MTYPE_PIM_IGMP_GROUP_SOURCE, sizeof(*src));
- if (!src) {
- zlog_warn("%s %s: XCALLOC() failure",
- __FILE__, __PRETTY_FUNCTION__);
- return 0; /* error, not found, could not create */
- }
-
- src->t_source_timer = NULL;
- src->source_group = group; /* back pointer */
- src->source_addr = src_addr;
- src->source_creation = pim_time_monotonic_sec();
- src->source_flags = 0;
- src->source_query_retransmit_count = 0;
- src->source_channel_oil = NULL;
-
- listnode_add(group->group_source_list, src);
-
- /* Any source (*,G) is forwarded only if mode is EXCLUDE {empty} */
- igmp_anysource_forward_stop(group);
-
- return src;
+ struct igmp_source *src;
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group->group_addr, group_str,
+ sizeof(group_str));
+ pim_inet4_dump("<source?>", src_addr, source_str,
+ sizeof(source_str));
+ zlog_debug(
+ "Creating new IGMP source %s for group %s on socket %d interface %s",
+ source_str, group_str, group->group_igmp_sock->fd,
+ group->group_igmp_sock->interface->name);
+ }
+
+ src = XCALLOC(MTYPE_PIM_IGMP_GROUP_SOURCE, sizeof(*src));
+ if (!src) {
+ zlog_warn("%s %s: XCALLOC() failure", __FILE__,
+ __PRETTY_FUNCTION__);
+ return 0; /* error, not found, could not create */
+ }
+
+ src->t_source_timer = NULL;
+ src->source_group = group; /* back pointer */
+ src->source_addr = src_addr;
+ src->source_creation = pim_time_monotonic_sec();
+ src->source_flags = 0;
+ src->source_query_retransmit_count = 0;
+ src->source_channel_oil = NULL;
+
+ listnode_add(group->group_source_list, src);
+
+ /* Any source (*,G) is forwarded only if mode is EXCLUDE {empty} */
+ igmp_anysource_forward_stop(group);
+
+ return src;
}
static struct igmp_source *add_source_by_addr(struct igmp_sock *igmp,
struct igmp_group *group,
struct in_addr src_addr)
{
- struct igmp_source *src;
+ struct igmp_source *src;
- src = igmp_find_source_by_addr(group, src_addr);
- if (src) {
- return src;
- }
+ src = igmp_find_source_by_addr(group, src_addr);
+ if (src) {
+ return src;
+ }
- src = source_new(group, src_addr);
- if (!src) {
- return 0;
- }
+ src = source_new(group, src_addr);
+ if (!src) {
+ return 0;
+ }
- return src;
+ return src;
}
static void allow(struct igmp_sock *igmp, struct in_addr from,
- struct in_addr group_addr,
- int num_sources, struct in_addr *sources)
+ struct in_addr group_addr, int num_sources,
+ struct in_addr *sources)
{
- struct igmp_source *source;
- struct igmp_group *group;
- int i;
-
- /* non-existant group is created as INCLUDE {empty} */
- group = igmp_add_group_by_addr(igmp, group_addr);
- if (!group) {
- return;
- }
-
- /* scan received sources */
- for (i = 0; i < num_sources; ++i) {
- struct in_addr *src_addr;
-
- src_addr = sources + i;
-
- source = add_source_by_addr(igmp, group, *src_addr);
- if (!source) {
- continue;
- }
-
- /*
- RFC 3376: 6.4.1. Reception of Current-State Records
-
- When receiving IS_IN reports for groups in EXCLUDE mode is
- sources should be moved from set with (timers = 0) to set with
- (timers > 0).
-
- igmp_source_reset_gmi() below, resetting the source timers to
- GMI, accomplishes this.
- */
- igmp_source_reset_gmi(igmp, group, source);
-
- } /* scan received sources */
-
- if ((num_sources == 0) &&
- (group->group_filtermode_isexcl) &&
- (listcount (group->group_source_list) == 1))
- {
- struct in_addr star = { .s_addr = INADDR_ANY };
-
- source = igmp_find_source_by_addr (group, star);
- if (source)
- igmp_source_reset_gmi (igmp, group, source);
- }
+ struct igmp_source *source;
+ struct igmp_group *group;
+ int i;
+
+ /* non-existant group is created as INCLUDE {empty} */
+ group = igmp_add_group_by_addr(igmp, group_addr);
+ if (!group) {
+ return;
+ }
+
+ /* scan received sources */
+ for (i = 0; i < num_sources; ++i) {
+ struct in_addr *src_addr;
+
+ src_addr = sources + i;
+
+ source = add_source_by_addr(igmp, group, *src_addr);
+ if (!source) {
+ continue;
+ }
+
+ /*
+ RFC 3376: 6.4.1. Reception of Current-State Records
+
+ When receiving IS_IN reports for groups in EXCLUDE mode is
+ sources should be moved from set with (timers = 0) to set with
+ (timers > 0).
+
+ igmp_source_reset_gmi() below, resetting the source timers to
+ GMI, accomplishes this.
+ */
+ igmp_source_reset_gmi(igmp, group, source);
+
+ } /* scan received sources */
+
+ if ((num_sources == 0) && (group->group_filtermode_isexcl)
+ && (listcount(group->group_source_list) == 1)) {
+ struct in_addr star = {.s_addr = INADDR_ANY};
+
+ source = igmp_find_source_by_addr(group, star);
+ if (source)
+ igmp_source_reset_gmi(igmp, group, source);
+ }
}
void igmpv3_report_isin(struct igmp_sock *igmp, struct in_addr from,
- struct in_addr group_addr,
- int num_sources, struct in_addr *sources)
+ struct in_addr group_addr, int num_sources,
+ struct in_addr *sources)
{
- on_trace(__PRETTY_FUNCTION__,
- igmp->interface, from, group_addr, num_sources, sources);
+ on_trace(__PRETTY_FUNCTION__, igmp->interface, from, group_addr,
+ num_sources, sources);
- allow(igmp, from, group_addr, num_sources, sources);
+ allow(igmp, from, group_addr, num_sources, sources);
}
-static void isex_excl(struct igmp_group *group,
- int num_sources, struct in_addr *sources)
+static void isex_excl(struct igmp_group *group, int num_sources,
+ struct in_addr *sources)
{
- struct igmp_source *source;
- int i;
-
- /* EXCLUDE mode */
- zassert(group->group_filtermode_isexcl);
-
- /* E.1: set deletion flag for known sources (X,Y) */
- source_mark_delete_flag (group);
-
- /* scan received sources (A) */
- for (i = 0; i < num_sources; ++i) {
- struct in_addr *src_addr;
-
- src_addr = sources + i;
-
- /* E.2: lookup reported source from (A) in (X,Y) */
- source = igmp_find_source_by_addr(group, *src_addr);
- if (source) {
- /* E.3: if found, clear deletion flag: (X*A) or (Y*A) */
- IGMP_SOURCE_DONT_DELETE(source->source_flags);
- }
- else {
- /* E.4: if not found, create source with timer=GMI: (A-X-Y) */
- source = source_new(group, *src_addr);
- if (!source) {
- /* ugh, internal malloc failure, skip source */
- continue;
- }
- zassert(!source->t_source_timer); /* timer == 0 */
- igmp_source_reset_gmi(group->group_igmp_sock, group, source);
- zassert(source->t_source_timer); /* (A-X-Y) timer > 0 */
- }
-
- } /* scan received sources */
-
- /*
- * If we are in isexcl mode and num_sources == 0
- * than that means we have a *,g entry that
- * needs to be handled
- */
- if (group->group_filtermode_isexcl && num_sources == 0)
- {
- struct in_addr star = { .s_addr = INADDR_ANY };
- source = igmp_find_source_by_addr (group, star);
- if (source)
- {
- IGMP_SOURCE_DONT_DELETE(source->source_flags);
- igmp_source_reset_gmi (group->group_igmp_sock, group, source);
- }
- }
-
- /* E.5: delete all sources marked with deletion flag: (X-A) and (Y-A) */
- source_delete_by_flag(group->group_source_list);
+ struct igmp_source *source;
+ int i;
+
+ /* EXCLUDE mode */
+ zassert(group->group_filtermode_isexcl);
+
+ /* E.1: set deletion flag for known sources (X,Y) */
+ source_mark_delete_flag(group);
+
+ /* scan received sources (A) */
+ for (i = 0; i < num_sources; ++i) {
+ struct in_addr *src_addr;
+
+ src_addr = sources + i;
+
+ /* E.2: lookup reported source from (A) in (X,Y) */
+ source = igmp_find_source_by_addr(group, *src_addr);
+ if (source) {
+ /* E.3: if found, clear deletion flag: (X*A) or (Y*A) */
+ IGMP_SOURCE_DONT_DELETE(source->source_flags);
+ } else {
+ /* E.4: if not found, create source with timer=GMI:
+ * (A-X-Y) */
+ source = source_new(group, *src_addr);
+ if (!source) {
+ /* ugh, internal malloc failure, skip source */
+ continue;
+ }
+ zassert(!source->t_source_timer); /* timer == 0 */
+ igmp_source_reset_gmi(group->group_igmp_sock, group,
+ source);
+ zassert(source->t_source_timer); /* (A-X-Y) timer > 0 */
+ }
+
+ } /* scan received sources */
+
+ /*
+ * If we are in isexcl mode and num_sources == 0
+ * than that means we have a *,g entry that
+ * needs to be handled
+ */
+ if (group->group_filtermode_isexcl && num_sources == 0) {
+ struct in_addr star = {.s_addr = INADDR_ANY};
+ source = igmp_find_source_by_addr(group, star);
+ if (source) {
+ IGMP_SOURCE_DONT_DELETE(source->source_flags);
+ igmp_source_reset_gmi(group->group_igmp_sock, group,
+ source);
+ }
+ }
+
+ /* E.5: delete all sources marked with deletion flag: (X-A) and (Y-A) */
+ source_delete_by_flag(group->group_source_list);
}
-static void isex_incl(struct igmp_group *group,
- int num_sources, struct in_addr *sources)
+static void isex_incl(struct igmp_group *group, int num_sources,
+ struct in_addr *sources)
{
- int i;
-
- /* INCLUDE mode */
- zassert(!group->group_filtermode_isexcl);
-
- /* I.1: set deletion flag for known sources (A) */
- source_mark_delete_flag (group);
-
- /* scan received sources (B) */
- for (i = 0; i < num_sources; ++i) {
- struct igmp_source *source;
- struct in_addr *src_addr;
-
- src_addr = sources + i;
-
- /* I.2: lookup reported source (B) */
- source = igmp_find_source_by_addr(group, *src_addr);
- if (source) {
- /* I.3: if found, clear deletion flag (A*B) */
- IGMP_SOURCE_DONT_DELETE(source->source_flags);
- }
- else {
- /* I.4: if not found, create source with timer=0 (B-A) */
- source = source_new(group, *src_addr);
- if (!source) {
- /* ugh, internal malloc failure, skip source */
- continue;
- }
- zassert(!source->t_source_timer); /* (B-A) timer=0 */
- }
-
- } /* scan received sources */
-
- /* I.5: delete all sources marked with deletion flag (A-B) */
- source_delete_by_flag(group->group_source_list);
-
- group->group_filtermode_isexcl = 1; /* boolean=true */
-
- zassert(group->group_filtermode_isexcl);
-
- group_exclude_fwd_anysrc_ifempty(group);
+ int i;
+
+ /* INCLUDE mode */
+ zassert(!group->group_filtermode_isexcl);
+
+ /* I.1: set deletion flag for known sources (A) */
+ source_mark_delete_flag(group);
+
+ /* scan received sources (B) */
+ for (i = 0; i < num_sources; ++i) {
+ struct igmp_source *source;
+ struct in_addr *src_addr;
+
+ src_addr = sources + i;
+
+ /* I.2: lookup reported source (B) */
+ source = igmp_find_source_by_addr(group, *src_addr);
+ if (source) {
+ /* I.3: if found, clear deletion flag (A*B) */
+ IGMP_SOURCE_DONT_DELETE(source->source_flags);
+ } else {
+ /* I.4: if not found, create source with timer=0 (B-A)
+ */
+ source = source_new(group, *src_addr);
+ if (!source) {
+ /* ugh, internal malloc failure, skip source */
+ continue;
+ }
+ zassert(!source->t_source_timer); /* (B-A) timer=0 */
+ }
+
+ } /* scan received sources */
+
+ /* I.5: delete all sources marked with deletion flag (A-B) */
+ source_delete_by_flag(group->group_source_list);
+
+ group->group_filtermode_isexcl = 1; /* boolean=true */
+
+ zassert(group->group_filtermode_isexcl);
+
+ group_exclude_fwd_anysrc_ifempty(group);
}
void igmpv3_report_isex(struct igmp_sock *igmp, struct in_addr from,
- struct in_addr group_addr,
- int num_sources, struct in_addr *sources,
- int from_igmp_v2_report)
+ struct in_addr group_addr, int num_sources,
+ struct in_addr *sources, int from_igmp_v2_report)
{
- struct interface *ifp = igmp->interface;
- struct igmp_group *group;
-
- on_trace(__PRETTY_FUNCTION__,
- ifp, from, group_addr, num_sources, sources);
-
- /* non-existant group is created as INCLUDE {empty} */
- group = igmp_add_group_by_addr(igmp, group_addr);
- if (!group) {
- return;
- }
-
- /* So we can display how we learned the group in our show command output */
- if (from_igmp_v2_report)
- group->igmp_version = 2;
-
- if (group->group_filtermode_isexcl) {
- /* EXCLUDE mode */
- isex_excl(group, num_sources, sources);
- }
- else {
- /* INCLUDE mode */
- isex_incl(group, num_sources, sources);
- zassert(group->group_filtermode_isexcl);
- }
-
- zassert(group->group_filtermode_isexcl);
-
- igmp_group_reset_gmi(group);
+ struct interface *ifp = igmp->interface;
+ struct igmp_group *group;
+
+ on_trace(__PRETTY_FUNCTION__, ifp, from, group_addr, num_sources,
+ sources);
+
+ /* non-existant group is created as INCLUDE {empty} */
+ group = igmp_add_group_by_addr(igmp, group_addr);
+ if (!group) {
+ return;
+ }
+
+ /* So we can display how we learned the group in our show command output
+ */
+ if (from_igmp_v2_report)
+ group->igmp_version = 2;
+
+ if (group->group_filtermode_isexcl) {
+ /* EXCLUDE mode */
+ isex_excl(group, num_sources, sources);
+ } else {
+ /* INCLUDE mode */
+ isex_incl(group, num_sources, sources);
+ zassert(group->group_filtermode_isexcl);
+ }
+
+ zassert(group->group_filtermode_isexcl);
+
+ igmp_group_reset_gmi(group);
}
-static void toin_incl(struct igmp_group *group,
- int num_sources, struct in_addr *sources)
+static void toin_incl(struct igmp_group *group, int num_sources,
+ struct in_addr *sources)
{
- struct igmp_sock *igmp = group->group_igmp_sock;
- int num_sources_tosend = listcount(group->group_source_list);
- int i;
-
- /* Set SEND flag for all known sources (A) */
- source_mark_send_flag (group);
-
- /* Scan received sources (B) */
- for (i = 0; i < num_sources; ++i) {
- struct igmp_source *source;
- struct in_addr *src_addr;
-
- src_addr = sources + i;
-
- /* Lookup reported source (B) */
- source = igmp_find_source_by_addr(group, *src_addr);
- if (source) {
- /* If found, clear SEND flag (A*B) */
- IGMP_SOURCE_DONT_SEND(source->source_flags);
- --num_sources_tosend;
- }
- else {
- /* If not found, create new source */
- source = source_new(group, *src_addr);
- if (!source) {
- /* ugh, internal malloc failure, skip source */
- continue;
- }
- }
-
- /* (B)=GMI */
- igmp_source_reset_gmi(igmp, group, source);
- }
-
- /* Send sources marked with SEND flag: Q(G,A-B) */
- if (num_sources_tosend > 0) {
- source_query_send_by_flag(group, num_sources_tosend);
- }
+ struct igmp_sock *igmp = group->group_igmp_sock;
+ int num_sources_tosend = listcount(group->group_source_list);
+ int i;
+
+ /* Set SEND flag for all known sources (A) */
+ source_mark_send_flag(group);
+
+ /* Scan received sources (B) */
+ for (i = 0; i < num_sources; ++i) {
+ struct igmp_source *source;
+ struct in_addr *src_addr;
+
+ src_addr = sources + i;
+
+ /* Lookup reported source (B) */
+ source = igmp_find_source_by_addr(group, *src_addr);
+ if (source) {
+ /* If found, clear SEND flag (A*B) */
+ IGMP_SOURCE_DONT_SEND(source->source_flags);
+ --num_sources_tosend;
+ } else {
+ /* If not found, create new source */
+ source = source_new(group, *src_addr);
+ if (!source) {
+ /* ugh, internal malloc failure, skip source */
+ continue;
+ }
+ }
+
+ /* (B)=GMI */
+ igmp_source_reset_gmi(igmp, group, source);
+ }
+
+ /* Send sources marked with SEND flag: Q(G,A-B) */
+ if (num_sources_tosend > 0) {
+ source_query_send_by_flag(group, num_sources_tosend);
+ }
}
-static void toin_excl(struct igmp_group *group,
- int num_sources, struct in_addr *sources)
+static void toin_excl(struct igmp_group *group, int num_sources,
+ struct in_addr *sources)
{
- struct igmp_sock *igmp = group->group_igmp_sock;
- int num_sources_tosend;
- int i;
-
- /* Set SEND flag for X (sources with timer > 0) */
- num_sources_tosend = source_mark_send_flag_by_timer (group);
-
- /* Scan received sources (A) */
- for (i = 0; i < num_sources; ++i) {
- struct igmp_source *source;
- struct in_addr *src_addr;
-
- src_addr = sources + i;
-
- /* Lookup reported source (A) */
- source = igmp_find_source_by_addr(group, *src_addr);
- if (source) {
- if (source->t_source_timer) {
- /* If found and timer running, clear SEND flag (X*A) */
- IGMP_SOURCE_DONT_SEND(source->source_flags);
- --num_sources_tosend;
- }
- }
- else {
- /* If not found, create new source */
- source = source_new(group, *src_addr);
- if (!source) {
- /* ugh, internal malloc failure, skip source */
- continue;
- }
- }
-
- /* (A)=GMI */
- igmp_source_reset_gmi(igmp, group, source);
- }
-
- /* Send sources marked with SEND flag: Q(G,X-A) */
- if (num_sources_tosend > 0) {
- source_query_send_by_flag(group, num_sources_tosend);
- }
-
- /* Send Q(G) */
- group_query_send(group);
+ struct igmp_sock *igmp = group->group_igmp_sock;
+ int num_sources_tosend;
+ int i;
+
+ /* Set SEND flag for X (sources with timer > 0) */
+ num_sources_tosend = source_mark_send_flag_by_timer(group);
+
+ /* Scan received sources (A) */
+ for (i = 0; i < num_sources; ++i) {
+ struct igmp_source *source;
+ struct in_addr *src_addr;
+
+ src_addr = sources + i;
+
+ /* Lookup reported source (A) */
+ source = igmp_find_source_by_addr(group, *src_addr);
+ if (source) {
+ if (source->t_source_timer) {
+ /* If found and timer running, clear SEND flag
+ * (X*A) */
+ IGMP_SOURCE_DONT_SEND(source->source_flags);
+ --num_sources_tosend;
+ }
+ } else {
+ /* If not found, create new source */
+ source = source_new(group, *src_addr);
+ if (!source) {
+ /* ugh, internal malloc failure, skip source */
+ continue;
+ }
+ }
+
+ /* (A)=GMI */
+ igmp_source_reset_gmi(igmp, group, source);
+ }
+
+ /* Send sources marked with SEND flag: Q(G,X-A) */
+ if (num_sources_tosend > 0) {
+ source_query_send_by_flag(group, num_sources_tosend);
+ }
+
+ /* Send Q(G) */
+ group_query_send(group);
}
void igmpv3_report_toin(struct igmp_sock *igmp, struct in_addr from,
- struct in_addr group_addr,
- int num_sources, struct in_addr *sources)
+ struct in_addr group_addr, int num_sources,
+ struct in_addr *sources)
{
- struct interface *ifp = igmp->interface;
- struct igmp_group *group;
-
- on_trace(__PRETTY_FUNCTION__,
- ifp, from, group_addr, num_sources, sources);
-
- /*
- * If the requested filter mode is INCLUDE *and* the requested source
- * list is empty, then the entry corresponding to the requested
- * interface and multicast address is deleted if present. If no such
- * entry is present, the request is ignored.
- */
- if (num_sources)
- {
- /* non-existant group is created as INCLUDE {empty} */
- group = igmp_add_group_by_addr(igmp, group_addr);
- if (!group) {
- return;
- }
- }
- else
- {
- group = find_group_by_addr (igmp, group_addr);
- if (!group)
- return;
- }
-
- if (group->group_filtermode_isexcl) {
- /* EXCLUDE mode */
- toin_excl(group, num_sources, sources);
- }
- else {
- /* INCLUDE mode */
- toin_incl(group, num_sources, sources);
- }
+ struct interface *ifp = igmp->interface;
+ struct igmp_group *group;
+
+ on_trace(__PRETTY_FUNCTION__, ifp, from, group_addr, num_sources,
+ sources);
+
+ /*
+ * If the requested filter mode is INCLUDE *and* the requested source
+ * list is empty, then the entry corresponding to the requested
+ * interface and multicast address is deleted if present. If no such
+ * entry is present, the request is ignored.
+ */
+ if (num_sources) {
+ /* non-existant group is created as INCLUDE {empty} */
+ group = igmp_add_group_by_addr(igmp, group_addr);
+ if (!group) {
+ return;
+ }
+ } else {
+ group = find_group_by_addr(igmp, group_addr);
+ if (!group)
+ return;
+ }
+
+ if (group->group_filtermode_isexcl) {
+ /* EXCLUDE mode */
+ toin_excl(group, num_sources, sources);
+ } else {
+ /* INCLUDE mode */
+ toin_incl(group, num_sources, sources);
+ }
}
-static void toex_incl(struct igmp_group *group,
- int num_sources, struct in_addr *sources)
+static void toex_incl(struct igmp_group *group, int num_sources,
+ struct in_addr *sources)
{
- int num_sources_tosend = 0;
- int i;
-
- zassert(!group->group_filtermode_isexcl);
-
- /* Set DELETE flag for all known sources (A) */
- source_mark_delete_flag (group);
-
- /* Clear off SEND flag from all known sources (A) */
- source_clear_send_flag(group->group_source_list);
-
- /* Scan received sources (B) */
- for (i = 0; i < num_sources; ++i) {
- struct igmp_source *source;
- struct in_addr *src_addr;
-
- src_addr = sources + i;
-
- /* Lookup reported source (B) */
- source = igmp_find_source_by_addr(group, *src_addr);
- if (source) {
- /* If found, clear deletion flag: (A*B) */
- IGMP_SOURCE_DONT_DELETE(source->source_flags);
- /* and set SEND flag (A*B) */
- IGMP_SOURCE_DO_SEND(source->source_flags);
- ++num_sources_tosend;
- }
- else {
- /* If source not found, create source with timer=0: (B-A)=0 */
- source = source_new(group, *src_addr);
- if (!source) {
- /* ugh, internal malloc failure, skip source */
- continue;
- }
- zassert(!source->t_source_timer); /* (B-A) timer=0 */
- }
-
- } /* Scan received sources (B) */
-
- group->group_filtermode_isexcl = 1; /* boolean=true */
-
- /* Delete all sources marked with DELETE flag (A-B) */
- source_delete_by_flag(group->group_source_list);
-
- /* Send sources marked with SEND flag: Q(G,A*B) */
- if (num_sources_tosend > 0) {
- source_query_send_by_flag(group, num_sources_tosend);
- }
-
- zassert(group->group_filtermode_isexcl);
-
- group_exclude_fwd_anysrc_ifempty(group);
+ int num_sources_tosend = 0;
+ int i;
+
+ zassert(!group->group_filtermode_isexcl);
+
+ /* Set DELETE flag for all known sources (A) */
+ source_mark_delete_flag(group);
+
+ /* Clear off SEND flag from all known sources (A) */
+ source_clear_send_flag(group->group_source_list);
+
+ /* Scan received sources (B) */
+ for (i = 0; i < num_sources; ++i) {
+ struct igmp_source *source;
+ struct in_addr *src_addr;
+
+ src_addr = sources + i;
+
+ /* Lookup reported source (B) */
+ source = igmp_find_source_by_addr(group, *src_addr);
+ if (source) {
+ /* If found, clear deletion flag: (A*B) */
+ IGMP_SOURCE_DONT_DELETE(source->source_flags);
+ /* and set SEND flag (A*B) */
+ IGMP_SOURCE_DO_SEND(source->source_flags);
+ ++num_sources_tosend;
+ } else {
+ /* If source not found, create source with timer=0:
+ * (B-A)=0 */
+ source = source_new(group, *src_addr);
+ if (!source) {
+ /* ugh, internal malloc failure, skip source */
+ continue;
+ }
+ zassert(!source->t_source_timer); /* (B-A) timer=0 */
+ }
+
+ } /* Scan received sources (B) */
+
+ group->group_filtermode_isexcl = 1; /* boolean=true */
+
+ /* Delete all sources marked with DELETE flag (A-B) */
+ source_delete_by_flag(group->group_source_list);
+
+ /* Send sources marked with SEND flag: Q(G,A*B) */
+ if (num_sources_tosend > 0) {
+ source_query_send_by_flag(group, num_sources_tosend);
+ }
+
+ zassert(group->group_filtermode_isexcl);
+
+ group_exclude_fwd_anysrc_ifempty(group);
}
-static void toex_excl(struct igmp_group *group,
- int num_sources, struct in_addr *sources)
+static void toex_excl(struct igmp_group *group, int num_sources,
+ struct in_addr *sources)
{
- int num_sources_tosend = 0;
- int i;
-
- /* set DELETE flag for all known sources (X,Y) */
- source_mark_delete_flag (group);
-
- /* clear off SEND flag from all known sources (X,Y) */
- source_clear_send_flag(group->group_source_list);
-
- if (num_sources == 0)
- {
- struct igmp_source *source;
- struct in_addr any = { .s_addr = INADDR_ANY };
-
- source = igmp_find_source_by_addr (group, any);
- if (source)
- IGMP_SOURCE_DONT_DELETE(source->source_flags);
- }
-
- /* scan received sources (A) */
- for (i = 0; i < num_sources; ++i) {
- struct igmp_source *source;
- struct in_addr *src_addr;
-
- src_addr = sources + i;
-
- /* lookup reported source (A) in known sources (X,Y) */
- source = igmp_find_source_by_addr(group, *src_addr);
- if (source) {
- /* if found, clear off DELETE flag from reported source (A) */
- IGMP_SOURCE_DONT_DELETE(source->source_flags);
- }
- else {
- /* if not found, create source with Group Timer: (A-X-Y)=Group Timer */
- long group_timer_msec;
- source = source_new(group, *src_addr);
- if (!source) {
- /* ugh, internal malloc failure, skip source */
- continue;
- }
-
- zassert(!source->t_source_timer); /* timer == 0 */
- group_timer_msec = igmp_group_timer_remain_msec(group);
- igmp_source_timer_on(group, source, group_timer_msec);
- zassert(source->t_source_timer); /* (A-X-Y) timer > 0 */
-
- /* make sure source is created with DELETE flag unset */
- zassert(!IGMP_SOURCE_TEST_DELETE(source->source_flags));
- }
-
- /* make sure reported source has DELETE flag unset */
- zassert(!IGMP_SOURCE_TEST_DELETE(source->source_flags));
-
- if (source->t_source_timer) {
- /* if source timer>0 mark SEND flag: Q(G,A-Y) */
- IGMP_SOURCE_DO_SEND(source->source_flags);
- ++num_sources_tosend;
- }
-
- } /* scan received sources (A) */
-
- /*
- delete all sources marked with DELETE flag:
- Delete (X-A)
- Delete (Y-A)
- */
- source_delete_by_flag(group->group_source_list);
-
- /* send sources marked with SEND flag: Q(G,A-Y) */
- if (num_sources_tosend > 0) {
- source_query_send_by_flag(group, num_sources_tosend);
- }
+ int num_sources_tosend = 0;
+ int i;
+
+ /* set DELETE flag for all known sources (X,Y) */
+ source_mark_delete_flag(group);
+
+ /* clear off SEND flag from all known sources (X,Y) */
+ source_clear_send_flag(group->group_source_list);
+
+ if (num_sources == 0) {
+ struct igmp_source *source;
+ struct in_addr any = {.s_addr = INADDR_ANY};
+
+ source = igmp_find_source_by_addr(group, any);
+ if (source)
+ IGMP_SOURCE_DONT_DELETE(source->source_flags);
+ }
+
+ /* scan received sources (A) */
+ for (i = 0; i < num_sources; ++i) {
+ struct igmp_source *source;
+ struct in_addr *src_addr;
+
+ src_addr = sources + i;
+
+ /* lookup reported source (A) in known sources (X,Y) */
+ source = igmp_find_source_by_addr(group, *src_addr);
+ if (source) {
+ /* if found, clear off DELETE flag from reported source
+ * (A) */
+ IGMP_SOURCE_DONT_DELETE(source->source_flags);
+ } else {
+ /* if not found, create source with Group Timer:
+ * (A-X-Y)=Group Timer */
+ long group_timer_msec;
+ source = source_new(group, *src_addr);
+ if (!source) {
+ /* ugh, internal malloc failure, skip source */
+ continue;
+ }
+
+ zassert(!source->t_source_timer); /* timer == 0 */
+ group_timer_msec = igmp_group_timer_remain_msec(group);
+ igmp_source_timer_on(group, source, group_timer_msec);
+ zassert(source->t_source_timer); /* (A-X-Y) timer > 0 */
+
+ /* make sure source is created with DELETE flag unset */
+ zassert(!IGMP_SOURCE_TEST_DELETE(source->source_flags));
+ }
+
+ /* make sure reported source has DELETE flag unset */
+ zassert(!IGMP_SOURCE_TEST_DELETE(source->source_flags));
+
+ if (source->t_source_timer) {
+ /* if source timer>0 mark SEND flag: Q(G,A-Y) */
+ IGMP_SOURCE_DO_SEND(source->source_flags);
+ ++num_sources_tosend;
+ }
+
+ } /* scan received sources (A) */
+
+ /*
+ delete all sources marked with DELETE flag:
+ Delete (X-A)
+ Delete (Y-A)
+ */
+ source_delete_by_flag(group->group_source_list);
+
+ /* send sources marked with SEND flag: Q(G,A-Y) */
+ if (num_sources_tosend > 0) {
+ source_query_send_by_flag(group, num_sources_tosend);
+ }
}
void igmpv3_report_toex(struct igmp_sock *igmp, struct in_addr from,
- struct in_addr group_addr,
- int num_sources, struct in_addr *sources)
+ struct in_addr group_addr, int num_sources,
+ struct in_addr *sources)
{
- struct interface *ifp = igmp->interface;
- struct igmp_group *group;
-
- on_trace(__PRETTY_FUNCTION__,
- ifp, from, group_addr, num_sources, sources);
-
- /* non-existant group is created as INCLUDE {empty} */
- group = igmp_add_group_by_addr(igmp, group_addr);
- if (!group) {
- return;
- }
-
- if (group->group_filtermode_isexcl) {
- /* EXCLUDE mode */
- toex_excl(group, num_sources, sources);
- }
- else {
- /* INCLUDE mode */
- toex_incl(group, num_sources, sources);
- zassert(group->group_filtermode_isexcl);
- }
- zassert(group->group_filtermode_isexcl);
-
- /* Group Timer=GMI */
- igmp_group_reset_gmi(group);
+ struct interface *ifp = igmp->interface;
+ struct igmp_group *group;
+
+ on_trace(__PRETTY_FUNCTION__, ifp, from, group_addr, num_sources,
+ sources);
+
+ /* non-existant group is created as INCLUDE {empty} */
+ group = igmp_add_group_by_addr(igmp, group_addr);
+ if (!group) {
+ return;
+ }
+
+ if (group->group_filtermode_isexcl) {
+ /* EXCLUDE mode */
+ toex_excl(group, num_sources, sources);
+ } else {
+ /* INCLUDE mode */
+ toex_incl(group, num_sources, sources);
+ zassert(group->group_filtermode_isexcl);
+ }
+ zassert(group->group_filtermode_isexcl);
+
+ /* Group Timer=GMI */
+ igmp_group_reset_gmi(group);
}
void igmpv3_report_allow(struct igmp_sock *igmp, struct in_addr from,
- struct in_addr group_addr,
- int num_sources, struct in_addr *sources)
+ struct in_addr group_addr, int num_sources,
+ struct in_addr *sources)
{
- on_trace(__PRETTY_FUNCTION__,
- igmp->interface, from, group_addr, num_sources, sources);
+ on_trace(__PRETTY_FUNCTION__, igmp->interface, from, group_addr,
+ num_sources, sources);
- allow(igmp, from, group_addr, num_sources, sources);
+ allow(igmp, from, group_addr, num_sources, sources);
}
/*
@@ -1005,67 +1003,64 @@ void igmpv3_report_allow(struct igmp_sock *igmp, struct in_addr from,
*/
static void group_retransmit_group(struct igmp_group *group)
{
- struct igmp_sock *igmp;
- struct pim_interface *pim_ifp;
- long lmqc; /* Last Member Query Count */
- long lmqi_msec; /* Last Member Query Interval */
- long lmqt_msec; /* Last Member Query Time */
- int s_flag;
- int query_buf_size;
-
- igmp = group->group_igmp_sock;
- pim_ifp = igmp->interface->info;
-
- if (pim_ifp->igmp_version == 3) {
- query_buf_size = PIM_IGMP_BUFSIZE_WRITE;
- } else {
- query_buf_size = IGMP_V12_MSG_SIZE;
- }
-
- char query_buf[query_buf_size];
-
- lmqc = igmp->querier_robustness_variable;
- lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec;
- lmqt_msec = lmqc * lmqi_msec;
-
- /*
- RFC3376: 6.6.3.1. Building and Sending Group Specific Queries
-
- When transmitting a group specific query, if the group timer is
- larger than LMQT, the "Suppress Router-Side Processing" bit is set
- in the query message.
- */
- s_flag = igmp_group_timer_remain_msec(group) > lmqt_msec;
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- zlog_debug("retransmit_group_specific_query: group %s on %s: s_flag=%d count=%d",
- group_str, igmp->interface->name, s_flag,
- group->group_specific_query_retransmit_count);
- }
-
- /*
- RFC3376: 4.1.12. IP Destination Addresses for Queries
-
- Group-Specific and Group-and-Source-Specific Queries are sent with
- an IP destination address equal to the multicast address of
- interest.
- */
-
- igmp_send_query(pim_ifp->igmp_version,
- group,
- igmp->fd,
- igmp->interface->name,
- query_buf,
- sizeof(query_buf),
- 0 /* num_sources_tosend */,
- group->group_addr /* dst_addr */,
- group->group_addr /* group_addr */,
- pim_ifp->igmp_specific_query_max_response_time_dsec,
- s_flag,
- igmp->querier_robustness_variable,
- igmp->querier_query_interval);
+ struct igmp_sock *igmp;
+ struct pim_interface *pim_ifp;
+ long lmqc; /* Last Member Query Count */
+ long lmqi_msec; /* Last Member Query Interval */
+ long lmqt_msec; /* Last Member Query Time */
+ int s_flag;
+ int query_buf_size;
+
+ igmp = group->group_igmp_sock;
+ pim_ifp = igmp->interface->info;
+
+ if (pim_ifp->igmp_version == 3) {
+ query_buf_size = PIM_IGMP_BUFSIZE_WRITE;
+ } else {
+ query_buf_size = IGMP_V12_MSG_SIZE;
+ }
+
+ char query_buf[query_buf_size];
+
+ lmqc = igmp->querier_robustness_variable;
+ lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec;
+ lmqt_msec = lmqc * lmqi_msec;
+
+ /*
+ RFC3376: 6.6.3.1. Building and Sending Group Specific Queries
+
+ When transmitting a group specific query, if the group timer is
+ larger than LMQT, the "Suppress Router-Side Processing" bit is set
+ in the query message.
+ */
+ s_flag = igmp_group_timer_remain_msec(group) > lmqt_msec;
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group->group_addr, group_str,
+ sizeof(group_str));
+ zlog_debug(
+ "retransmit_group_specific_query: group %s on %s: s_flag=%d count=%d",
+ group_str, igmp->interface->name, s_flag,
+ group->group_specific_query_retransmit_count);
+ }
+
+ /*
+ RFC3376: 4.1.12. IP Destination Addresses for Queries
+
+ Group-Specific and Group-and-Source-Specific Queries are sent with
+ an IP destination address equal to the multicast address of
+ interest.
+ */
+
+ igmp_send_query(pim_ifp->igmp_version, group, igmp->fd,
+ igmp->interface->name, query_buf, sizeof(query_buf),
+ 0 /* num_sources_tosend */,
+ group->group_addr /* dst_addr */,
+ group->group_addr /* group_addr */,
+ pim_ifp->igmp_specific_query_max_response_time_dsec,
+ s_flag, igmp->querier_robustness_variable,
+ igmp->querier_query_interval);
}
/*
@@ -1083,205 +1078,214 @@ static void group_retransmit_group(struct igmp_group *group)
static int group_retransmit_sources(struct igmp_group *group,
int send_with_sflag_set)
{
- struct igmp_sock *igmp;
- struct pim_interface *pim_ifp;
- long lmqc; /* Last Member Query Count */
- long lmqi_msec; /* Last Member Query Interval */
- long lmqt_msec; /* Last Member Query Time */
- char query_buf1[PIM_IGMP_BUFSIZE_WRITE]; /* 1 = with s_flag set */
- char query_buf2[PIM_IGMP_BUFSIZE_WRITE]; /* 2 = with s_flag clear */
- int query_buf1_max_sources;
- int query_buf2_max_sources;
- struct in_addr *source_addr1;
- struct in_addr *source_addr2;
- int num_sources_tosend1;
- int num_sources_tosend2;
- struct listnode *src_node;
- struct igmp_source *src;
- int num_retransmit_sources_left = 0;
-
- source_addr1 = (struct in_addr *)(query_buf1 + IGMP_V3_SOURCES_OFFSET);
- source_addr2 = (struct in_addr *)(query_buf2 + IGMP_V3_SOURCES_OFFSET);
-
- igmp = group->group_igmp_sock;
- pim_ifp = igmp->interface->info;
-
- lmqc = igmp->querier_robustness_variable;
- lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec;
- lmqt_msec = lmqc * lmqi_msec;
-
- /* Scan all group sources */
- for (ALL_LIST_ELEMENTS_RO(group->group_source_list, src_node, src)) {
-
- /* Source has retransmission state? */
- if (src->source_query_retransmit_count < 1)
- continue;
-
- if (--src->source_query_retransmit_count > 0) {
- ++num_retransmit_sources_left;
- }
-
- /* Copy source address into appropriate query buffer */
- if (igmp_source_timer_remain_msec(src) > lmqt_msec) {
- *source_addr1 = src->source_addr;
- ++source_addr1;
- }
- else {
- *source_addr2 = src->source_addr;
- ++source_addr2;
- }
-
- }
-
- num_sources_tosend1 = source_addr1 - (struct in_addr *)(query_buf1 + IGMP_V3_SOURCES_OFFSET);
- num_sources_tosend2 = source_addr2 - (struct in_addr *)(query_buf2 + IGMP_V3_SOURCES_OFFSET);
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- zlog_debug("retransmit_grp&src_specific_query: group %s on %s: srcs_with_sflag=%d srcs_wo_sflag=%d will_send_sflag=%d retransmit_src_left=%d",
- group_str, igmp->interface->name,
- num_sources_tosend1,
- num_sources_tosend2,
- send_with_sflag_set,
- num_retransmit_sources_left);
- }
-
- if (num_sources_tosend1 > 0) {
- /*
- Send group-and-source-specific query with s_flag set and all
- sources with timers greater than LMQT.
- */
-
- if (send_with_sflag_set) {
-
- query_buf1_max_sources = (sizeof(query_buf1) - IGMP_V3_SOURCES_OFFSET) >> 2;
- if (num_sources_tosend1 > query_buf1_max_sources) {
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- zlog_warn("%s: group %s on %s: s_flag=1 unable to fit %d sources into buf_size=%zu (max_sources=%d)",
- __PRETTY_FUNCTION__, group_str, igmp->interface->name,
- num_sources_tosend1, sizeof(query_buf1), query_buf1_max_sources);
- }
- else {
- /*
- RFC3376: 4.1.12. IP Destination Addresses for Queries
-
- Group-Specific and Group-and-Source-Specific Queries are sent with
- an IP destination address equal to the multicast address of
- interest.
- */
-
- igmp_send_query(pim_ifp->igmp_version,
- group,
- igmp->fd,
- igmp->interface->name,
- query_buf1,
- sizeof(query_buf1),
- num_sources_tosend1,
- group->group_addr,
- group->group_addr,
- pim_ifp->igmp_specific_query_max_response_time_dsec,
- 1 /* s_flag */,
- igmp->querier_robustness_variable,
- igmp->querier_query_interval);
- }
-
- } /* send_with_sflag_set */
-
- }
-
- if (num_sources_tosend2 > 0) {
- /*
- Send group-and-source-specific query with s_flag clear and all
- sources with timers lower or equal to LMQT.
- */
-
- query_buf2_max_sources = (sizeof(query_buf2) - IGMP_V3_SOURCES_OFFSET) >> 2;
- if (num_sources_tosend2 > query_buf2_max_sources) {
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- zlog_warn("%s: group %s on %s: s_flag=0 unable to fit %d sources into buf_size=%zu (max_sources=%d)",
- __PRETTY_FUNCTION__, group_str, igmp->interface->name,
- num_sources_tosend2, sizeof(query_buf2), query_buf2_max_sources);
- }
- else {
- /*
- RFC3376: 4.1.12. IP Destination Addresses for Queries
-
- Group-Specific and Group-and-Source-Specific Queries are sent with
- an IP destination address equal to the multicast address of
- interest.
- */
-
- igmp_send_query(pim_ifp->igmp_version,
- group,
- igmp->fd,
- igmp->interface->name,
- query_buf2,
- sizeof(query_buf2),
- num_sources_tosend2,
- group->group_addr,
- group->group_addr,
- pim_ifp->igmp_specific_query_max_response_time_dsec,
- 0 /* s_flag */,
- igmp->querier_robustness_variable,
- igmp->querier_query_interval);
- }
- }
-
- return num_retransmit_sources_left;
+ struct igmp_sock *igmp;
+ struct pim_interface *pim_ifp;
+ long lmqc; /* Last Member Query Count */
+ long lmqi_msec; /* Last Member Query Interval */
+ long lmqt_msec; /* Last Member Query Time */
+ char query_buf1[PIM_IGMP_BUFSIZE_WRITE]; /* 1 = with s_flag set */
+ char query_buf2[PIM_IGMP_BUFSIZE_WRITE]; /* 2 = with s_flag clear */
+ int query_buf1_max_sources;
+ int query_buf2_max_sources;
+ struct in_addr *source_addr1;
+ struct in_addr *source_addr2;
+ int num_sources_tosend1;
+ int num_sources_tosend2;
+ struct listnode *src_node;
+ struct igmp_source *src;
+ int num_retransmit_sources_left = 0;
+
+ source_addr1 = (struct in_addr *)(query_buf1 + IGMP_V3_SOURCES_OFFSET);
+ source_addr2 = (struct in_addr *)(query_buf2 + IGMP_V3_SOURCES_OFFSET);
+
+ igmp = group->group_igmp_sock;
+ pim_ifp = igmp->interface->info;
+
+ lmqc = igmp->querier_robustness_variable;
+ lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec;
+ lmqt_msec = lmqc * lmqi_msec;
+
+ /* Scan all group sources */
+ for (ALL_LIST_ELEMENTS_RO(group->group_source_list, src_node, src)) {
+
+ /* Source has retransmission state? */
+ if (src->source_query_retransmit_count < 1)
+ continue;
+
+ if (--src->source_query_retransmit_count > 0) {
+ ++num_retransmit_sources_left;
+ }
+
+ /* Copy source address into appropriate query buffer */
+ if (igmp_source_timer_remain_msec(src) > lmqt_msec) {
+ *source_addr1 = src->source_addr;
+ ++source_addr1;
+ } else {
+ *source_addr2 = src->source_addr;
+ ++source_addr2;
+ }
+ }
+
+ num_sources_tosend1 =
+ source_addr1
+ - (struct in_addr *)(query_buf1 + IGMP_V3_SOURCES_OFFSET);
+ num_sources_tosend2 =
+ source_addr2
+ - (struct in_addr *)(query_buf2 + IGMP_V3_SOURCES_OFFSET);
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group->group_addr, group_str,
+ sizeof(group_str));
+ zlog_debug(
+ "retransmit_grp&src_specific_query: group %s on %s: srcs_with_sflag=%d srcs_wo_sflag=%d will_send_sflag=%d retransmit_src_left=%d",
+ group_str, igmp->interface->name, num_sources_tosend1,
+ num_sources_tosend2, send_with_sflag_set,
+ num_retransmit_sources_left);
+ }
+
+ if (num_sources_tosend1 > 0) {
+ /*
+ Send group-and-source-specific query with s_flag set and all
+ sources with timers greater than LMQT.
+ */
+
+ if (send_with_sflag_set) {
+
+ query_buf1_max_sources =
+ (sizeof(query_buf1) - IGMP_V3_SOURCES_OFFSET)
+ >> 2;
+ if (num_sources_tosend1 > query_buf1_max_sources) {
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group->group_addr,
+ group_str, sizeof(group_str));
+ zlog_warn(
+ "%s: group %s on %s: s_flag=1 unable to fit %d sources into buf_size=%zu (max_sources=%d)",
+ __PRETTY_FUNCTION__, group_str,
+ igmp->interface->name,
+ num_sources_tosend1, sizeof(query_buf1),
+ query_buf1_max_sources);
+ } else {
+ /*
+ RFC3376: 4.1.12. IP Destination Addresses for
+ Queries
+
+ Group-Specific and Group-and-Source-Specific
+ Queries are sent with
+ an IP destination address equal to the
+ multicast address of
+ interest.
+ */
+
+ igmp_send_query(
+ pim_ifp->igmp_version, group, igmp->fd,
+ igmp->interface->name, query_buf1,
+ sizeof(query_buf1), num_sources_tosend1,
+ group->group_addr, group->group_addr,
+ pim_ifp->igmp_specific_query_max_response_time_dsec,
+ 1 /* s_flag */,
+ igmp->querier_robustness_variable,
+ igmp->querier_query_interval);
+ }
+
+ } /* send_with_sflag_set */
+ }
+
+ if (num_sources_tosend2 > 0) {
+ /*
+ Send group-and-source-specific query with s_flag clear and all
+ sources with timers lower or equal to LMQT.
+ */
+
+ query_buf2_max_sources =
+ (sizeof(query_buf2) - IGMP_V3_SOURCES_OFFSET) >> 2;
+ if (num_sources_tosend2 > query_buf2_max_sources) {
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group->group_addr, group_str,
+ sizeof(group_str));
+ zlog_warn(
+ "%s: group %s on %s: s_flag=0 unable to fit %d sources into buf_size=%zu (max_sources=%d)",
+ __PRETTY_FUNCTION__, group_str,
+ igmp->interface->name, num_sources_tosend2,
+ sizeof(query_buf2), query_buf2_max_sources);
+ } else {
+ /*
+ RFC3376: 4.1.12. IP Destination Addresses for Queries
+
+ Group-Specific and Group-and-Source-Specific Queries
+ are sent with
+ an IP destination address equal to the multicast
+ address of
+ interest.
+ */
+
+ igmp_send_query(
+ pim_ifp->igmp_version, group, igmp->fd,
+ igmp->interface->name, query_buf2,
+ sizeof(query_buf2), num_sources_tosend2,
+ group->group_addr, group->group_addr,
+ pim_ifp->igmp_specific_query_max_response_time_dsec,
+ 0 /* s_flag */,
+ igmp->querier_robustness_variable,
+ igmp->querier_query_interval);
+ }
+ }
+
+ return num_retransmit_sources_left;
}
static int igmp_group_retransmit(struct thread *t)
{
- struct igmp_group *group;
- int num_retransmit_sources_left;
- int send_with_sflag_set; /* boolean */
-
- group = THREAD_ARG(t);
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- zlog_debug("group_retransmit_timer: group %s on %s",
- group_str, group->group_igmp_sock->interface->name);
- }
-
- /* Retransmit group-specific queries? (RFC3376: 6.6.3.1) */
- if (group->group_specific_query_retransmit_count > 0) {
-
- /* Retransmit group-specific queries (RFC3376: 6.6.3.1) */
- group_retransmit_group(group);
- --group->group_specific_query_retransmit_count;
-
- /*
- RFC3376: 6.6.3.2
- If a group specific query is scheduled to be transmitted at the
- same time as a group and source specific query for the same group,
- then transmission of the group and source specific message with the
- "Suppress Router-Side Processing" bit set may be suppressed.
- */
- send_with_sflag_set = 0; /* boolean=false */
- }
- else {
- send_with_sflag_set = 1; /* boolean=true */
- }
-
- /* Retransmit group-and-source-specific queries (RFC3376: 6.6.3.2) */
- num_retransmit_sources_left = group_retransmit_sources(group,
- send_with_sflag_set);
-
- /*
- Keep group retransmit timer running if there is any retransmit
- counter pending
- */
- if ((num_retransmit_sources_left > 0) ||
- (group->group_specific_query_retransmit_count > 0)) {
- group_retransmit_timer_on(group);
- }
-
- return 0;
+ struct igmp_group *group;
+ int num_retransmit_sources_left;
+ int send_with_sflag_set; /* boolean */
+
+ group = THREAD_ARG(t);
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group->group_addr, group_str,
+ sizeof(group_str));
+ zlog_debug("group_retransmit_timer: group %s on %s", group_str,
+ group->group_igmp_sock->interface->name);
+ }
+
+ /* Retransmit group-specific queries? (RFC3376: 6.6.3.1) */
+ if (group->group_specific_query_retransmit_count > 0) {
+
+ /* Retransmit group-specific queries (RFC3376: 6.6.3.1) */
+ group_retransmit_group(group);
+ --group->group_specific_query_retransmit_count;
+
+ /*
+ RFC3376: 6.6.3.2
+ If a group specific query is scheduled to be transmitted at
+ the
+ same time as a group and source specific query for the same
+ group,
+ then transmission of the group and source specific message
+ with the
+ "Suppress Router-Side Processing" bit set may be suppressed.
+ */
+ send_with_sflag_set = 0; /* boolean=false */
+ } else {
+ send_with_sflag_set = 1; /* boolean=true */
+ }
+
+ /* Retransmit group-and-source-specific queries (RFC3376: 6.6.3.2) */
+ num_retransmit_sources_left =
+ group_retransmit_sources(group, send_with_sflag_set);
+
+ /*
+ Keep group retransmit timer running if there is any retransmit
+ counter pending
+ */
+ if ((num_retransmit_sources_left > 0)
+ || (group->group_specific_query_retransmit_count > 0)) {
+ group_retransmit_timer_on(group);
+ }
+
+ return 0;
}
/*
@@ -1291,42 +1295,42 @@ static int igmp_group_retransmit(struct thread *t)
*/
static void group_retransmit_timer_on(struct igmp_group *group)
{
- struct igmp_sock *igmp;
- struct pim_interface *pim_ifp;
- long lmqi_msec; /* Last Member Query Interval */
-
- /* if group retransmit timer is running, do nothing */
- if (group->t_group_query_retransmit_timer) {
- return;
- }
-
- igmp = group->group_igmp_sock;
- pim_ifp = igmp->interface->info;
-
- lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec;
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- zlog_debug("Scheduling %ld.%03ld sec retransmit timer for group %s on %s",
- lmqi_msec / 1000,
- lmqi_msec % 1000,
- group_str,
- igmp->interface->name);
- }
-
- thread_add_timer_msec(master, igmp_group_retransmit, group, lmqi_msec,
- &group->t_group_query_retransmit_timer);
+ struct igmp_sock *igmp;
+ struct pim_interface *pim_ifp;
+ long lmqi_msec; /* Last Member Query Interval */
+
+ /* if group retransmit timer is running, do nothing */
+ if (group->t_group_query_retransmit_timer) {
+ return;
+ }
+
+ igmp = group->group_igmp_sock;
+ pim_ifp = igmp->interface->info;
+
+ lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec;
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group->group_addr, group_str,
+ sizeof(group_str));
+ zlog_debug(
+ "Scheduling %ld.%03ld sec retransmit timer for group %s on %s",
+ lmqi_msec / 1000, lmqi_msec % 1000, group_str,
+ igmp->interface->name);
+ }
+
+ thread_add_timer_msec(master, igmp_group_retransmit, group, lmqi_msec,
+ &group->t_group_query_retransmit_timer);
}
static long igmp_group_timer_remain_msec(struct igmp_group *group)
{
- return pim_time_timer_remain_msec(group->t_group_timer);
+ return pim_time_timer_remain_msec(group->t_group_timer);
}
static long igmp_source_timer_remain_msec(struct igmp_source *source)
{
- return pim_time_timer_remain_msec(source->t_source_timer);
+ return pim_time_timer_remain_msec(source->t_source_timer);
}
/*
@@ -1334,21 +1338,22 @@ static long igmp_source_timer_remain_msec(struct igmp_source *source)
*/
static void group_query_send(struct igmp_group *group)
{
- long lmqc; /* Last Member Query Count */
+ long lmqc; /* Last Member Query Count */
- lmqc = group->group_igmp_sock->querier_robustness_variable;
+ lmqc = group->group_igmp_sock->querier_robustness_variable;
- /* lower group timer to lmqt */
- igmp_group_timer_lower_to_lmqt(group);
+ /* lower group timer to lmqt */
+ igmp_group_timer_lower_to_lmqt(group);
- /* reset retransmission counter */
- group->group_specific_query_retransmit_count = lmqc;
+ /* reset retransmission counter */
+ group->group_specific_query_retransmit_count = lmqc;
- /* immediately send group specific query (decrease retransmit counter by 1)*/
- group_retransmit_group(group);
+ /* immediately send group specific query (decrease retransmit counter by
+ * 1)*/
+ group_retransmit_group(group);
- /* make sure group retransmit timer is running */
- group_retransmit_timer_on(group);
+ /* make sure group retransmit timer is running */
+ group_retransmit_timer_on(group);
}
/*
@@ -1357,612 +1362,674 @@ static void group_query_send(struct igmp_group *group)
static void source_query_send_by_flag(struct igmp_group *group,
int num_sources_tosend)
{
- struct igmp_sock *igmp;
- struct pim_interface *pim_ifp;
- struct listnode *src_node;
- struct igmp_source *src;
- long lmqc; /* Last Member Query Count */
- long lmqi_msec; /* Last Member Query Interval */
- long lmqt_msec; /* Last Member Query Time */
-
- zassert(num_sources_tosend > 0);
-
- igmp = group->group_igmp_sock;
- pim_ifp = igmp->interface->info;
-
- lmqc = igmp->querier_robustness_variable;
- lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec;
- lmqt_msec = lmqc * lmqi_msec;
-
- /*
- RFC3376: 6.6.3.2. Building and Sending Group and Source Specific Queries
-
- (...) for each of the sources in X of group G, with source timer larger
- than LMQT:
- o Set number of retransmissions for each source to [Last Member
- Query Count].
- o Lower source timer to LMQT.
- */
- for (ALL_LIST_ELEMENTS_RO(group->group_source_list, src_node, src)) {
- if (IGMP_SOURCE_TEST_SEND(src->source_flags)) {
- /* source "src" in X of group G */
- if (igmp_source_timer_remain_msec(src) > lmqt_msec) {
- src->source_query_retransmit_count = lmqc;
- igmp_source_timer_lower_to_lmqt(src);
- }
- }
- }
-
- /* send group-and-source specific queries */
- group_retransmit_sources(group, 1 /* send_with_sflag_set=true */);
-
- /* make sure group retransmit timer is running */
- group_retransmit_timer_on(group);
+ struct igmp_sock *igmp;
+ struct pim_interface *pim_ifp;
+ struct listnode *src_node;
+ struct igmp_source *src;
+ long lmqc; /* Last Member Query Count */
+ long lmqi_msec; /* Last Member Query Interval */
+ long lmqt_msec; /* Last Member Query Time */
+
+ zassert(num_sources_tosend > 0);
+
+ igmp = group->group_igmp_sock;
+ pim_ifp = igmp->interface->info;
+
+ lmqc = igmp->querier_robustness_variable;
+ lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec;
+ lmqt_msec = lmqc * lmqi_msec;
+
+ /*
+ RFC3376: 6.6.3.2. Building and Sending Group and Source Specific
+ Queries
+
+ (...) for each of the sources in X of group G, with source timer
+ larger
+ than LMQT:
+ o Set number of retransmissions for each source to [Last Member
+ Query Count].
+ o Lower source timer to LMQT.
+ */
+ for (ALL_LIST_ELEMENTS_RO(group->group_source_list, src_node, src)) {
+ if (IGMP_SOURCE_TEST_SEND(src->source_flags)) {
+ /* source "src" in X of group G */
+ if (igmp_source_timer_remain_msec(src) > lmqt_msec) {
+ src->source_query_retransmit_count = lmqc;
+ igmp_source_timer_lower_to_lmqt(src);
+ }
+ }
+ }
+
+ /* send group-and-source specific queries */
+ group_retransmit_sources(group, 1 /* send_with_sflag_set=true */);
+
+ /* make sure group retransmit timer is running */
+ group_retransmit_timer_on(group);
}
-static void block_excl(struct igmp_group *group,
- int num_sources, struct in_addr *sources)
+static void block_excl(struct igmp_group *group, int num_sources,
+ struct in_addr *sources)
{
- int num_sources_tosend = 0;
- int i;
-
- /* 1. clear off SEND flag from all known sources (X,Y) */
- source_clear_send_flag(group->group_source_list);
-
- /* 2. scan received sources (A) */
- for (i = 0; i < num_sources; ++i) {
- struct igmp_source *source;
- struct in_addr *src_addr;
-
- src_addr = sources + i;
-
- /* lookup reported source (A) in known sources (X,Y) */
- source = igmp_find_source_by_addr(group, *src_addr);
- if (!source) {
- /* 3: if not found, create source with Group Timer: (A-X-Y)=Group Timer */
- long group_timer_msec;
- source = source_new(group, *src_addr);
- if (!source) {
- /* ugh, internal malloc failure, skip source */
- continue;
- }
-
- zassert(!source->t_source_timer); /* timer == 0 */
- group_timer_msec = igmp_group_timer_remain_msec(group);
- igmp_source_timer_on(group, source, group_timer_msec);
- zassert(source->t_source_timer); /* (A-X-Y) timer > 0 */
- }
-
- if (source->t_source_timer) {
- /* 4. if source timer>0 mark SEND flag: Q(G,A-Y) */
- IGMP_SOURCE_DO_SEND(source->source_flags);
- ++num_sources_tosend;
- }
- }
-
- /* 5. send sources marked with SEND flag: Q(G,A-Y) */
- if (num_sources_tosend > 0) {
- source_query_send_by_flag(group, num_sources_tosend);
- }
+ int num_sources_tosend = 0;
+ int i;
+
+ /* 1. clear off SEND flag from all known sources (X,Y) */
+ source_clear_send_flag(group->group_source_list);
+
+ /* 2. scan received sources (A) */
+ for (i = 0; i < num_sources; ++i) {
+ struct igmp_source *source;
+ struct in_addr *src_addr;
+
+ src_addr = sources + i;
+
+ /* lookup reported source (A) in known sources (X,Y) */
+ source = igmp_find_source_by_addr(group, *src_addr);
+ if (!source) {
+ /* 3: if not found, create source with Group Timer:
+ * (A-X-Y)=Group Timer */
+ long group_timer_msec;
+ source = source_new(group, *src_addr);
+ if (!source) {
+ /* ugh, internal malloc failure, skip source */
+ continue;
+ }
+
+ zassert(!source->t_source_timer); /* timer == 0 */
+ group_timer_msec = igmp_group_timer_remain_msec(group);
+ igmp_source_timer_on(group, source, group_timer_msec);
+ zassert(source->t_source_timer); /* (A-X-Y) timer > 0 */
+ }
+
+ if (source->t_source_timer) {
+ /* 4. if source timer>0 mark SEND flag: Q(G,A-Y) */
+ IGMP_SOURCE_DO_SEND(source->source_flags);
+ ++num_sources_tosend;
+ }
+ }
+
+ /* 5. send sources marked with SEND flag: Q(G,A-Y) */
+ if (num_sources_tosend > 0) {
+ source_query_send_by_flag(group, num_sources_tosend);
+ }
}
-static void block_incl(struct igmp_group *group,
- int num_sources, struct in_addr *sources)
+static void block_incl(struct igmp_group *group, int num_sources,
+ struct in_addr *sources)
{
- int num_sources_tosend = 0;
- int i;
-
- /* 1. clear off SEND flag from all known sources (B) */
- source_clear_send_flag(group->group_source_list);
-
- /* 2. scan received sources (A) */
- for (i = 0; i < num_sources; ++i) {
- struct igmp_source *source;
- struct in_addr *src_addr;
-
- src_addr = sources + i;
-
- /* lookup reported source (A) in known sources (B) */
- source = igmp_find_source_by_addr(group, *src_addr);
- if (source) {
- /* 3. if found (A*B), mark SEND flag: Q(G,A*B) */
- IGMP_SOURCE_DO_SEND(source->source_flags);
- ++num_sources_tosend;
- }
- }
-
- /* 4. send sources marked with SEND flag: Q(G,A*B) */
- if (num_sources_tosend > 0) {
- source_query_send_by_flag(group, num_sources_tosend);
- }
+ int num_sources_tosend = 0;
+ int i;
+
+ /* 1. clear off SEND flag from all known sources (B) */
+ source_clear_send_flag(group->group_source_list);
+
+ /* 2. scan received sources (A) */
+ for (i = 0; i < num_sources; ++i) {
+ struct igmp_source *source;
+ struct in_addr *src_addr;
+
+ src_addr = sources + i;
+
+ /* lookup reported source (A) in known sources (B) */
+ source = igmp_find_source_by_addr(group, *src_addr);
+ if (source) {
+ /* 3. if found (A*B), mark SEND flag: Q(G,A*B) */
+ IGMP_SOURCE_DO_SEND(source->source_flags);
+ ++num_sources_tosend;
+ }
+ }
+
+ /* 4. send sources marked with SEND flag: Q(G,A*B) */
+ if (num_sources_tosend > 0) {
+ source_query_send_by_flag(group, num_sources_tosend);
+ }
}
void igmpv3_report_block(struct igmp_sock *igmp, struct in_addr from,
- struct in_addr group_addr,
- int num_sources, struct in_addr *sources)
+ struct in_addr group_addr, int num_sources,
+ struct in_addr *sources)
{
- struct interface *ifp = igmp->interface;
- struct igmp_group *group;
-
- on_trace(__PRETTY_FUNCTION__,
- ifp, from, group_addr, num_sources, sources);
-
- /* non-existant group is created as INCLUDE {empty} */
- group = igmp_add_group_by_addr(igmp, group_addr);
- if (!group) {
- return;
- }
-
- if (group->group_filtermode_isexcl) {
- /* EXCLUDE mode */
- block_excl(group, num_sources, sources);
- }
- else {
- /* INCLUDE mode */
- block_incl(group, num_sources, sources);
- }
+ struct interface *ifp = igmp->interface;
+ struct igmp_group *group;
+
+ on_trace(__PRETTY_FUNCTION__, ifp, from, group_addr, num_sources,
+ sources);
+
+ /* non-existant group is created as INCLUDE {empty} */
+ group = igmp_add_group_by_addr(igmp, group_addr);
+ if (!group) {
+ return;
+ }
+
+ if (group->group_filtermode_isexcl) {
+ /* EXCLUDE mode */
+ block_excl(group, num_sources, sources);
+ } else {
+ /* INCLUDE mode */
+ block_incl(group, num_sources, sources);
+ }
}
void igmp_group_timer_lower_to_lmqt(struct igmp_group *group)
{
- struct igmp_sock *igmp;
- struct interface *ifp;
- struct pim_interface *pim_ifp;
- char *ifname;
- int lmqi_dsec; /* Last Member Query Interval */
- int lmqc; /* Last Member Query Count */
- int lmqt_msec; /* Last Member Query Time */
-
- /*
- RFC 3376: 6.2.2. Definition of Group Timers
-
- The group timer is only used when a group is in EXCLUDE mode and
- it represents the time for the *filter-mode* of the group to
- expire and switch to INCLUDE mode.
- */
- if (!group->group_filtermode_isexcl) {
- return;
- }
-
- igmp = group->group_igmp_sock;
- ifp = igmp->interface;
- pim_ifp = ifp->info;
- ifname = ifp->name;
-
- 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 */
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- zlog_debug("%s: group %s on %s: LMQC=%d LMQI=%d dsec LMQT=%d msec",
- __PRETTY_FUNCTION__,
- group_str, ifname,
- lmqc, lmqi_dsec, lmqt_msec);
- }
-
- zassert(group->group_filtermode_isexcl);
-
- igmp_group_timer_on(group, lmqt_msec, ifname);
+ struct igmp_sock *igmp;
+ struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ char *ifname;
+ int lmqi_dsec; /* Last Member Query Interval */
+ int lmqc; /* Last Member Query Count */
+ int lmqt_msec; /* Last Member Query Time */
+
+ /*
+ RFC 3376: 6.2.2. Definition of Group Timers
+
+ The group timer is only used when a group is in EXCLUDE mode and
+ it represents the time for the *filter-mode* of the group to
+ expire and switch to INCLUDE mode.
+ */
+ if (!group->group_filtermode_isexcl) {
+ return;
+ }
+
+ igmp = group->group_igmp_sock;
+ ifp = igmp->interface;
+ pim_ifp = ifp->info;
+ ifname = ifp->name;
+
+ 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 */
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group->group_addr, group_str,
+ sizeof(group_str));
+ zlog_debug(
+ "%s: group %s on %s: LMQC=%d LMQI=%d dsec LMQT=%d msec",
+ __PRETTY_FUNCTION__, group_str, ifname, lmqc, lmqi_dsec,
+ lmqt_msec);
+ }
+
+ zassert(group->group_filtermode_isexcl);
+
+ igmp_group_timer_on(group, lmqt_msec, ifname);
}
void igmp_source_timer_lower_to_lmqt(struct igmp_source *source)
{
- struct igmp_group *group;
- struct igmp_sock *igmp;
- struct interface *ifp;
- struct pim_interface *pim_ifp;
- char *ifname;
- int lmqi_dsec; /* Last Member Query Interval */
- int lmqc; /* Last Member Query Count */
- int lmqt_msec; /* Last Member Query Time */
-
- group = source->source_group;
- igmp = group->group_igmp_sock;
- ifp = igmp->interface;
- pim_ifp = ifp->info;
- ifname = ifp->name;
-
- 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 */
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
- zlog_debug("%s: group %s source %s on %s: LMQC=%d LMQI=%d dsec LMQT=%d msec",
- __PRETTY_FUNCTION__,
- group_str, source_str, ifname,
- lmqc, lmqi_dsec, lmqt_msec);
- }
-
- igmp_source_timer_on(group, source, lmqt_msec);
+ struct igmp_group *group;
+ struct igmp_sock *igmp;
+ struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ char *ifname;
+ int lmqi_dsec; /* Last Member Query Interval */
+ int lmqc; /* Last Member Query Count */
+ int lmqt_msec; /* Last Member Query Time */
+
+ group = source->source_group;
+ igmp = group->group_igmp_sock;
+ ifp = igmp->interface;
+ pim_ifp = ifp->info;
+ ifname = ifp->name;
+
+ 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 */
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group->group_addr, group_str,
+ sizeof(group_str));
+ pim_inet4_dump("<source?>", source->source_addr, source_str,
+ sizeof(source_str));
+ zlog_debug(
+ "%s: group %s source %s on %s: LMQC=%d LMQI=%d dsec LMQT=%d msec",
+ __PRETTY_FUNCTION__, group_str, source_str, ifname,
+ lmqc, lmqi_dsec, lmqt_msec);
+ }
+
+ igmp_source_timer_on(group, source, lmqt_msec);
}
-void
-igmp_v3_send_query (struct igmp_group *group,
- int fd,
- const char *ifname,
- char *query_buf,
- int query_buf_size,
- int num_sources,
- struct in_addr dst_addr,
- struct in_addr group_addr,
- int query_max_response_time_dsec,
- uint8_t s_flag,
- uint8_t querier_robustness_variable,
- uint16_t querier_query_interval)
+void igmp_v3_send_query(struct igmp_group *group, int fd, const char *ifname,
+ char *query_buf, int query_buf_size, int num_sources,
+ struct in_addr dst_addr, struct in_addr group_addr,
+ int query_max_response_time_dsec, uint8_t s_flag,
+ uint8_t querier_robustness_variable,
+ uint16_t querier_query_interval)
{
- ssize_t msg_size;
- uint8_t max_resp_code;
- uint8_t qqic;
- ssize_t sent;
- struct sockaddr_in to;
- socklen_t tolen;
- uint16_t checksum;
-
- zassert(num_sources >= 0);
-
- msg_size = IGMP_V3_SOURCES_OFFSET + (num_sources << 2);
- if (msg_size > query_buf_size) {
- zlog_err("%s %s: unable to send: msg_size=%zd larger than query_buf_size=%d",
- __FILE__, __PRETTY_FUNCTION__,
- msg_size, query_buf_size);
- return;
- }
-
- s_flag = PIM_FORCE_BOOLEAN(s_flag);
- zassert((s_flag == 0) || (s_flag == 1));
-
- max_resp_code = igmp_msg_encode16to8(query_max_response_time_dsec);
- qqic = igmp_msg_encode16to8(querier_query_interval);
-
- /*
- RFC 3376: 4.1.6. QRV (Querier's Robustness Variable)
-
- If non-zero, the QRV field contains the [Robustness Variable]
- value used by the querier, i.e., the sender of the Query. If the
- querier's [Robustness Variable] exceeds 7, the maximum value of
- the QRV field, the QRV is set to zero.
- */
- if (querier_robustness_variable > 7) {
- querier_robustness_variable = 0;
- }
-
- query_buf[0] = PIM_IGMP_MEMBERSHIP_QUERY;
- query_buf[1] = max_resp_code;
- *(uint16_t *)(query_buf + IGMP_CHECKSUM_OFFSET) = 0; /* for computing checksum */
- memcpy(query_buf+4, &group_addr, sizeof(struct in_addr));
-
- query_buf[8] = (s_flag << 3) | querier_robustness_variable;
- query_buf[9] = qqic;
- *(uint16_t *)(query_buf + IGMP_V3_NUMSOURCES_OFFSET) = htons(num_sources);
-
- checksum = in_cksum(query_buf, msg_size);
- *(uint16_t *)(query_buf + IGMP_CHECKSUM_OFFSET) = checksum;
-
- if (PIM_DEBUG_IGMP_PACKETS) {
- char dst_str[INET_ADDRSTRLEN];
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<dst?>", dst_addr, dst_str, sizeof(dst_str));
- pim_inet4_dump("<group?>", group_addr, group_str, sizeof(group_str));
- zlog_debug("Send IGMPv3 query to %s on %s for group %s, sources=%d msg_size=%zd s_flag=%x QRV=%u QQI=%u QQIC=%02x",
- dst_str, ifname, group_str,
- num_sources, msg_size, s_flag, querier_robustness_variable,
- querier_query_interval, qqic);
- }
-
- memset(&to, 0, sizeof(to));
- to.sin_family = AF_INET;
- to.sin_addr = dst_addr;
- tolen = sizeof(to);
-
- sent = sendto(fd, query_buf, msg_size, MSG_DONTWAIT,
- (struct sockaddr *)&to, tolen);
- if (sent != (ssize_t) msg_size) {
- char dst_str[INET_ADDRSTRLEN];
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<dst?>", dst_addr, dst_str, sizeof(dst_str));
- pim_inet4_dump("<group?>", group_addr, group_str, sizeof(group_str));
- if (sent < 0) {
- zlog_warn("Send IGMPv3 query failed due to %s on %s: group=%s msg_size=%zd: errno=%d: %s",
- dst_str, ifname, group_str, msg_size, errno, safe_strerror(errno));
- }
- else {
- zlog_warn("Send IGMPv3 query failed due to %s on %s: group=%s msg_size=%zd: sent=%zd",
- dst_str, ifname, group_str, msg_size, sent);
- }
- return;
- }
-
- /*
- s_flag sanity test: s_flag must be set for general queries
-
- RFC 3376: 6.6.1. Timer Updates
-
- When a router sends or receives a query with a clear Suppress
- Router-Side Processing flag, it must update its timers to reflect
- the correct timeout values for the group or sources being queried.
-
- General queries don't trigger timer update.
- */
- if (!s_flag) {
- /* general query? */
- if (PIM_INADDR_IS_ANY(group_addr)) {
- char dst_str[INET_ADDRSTRLEN];
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<dst?>", dst_addr, dst_str, sizeof(dst_str));
- pim_inet4_dump("<group?>", group_addr, group_str, sizeof(group_str));
- zlog_warn("%s: to %s on %s: group=%s sources=%d: s_flag is clear for general query!",
- __PRETTY_FUNCTION__,
- dst_str, ifname, group_str, num_sources);
- }
- }
+ ssize_t msg_size;
+ uint8_t max_resp_code;
+ uint8_t qqic;
+ ssize_t sent;
+ struct sockaddr_in to;
+ socklen_t tolen;
+ uint16_t checksum;
+
+ zassert(num_sources >= 0);
+
+ msg_size = IGMP_V3_SOURCES_OFFSET + (num_sources << 2);
+ if (msg_size > query_buf_size) {
+ zlog_err(
+ "%s %s: unable to send: msg_size=%zd larger than query_buf_size=%d",
+ __FILE__, __PRETTY_FUNCTION__, msg_size,
+ query_buf_size);
+ return;
+ }
+
+ s_flag = PIM_FORCE_BOOLEAN(s_flag);
+ zassert((s_flag == 0) || (s_flag == 1));
+
+ max_resp_code = igmp_msg_encode16to8(query_max_response_time_dsec);
+ qqic = igmp_msg_encode16to8(querier_query_interval);
+
+ /*
+ RFC 3376: 4.1.6. QRV (Querier's Robustness Variable)
+
+ If non-zero, the QRV field contains the [Robustness Variable]
+ value used by the querier, i.e., the sender of the Query. If the
+ querier's [Robustness Variable] exceeds 7, the maximum value of
+ the QRV field, the QRV is set to zero.
+ */
+ if (querier_robustness_variable > 7) {
+ querier_robustness_variable = 0;
+ }
+
+ query_buf[0] = PIM_IGMP_MEMBERSHIP_QUERY;
+ query_buf[1] = max_resp_code;
+ *(uint16_t *)(query_buf + IGMP_CHECKSUM_OFFSET) =
+ 0; /* for computing checksum */
+ memcpy(query_buf + 4, &group_addr, sizeof(struct in_addr));
+
+ query_buf[8] = (s_flag << 3) | querier_robustness_variable;
+ query_buf[9] = qqic;
+ *(uint16_t *)(query_buf + IGMP_V3_NUMSOURCES_OFFSET) =
+ htons(num_sources);
+
+ checksum = in_cksum(query_buf, msg_size);
+ *(uint16_t *)(query_buf + IGMP_CHECKSUM_OFFSET) = checksum;
+
+ if (PIM_DEBUG_IGMP_PACKETS) {
+ char dst_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<dst?>", dst_addr, dst_str, sizeof(dst_str));
+ pim_inet4_dump("<group?>", group_addr, group_str,
+ sizeof(group_str));
+ zlog_debug(
+ "Send IGMPv3 query to %s on %s for group %s, sources=%d msg_size=%zd s_flag=%x QRV=%u QQI=%u QQIC=%02x",
+ dst_str, ifname, group_str, num_sources, msg_size,
+ s_flag, querier_robustness_variable,
+ querier_query_interval, qqic);
+ }
+
+ memset(&to, 0, sizeof(to));
+ to.sin_family = AF_INET;
+ to.sin_addr = dst_addr;
+ tolen = sizeof(to);
+
+ sent = sendto(fd, query_buf, msg_size, MSG_DONTWAIT,
+ (struct sockaddr *)&to, tolen);
+ if (sent != (ssize_t)msg_size) {
+ char dst_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<dst?>", dst_addr, dst_str, sizeof(dst_str));
+ pim_inet4_dump("<group?>", group_addr, group_str,
+ sizeof(group_str));
+ if (sent < 0) {
+ zlog_warn(
+ "Send IGMPv3 query failed due to %s on %s: group=%s msg_size=%zd: errno=%d: %s",
+ dst_str, ifname, group_str, msg_size, errno,
+ safe_strerror(errno));
+ } else {
+ zlog_warn(
+ "Send IGMPv3 query failed due to %s on %s: group=%s msg_size=%zd: sent=%zd",
+ dst_str, ifname, group_str, msg_size, sent);
+ }
+ return;
+ }
+
+ /*
+ s_flag sanity test: s_flag must be set for general queries
+
+ RFC 3376: 6.6.1. Timer Updates
+
+ When a router sends or receives a query with a clear Suppress
+ Router-Side Processing flag, it must update its timers to reflect
+ the correct timeout values for the group or sources being queried.
+
+ General queries don't trigger timer update.
+ */
+ if (!s_flag) {
+ /* general query? */
+ if (PIM_INADDR_IS_ANY(group_addr)) {
+ char dst_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<dst?>", dst_addr, dst_str,
+ sizeof(dst_str));
+ pim_inet4_dump("<group?>", group_addr, group_str,
+ sizeof(group_str));
+ zlog_warn(
+ "%s: to %s on %s: group=%s sources=%d: s_flag is clear for general query!",
+ __PRETTY_FUNCTION__, dst_str, ifname, group_str,
+ num_sources);
+ }
+ }
}
-void
-igmp_v3_recv_query (struct igmp_sock *igmp, const char *from_str, char *igmp_msg)
+void igmp_v3_recv_query(struct igmp_sock *igmp, const char *from_str,
+ char *igmp_msg)
{
- struct interface *ifp;
- struct pim_interface *pim_ifp;
- struct in_addr group_addr;
- uint8_t resv_s_qrv = 0;
- uint8_t s_flag = 0;
- uint8_t qrv = 0;
- int i;
-
- memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
- ifp = igmp->interface;
- pim_ifp = ifp->info;
-
- /*
- * RFC 3376: 4.1.6. QRV (Querier's Robustness Variable)
- *
- * Routers adopt the QRV value from the most recently received Query
- * as their own [Robustness Variable] value, unless that most
- * recently received QRV was zero, in which case the receivers use
- * the default [Robustness Variable] value specified in section 8.1
- * or a statically configured value.
- */
- resv_s_qrv = igmp_msg[8];
- qrv = 7 & resv_s_qrv;
- igmp->querier_robustness_variable = qrv ? qrv : pim_ifp->igmp_default_robustness_variable;
-
- /*
- * RFC 3376: 4.1.7. QQIC (Querier's Query Interval Code)
- *
- * Multicast routers that are not the current querier adopt the QQI
- * value from the most recently received Query as their own [Query
- * Interval] value, unless that most recently received QQI was zero,
- * in which case the receiving routers use the default.
- */
- if (igmp->t_other_querier_timer) {
- /* other querier present */
- uint8_t qqic;
- uint16_t qqi;
- qqic = igmp_msg[9];
- qqi = igmp_msg_decode8to16(qqic);
- igmp->querier_query_interval = qqi ? qqi : pim_ifp->igmp_default_query_interval;
-
- if (PIM_DEBUG_IGMP_TRACE) {
- char ifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
- zlog_debug("Querier %s new query interval is %s QQI=%u sec (recv QQIC=%02x from %s)",
- ifaddr_str,
- qqi ? "recv-non-default" : "default",
- igmp->querier_query_interval,
- qqic,
- from_str);
- }
- }
-
- /*
- * RFC 3376: 6.6.1. Timer Updates
- *
- * When a router sends or receives a query with a clear Suppress
- * Router-Side Processing flag, it must update its timers to reflect
- * the correct timeout values for the group or sources being queried.
- *
- * General queries don't trigger timer update.
- */
- s_flag = (1 << 3) & resv_s_qrv;
-
- if (!s_flag) {
- /* s_flag is clear */
-
- if (PIM_INADDR_IS_ANY(group_addr)) {
- /* this is a general query */
- /* log that general query should have the s_flag set */
- zlog_warn("General IGMP query v3 from %s on %s: Suppress Router-Side Processing flag is clear",
- from_str, ifp->name);
- } else {
- struct igmp_group *group;
-
- /* this is a non-general query: perform timer updates */
-
- group = find_group_by_addr(igmp, group_addr);
- if (group) {
- int recv_num_sources = ntohs(*(uint16_t *)(igmp_msg + IGMP_V3_NUMSOURCES_OFFSET));
-
- /*
- * RFC 3376: 6.6.1. Timer Updates
- * Query Q(G,A): Source Timer for sources in A are lowered to LMQT
- * Query Q(G): Group Timer is lowered to LMQT
- */
- if (recv_num_sources < 1) {
- /* Query Q(G): Group Timer is lowered to LMQT */
-
- igmp_group_timer_lower_to_lmqt(group);
- } else {
- /* Query Q(G,A): Source Timer for sources in A are lowered to LMQT */
-
- /* Scan sources in query and lower their timers to LMQT */
- struct in_addr *sources = (struct in_addr *)(igmp_msg + IGMP_V3_SOURCES_OFFSET);
- for (i = 0; i < recv_num_sources; ++i) {
- struct in_addr src_addr;
- struct igmp_source *src;
- memcpy(&src_addr, sources + i, sizeof(struct in_addr));
- src = igmp_find_source_by_addr(group, src_addr);
- if (src) {
- igmp_source_timer_lower_to_lmqt(src);
- }
- }
- }
- } else {
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", group_addr, group_str, sizeof(group_str));
- zlog_warn("IGMP query v3 from %s on %s: could not find group %s for timer update",
- from_str, ifp->name, group_str);
- }
- }
- } /* s_flag is clear: timer updates */
+ struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ struct in_addr group_addr;
+ uint8_t resv_s_qrv = 0;
+ uint8_t s_flag = 0;
+ uint8_t qrv = 0;
+ int i;
+
+ memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
+ ifp = igmp->interface;
+ pim_ifp = ifp->info;
+
+ /*
+ * RFC 3376: 4.1.6. QRV (Querier's Robustness Variable)
+ *
+ * Routers adopt the QRV value from the most recently received Query
+ * as their own [Robustness Variable] value, unless that most
+ * recently received QRV was zero, in which case the receivers use
+ * the default [Robustness Variable] value specified in section 8.1
+ * or a statically configured value.
+ */
+ resv_s_qrv = igmp_msg[8];
+ qrv = 7 & resv_s_qrv;
+ igmp->querier_robustness_variable =
+ qrv ? qrv : pim_ifp->igmp_default_robustness_variable;
+
+ /*
+ * RFC 3376: 4.1.7. QQIC (Querier's Query Interval Code)
+ *
+ * Multicast routers that are not the current querier adopt the QQI
+ * value from the most recently received Query as their own [Query
+ * Interval] value, unless that most recently received QQI was zero,
+ * in which case the receiving routers use the default.
+ */
+ if (igmp->t_other_querier_timer) {
+ /* other querier present */
+ uint8_t qqic;
+ uint16_t qqi;
+ qqic = igmp_msg[9];
+ qqi = igmp_msg_decode8to16(qqic);
+ igmp->querier_query_interval =
+ qqi ? qqi : pim_ifp->igmp_default_query_interval;
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char ifaddr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
+ sizeof(ifaddr_str));
+ zlog_debug(
+ "Querier %s new query interval is %s QQI=%u sec (recv QQIC=%02x from %s)",
+ ifaddr_str,
+ qqi ? "recv-non-default" : "default",
+ igmp->querier_query_interval, qqic, from_str);
+ }
+ }
+
+ /*
+ * RFC 3376: 6.6.1. Timer Updates
+ *
+ * When a router sends or receives a query with a clear Suppress
+ * Router-Side Processing flag, it must update its timers to reflect
+ * the correct timeout values for the group or sources being queried.
+ *
+ * General queries don't trigger timer update.
+ */
+ s_flag = (1 << 3) & resv_s_qrv;
+
+ if (!s_flag) {
+ /* s_flag is clear */
+
+ if (PIM_INADDR_IS_ANY(group_addr)) {
+ /* this is a general query */
+ /* log that general query should have the s_flag set */
+ zlog_warn(
+ "General IGMP query v3 from %s on %s: Suppress Router-Side Processing flag is clear",
+ from_str, ifp->name);
+ } else {
+ struct igmp_group *group;
+
+ /* this is a non-general query: perform timer updates */
+
+ group = find_group_by_addr(igmp, group_addr);
+ if (group) {
+ int recv_num_sources = ntohs(*(
+ uint16_t
+ *)(igmp_msg
+ + IGMP_V3_NUMSOURCES_OFFSET));
+
+ /*
+ * RFC 3376: 6.6.1. Timer Updates
+ * Query Q(G,A): Source Timer for sources in A
+ * are lowered to LMQT
+ * Query Q(G): Group Timer is lowered to LMQT
+ */
+ if (recv_num_sources < 1) {
+ /* Query Q(G): Group Timer is lowered to
+ * LMQT */
+
+ igmp_group_timer_lower_to_lmqt(group);
+ } else {
+ /* Query Q(G,A): Source Timer for
+ * sources in A are lowered to LMQT */
+
+ /* Scan sources in query and lower their
+ * timers to LMQT */
+ struct in_addr *sources =
+ (struct in_addr
+ *)(igmp_msg
+ + IGMP_V3_SOURCES_OFFSET);
+ for (i = 0; i < recv_num_sources; ++i) {
+ struct in_addr src_addr;
+ struct igmp_source *src;
+ memcpy(&src_addr, sources + i,
+ sizeof(struct in_addr));
+ src = igmp_find_source_by_addr(
+ group, src_addr);
+ if (src) {
+ igmp_source_timer_lower_to_lmqt(
+ src);
+ }
+ }
+ }
+ } else {
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", group_addr,
+ group_str, sizeof(group_str));
+ zlog_warn(
+ "IGMP query v3 from %s on %s: could not find group %s for timer update",
+ from_str, ifp->name, group_str);
+ }
+ }
+ } /* s_flag is clear: timer updates */
}
-int
-igmp_v3_recv_report (struct igmp_sock *igmp,
- struct in_addr from, const char *from_str,
- char *igmp_msg, int igmp_msg_len)
+int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from,
+ const char *from_str, char *igmp_msg, int igmp_msg_len)
{
- uint16_t recv_checksum;
- uint16_t checksum;
- int num_groups;
- uint8_t *group_record;
- uint8_t *report_pastend = (uint8_t *) igmp_msg + igmp_msg_len;
- struct interface *ifp = igmp->interface;
- int i;
- int local_ncb = 0;
-
- if (igmp_msg_len < IGMP_V3_MSG_MIN_SIZE) {
- zlog_warn("Recv IGMP report v3 from %s on %s: size=%d shorter than minimum=%d",
- from_str, ifp->name, igmp_msg_len, IGMP_V3_MSG_MIN_SIZE);
- return -1;
- }
-
- recv_checksum = *(uint16_t *) (igmp_msg + IGMP_CHECKSUM_OFFSET);
-
- /* for computing checksum */
- *(uint16_t *) (igmp_msg + IGMP_CHECKSUM_OFFSET) = 0;
-
- checksum = in_cksum(igmp_msg, igmp_msg_len);
- if (checksum != recv_checksum) {
- zlog_warn("Recv IGMP report v3 from %s on %s: checksum mismatch: received=%x computed=%x",
- from_str, ifp->name, recv_checksum, checksum);
- return -1;
- }
-
- num_groups = ntohs(*(uint16_t *) (igmp_msg + IGMP_V3_REPORT_NUMGROUPS_OFFSET));
- if (num_groups < 1) {
- zlog_warn("Recv IGMP report v3 from %s on %s: missing group records",
- from_str, ifp->name);
- return -1;
- }
-
- if (PIM_DEBUG_IGMP_PACKETS) {
- zlog_debug("Recv IGMP report v3 from %s on %s: size=%d checksum=%x groups=%d",
- from_str, ifp->name, igmp_msg_len, checksum, num_groups);
- }
-
- group_record = (uint8_t *) igmp_msg + IGMP_V3_REPORT_GROUPPRECORD_OFFSET;
-
- /* Scan groups */
- for (i = 0; i < num_groups; ++i) {
- struct in_addr rec_group;
- uint8_t *sources;
- uint8_t *src;
- int rec_type;
- int rec_auxdatalen;
- int rec_num_sources;
- int j;
- struct prefix lncb;
- struct prefix g;
-
- if ((group_record + IGMP_V3_GROUP_RECORD_MIN_SIZE) > report_pastend) {
- zlog_warn("Recv IGMP report v3 from %s on %s: group record beyond report end",
- from_str, ifp->name);
- return -1;
- }
-
- rec_type = group_record[IGMP_V3_GROUP_RECORD_TYPE_OFFSET];
- rec_auxdatalen = group_record[IGMP_V3_GROUP_RECORD_AUXDATALEN_OFFSET];
- rec_num_sources = ntohs(* (uint16_t *) (group_record + IGMP_V3_GROUP_RECORD_NUMSOURCES_OFFSET));
-
- memcpy(&rec_group, group_record + IGMP_V3_GROUP_RECORD_GROUP_OFFSET, sizeof(struct in_addr));
-
- if (PIM_DEBUG_IGMP_PACKETS) {
- zlog_debug("Recv IGMP report v3 from %s on %s: record=%d type=%d auxdatalen=%d sources=%d group=%s",
- from_str, ifp->name, i, rec_type, rec_auxdatalen, rec_num_sources, inet_ntoa(rec_group));
- }
-
- /* Scan sources */
-
- sources = group_record + IGMP_V3_GROUP_RECORD_SOURCE_OFFSET;
-
- for (j = 0, src = sources; j < rec_num_sources; ++j, src += 4) {
-
- if ((src + 4) > report_pastend) {
- zlog_warn("Recv IGMP report v3 from %s on %s: group source beyond report end",
- from_str, ifp->name);
- return -1;
- }
-
- if (PIM_DEBUG_IGMP_PACKETS) {
- char src_str[200];
-
- if (!inet_ntop(AF_INET, src, src_str , sizeof(src_str)))
- sprintf(src_str, "<source?>");
-
- zlog_debug("Recv IGMP report v3 from %s on %s: record=%d group=%s source=%s",
- from_str, ifp->name, i, inet_ntoa(rec_group), src_str);
- }
- } /* for (sources) */
-
-
- lncb.family = AF_INET;
- lncb.u.prefix4.s_addr = 0x000000E0;
- lncb.prefixlen = 24;
-
- g.family = AF_INET;
- g.u.prefix4 = rec_group;
- g.prefixlen = 32;
- /*
- * If we receive a igmp report with the group in 224.0.0.0/24
- * then we should ignore it
- */
- if (prefix_match(&lncb, &g))
- local_ncb = 1;
-
- if (!local_ncb)
- switch (rec_type) {
- case IGMP_GRP_REC_TYPE_MODE_IS_INCLUDE:
- igmpv3_report_isin(igmp, from, rec_group, rec_num_sources, (struct in_addr *) sources);
- break;
- case IGMP_GRP_REC_TYPE_MODE_IS_EXCLUDE:
- igmpv3_report_isex(igmp, from, rec_group, rec_num_sources, (struct in_addr *) sources, 0);
- break;
- case IGMP_GRP_REC_TYPE_CHANGE_TO_INCLUDE_MODE:
- igmpv3_report_toin(igmp, from, rec_group, rec_num_sources, (struct in_addr *) sources);
- break;
- case IGMP_GRP_REC_TYPE_CHANGE_TO_EXCLUDE_MODE:
- igmpv3_report_toex(igmp, from, rec_group, rec_num_sources, (struct in_addr *) sources);
- break;
- case IGMP_GRP_REC_TYPE_ALLOW_NEW_SOURCES:
- igmpv3_report_allow(igmp, from, rec_group, rec_num_sources, (struct in_addr *) sources);
- break;
- case IGMP_GRP_REC_TYPE_BLOCK_OLD_SOURCES:
- igmpv3_report_block(igmp, from, rec_group, rec_num_sources, (struct in_addr *) sources);
- break;
- default:
- zlog_warn("Recv IGMP report v3 from %s on %s: unknown record type: type=%d",
- from_str, ifp->name, rec_type);
- }
-
- group_record += 8 + (rec_num_sources << 2) + (rec_auxdatalen << 2);
- local_ncb = 0;
-
- } /* for (group records) */
-
- return 0;
+ uint16_t recv_checksum;
+ uint16_t checksum;
+ int num_groups;
+ uint8_t *group_record;
+ uint8_t *report_pastend = (uint8_t *)igmp_msg + igmp_msg_len;
+ struct interface *ifp = igmp->interface;
+ int i;
+ int local_ncb = 0;
+
+ if (igmp_msg_len < IGMP_V3_MSG_MIN_SIZE) {
+ zlog_warn(
+ "Recv IGMP report v3 from %s on %s: size=%d shorter than minimum=%d",
+ from_str, ifp->name, igmp_msg_len,
+ IGMP_V3_MSG_MIN_SIZE);
+ return -1;
+ }
+
+ recv_checksum = *(uint16_t *)(igmp_msg + IGMP_CHECKSUM_OFFSET);
+
+ /* for computing checksum */
+ *(uint16_t *)(igmp_msg + IGMP_CHECKSUM_OFFSET) = 0;
+
+ checksum = in_cksum(igmp_msg, igmp_msg_len);
+ if (checksum != recv_checksum) {
+ zlog_warn(
+ "Recv IGMP report v3 from %s on %s: checksum mismatch: received=%x computed=%x",
+ from_str, ifp->name, recv_checksum, checksum);
+ return -1;
+ }
+
+ num_groups = ntohs(
+ *(uint16_t *)(igmp_msg + IGMP_V3_REPORT_NUMGROUPS_OFFSET));
+ if (num_groups < 1) {
+ zlog_warn(
+ "Recv IGMP report v3 from %s on %s: missing group records",
+ from_str, ifp->name);
+ return -1;
+ }
+
+ if (PIM_DEBUG_IGMP_PACKETS) {
+ zlog_debug(
+ "Recv IGMP report v3 from %s on %s: size=%d checksum=%x groups=%d",
+ from_str, ifp->name, igmp_msg_len, checksum,
+ num_groups);
+ }
+
+ group_record = (uint8_t *)igmp_msg + IGMP_V3_REPORT_GROUPPRECORD_OFFSET;
+
+ /* Scan groups */
+ for (i = 0; i < num_groups; ++i) {
+ struct in_addr rec_group;
+ uint8_t *sources;
+ uint8_t *src;
+ int rec_type;
+ int rec_auxdatalen;
+ int rec_num_sources;
+ int j;
+ struct prefix lncb;
+ struct prefix g;
+
+ if ((group_record + IGMP_V3_GROUP_RECORD_MIN_SIZE)
+ > report_pastend) {
+ zlog_warn(
+ "Recv IGMP report v3 from %s on %s: group record beyond report end",
+ from_str, ifp->name);
+ return -1;
+ }
+
+ rec_type = group_record[IGMP_V3_GROUP_RECORD_TYPE_OFFSET];
+ rec_auxdatalen =
+ group_record[IGMP_V3_GROUP_RECORD_AUXDATALEN_OFFSET];
+ rec_num_sources = ntohs(*(
+ uint16_t *)(group_record
+ + IGMP_V3_GROUP_RECORD_NUMSOURCES_OFFSET));
+
+ memcpy(&rec_group,
+ group_record + IGMP_V3_GROUP_RECORD_GROUP_OFFSET,
+ sizeof(struct in_addr));
+
+ if (PIM_DEBUG_IGMP_PACKETS) {
+ zlog_debug(
+ "Recv IGMP report v3 from %s on %s: record=%d type=%d auxdatalen=%d sources=%d group=%s",
+ from_str, ifp->name, i, rec_type,
+ rec_auxdatalen, rec_num_sources,
+ inet_ntoa(rec_group));
+ }
+
+ /* Scan sources */
+
+ sources = group_record + IGMP_V3_GROUP_RECORD_SOURCE_OFFSET;
+
+ for (j = 0, src = sources; j < rec_num_sources; ++j, src += 4) {
+
+ if ((src + 4) > report_pastend) {
+ zlog_warn(
+ "Recv IGMP report v3 from %s on %s: group source beyond report end",
+ from_str, ifp->name);
+ return -1;
+ }
+
+ if (PIM_DEBUG_IGMP_PACKETS) {
+ char src_str[200];
+
+ if (!inet_ntop(AF_INET, src, src_str,
+ sizeof(src_str)))
+ sprintf(src_str, "<source?>");
+
+ zlog_debug(
+ "Recv IGMP report v3 from %s on %s: record=%d group=%s source=%s",
+ from_str, ifp->name, i,
+ inet_ntoa(rec_group), src_str);
+ }
+ } /* for (sources) */
+
+
+ lncb.family = AF_INET;
+ lncb.u.prefix4.s_addr = 0x000000E0;
+ lncb.prefixlen = 24;
+
+ g.family = AF_INET;
+ g.u.prefix4 = rec_group;
+ g.prefixlen = 32;
+ /*
+ * If we receive a igmp report with the group in 224.0.0.0/24
+ * then we should ignore it
+ */
+ if (prefix_match(&lncb, &g))
+ local_ncb = 1;
+
+ if (!local_ncb)
+ switch (rec_type) {
+ case IGMP_GRP_REC_TYPE_MODE_IS_INCLUDE:
+ igmpv3_report_isin(igmp, from, rec_group,
+ rec_num_sources,
+ (struct in_addr *)sources);
+ break;
+ case IGMP_GRP_REC_TYPE_MODE_IS_EXCLUDE:
+ igmpv3_report_isex(
+ igmp, from, rec_group, rec_num_sources,
+ (struct in_addr *)sources, 0);
+ break;
+ case IGMP_GRP_REC_TYPE_CHANGE_TO_INCLUDE_MODE:
+ igmpv3_report_toin(igmp, from, rec_group,
+ rec_num_sources,
+ (struct in_addr *)sources);
+ break;
+ case IGMP_GRP_REC_TYPE_CHANGE_TO_EXCLUDE_MODE:
+ igmpv3_report_toex(igmp, from, rec_group,
+ rec_num_sources,
+ (struct in_addr *)sources);
+ break;
+ case IGMP_GRP_REC_TYPE_ALLOW_NEW_SOURCES:
+ igmpv3_report_allow(igmp, from, rec_group,
+ rec_num_sources,
+ (struct in_addr *)sources);
+ break;
+ case IGMP_GRP_REC_TYPE_BLOCK_OLD_SOURCES:
+ igmpv3_report_block(igmp, from, rec_group,
+ rec_num_sources,
+ (struct in_addr *)sources);
+ break;
+ default:
+ zlog_warn(
+ "Recv IGMP report v3 from %s on %s: unknown record type: type=%d",
+ from_str, ifp->name, rec_type);
+ }
+
+ group_record +=
+ 8 + (rec_num_sources << 2) + (rec_auxdatalen << 2);
+ local_ncb = 0;
+
+ } /* for (group records) */
+
+ return 0;
}
diff --git a/pimd/pim_igmpv3.h b/pimd/pim_igmpv3.h
index 99f7b84b8..6abaef6e2 100644
--- a/pimd/pim_igmpv3.h
+++ b/pimd/pim_igmpv3.h
@@ -52,8 +52,7 @@
#define PIM_IGMP_OHPI_DSEC(qrv,qqi,qri_dsec) ((qrv) * (10 * (qqi)) + (qri_dsec))
void igmp_group_reset_gmi(struct igmp_group *group);
-void igmp_source_reset_gmi(struct igmp_sock *igmp,
- struct igmp_group *group,
+void igmp_source_reset_gmi(struct igmp_sock *igmp, struct igmp_group *group,
struct igmp_source *source);
void igmp_source_free(struct igmp_source *source);
@@ -61,24 +60,23 @@ void igmp_source_delete(struct igmp_source *source);
void igmp_source_delete_expired(struct list *source_list);
void igmpv3_report_isin(struct igmp_sock *igmp, struct in_addr from,
- struct in_addr group_addr,
- int num_sources, struct in_addr *sources);
+ struct in_addr group_addr, int num_sources,
+ struct in_addr *sources);
void igmpv3_report_isex(struct igmp_sock *igmp, struct in_addr from,
- struct in_addr group_addr,
- int num_sources, struct in_addr *sources,
- int from_igmp_v2_report);
+ struct in_addr group_addr, int num_sources,
+ struct in_addr *sources, int from_igmp_v2_report);
void igmpv3_report_toin(struct igmp_sock *igmp, struct in_addr from,
- struct in_addr group_addr,
- int num_sources, struct in_addr *sources);
+ struct in_addr group_addr, int num_sources,
+ struct in_addr *sources);
void igmpv3_report_toex(struct igmp_sock *igmp, struct in_addr from,
- struct in_addr group_addr,
- int num_sources, struct in_addr *sources);
+ struct in_addr group_addr, int num_sources,
+ struct in_addr *sources);
void igmpv3_report_allow(struct igmp_sock *igmp, struct in_addr from,
- struct in_addr group_addr,
- int num_sources, struct in_addr *sources);
+ struct in_addr group_addr, int num_sources,
+ struct in_addr *sources);
void igmpv3_report_block(struct igmp_sock *igmp, struct in_addr from,
- struct in_addr group_addr,
- int num_sources, struct in_addr *sources);
+ struct in_addr group_addr, int num_sources,
+ struct in_addr *sources);
void igmp_group_timer_lower_to_lmqt(struct igmp_group *group);
void igmp_source_timer_lower_to_lmqt(struct igmp_source *source);
@@ -86,24 +84,17 @@ void igmp_source_timer_lower_to_lmqt(struct igmp_source *source);
struct igmp_source *igmp_find_source_by_addr(struct igmp_group *group,
struct in_addr src_addr);
-void igmp_v3_send_query (struct igmp_group *group,
- int fd,
- const char *ifname,
- char *query_buf,
- int query_buf_size,
- int num_sources,
- struct in_addr dst_addr,
- struct in_addr group_addr,
- int query_max_response_time_dsec,
- uint8_t s_flag,
- uint8_t querier_robustness_variable,
- uint16_t querier_query_interval);
-
-void igmp_v3_recv_query (struct igmp_sock *igmp, const char *from_str,
- char *igmp_msg);
-
-int igmp_v3_recv_report (struct igmp_sock *igmp,
- struct in_addr from, const char *from_str,
- char *igmp_msg, int igmp_msg_len);
+void igmp_v3_send_query(struct igmp_group *group, int fd, const char *ifname,
+ char *query_buf, int query_buf_size, int num_sources,
+ struct in_addr dst_addr, struct in_addr group_addr,
+ int query_max_response_time_dsec, uint8_t s_flag,
+ uint8_t querier_robustness_variable,
+ uint16_t querier_query_interval);
+
+void igmp_v3_recv_query(struct igmp_sock *igmp, const char *from_str,
+ char *igmp_msg);
+
+int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from,
+ const char *from_str, char *igmp_msg, int igmp_msg_len);
#endif /* PIM_IGMPV3_H */
diff --git a/pimd/pim_int.c b/pimd/pim_int.c
index 577bf15c6..377839906 100644
--- a/pimd/pim_int.c
+++ b/pimd/pim_int.c
@@ -27,18 +27,18 @@
uint32_t pim_read_uint32_host(const uint8_t *buf)
{
- uint32_t val;
- memcpy(&val, buf, sizeof(val));
- /* val is in netorder */
- val = ntohl(val);
- /* val is in hostorder */
- return val;
+ uint32_t val;
+ memcpy(&val, buf, sizeof(val));
+ /* val is in netorder */
+ val = ntohl(val);
+ /* val is in hostorder */
+ return val;
}
void pim_write_uint32(uint8_t *buf, uint32_t val_host)
{
- /* val_host is in host order */
- val_host = htonl(val_host);
- /* val_host is in netorder */
- memcpy(buf, &val_host, sizeof(val_host));
+ /* val_host is in host order */
+ val_host = htonl(val_host);
+ /* val_host is in netorder */
+ memcpy(buf, &val_host, sizeof(val_host));
}
diff --git a/pimd/pim_join.c b/pimd/pim_join.c
index 35deecfd8..9bc5c2d9c 100644
--- a/pimd/pim_join.c
+++ b/pimd/pim_join.c
@@ -39,301 +39,295 @@
#include "pim_rp.h"
#include "pim_jp_agg.h"
-static void
-on_trace (const char *label,
- struct interface *ifp, struct in_addr src)
+static void on_trace(const char *label, struct interface *ifp,
+ struct in_addr src)
{
- if (PIM_DEBUG_PIM_TRACE) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src, src_str, sizeof(src_str));
- zlog_debug("%s: from %s on %s",
- label, src_str, ifp->name);
- }
+ if (PIM_DEBUG_PIM_TRACE) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src, src_str, sizeof(src_str));
+ zlog_debug("%s: from %s on %s", label, src_str, ifp->name);
+ }
}
-static void recv_join(struct interface *ifp,
- struct pim_neighbor *neigh,
- uint16_t holdtime,
- struct in_addr upstream,
- struct prefix_sg *sg,
- uint8_t source_flags)
+static void recv_join(struct interface *ifp, struct pim_neighbor *neigh,
+ uint16_t holdtime, struct in_addr upstream,
+ struct prefix_sg *sg, uint8_t source_flags)
{
- struct pim_interface *pim_ifp = NULL;
-
- if (PIM_DEBUG_PIM_TRACE) {
- char up_str[INET_ADDRSTRLEN];
- char neigh_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<upstream?>", upstream, up_str, sizeof(up_str));
- pim_inet4_dump("<neigh?>", neigh->source_addr, neigh_str, sizeof(neigh_str));
- zlog_warn("%s: join (S,G)=%s rpt=%d wc=%d upstream=%s holdtime=%d from %s on %s",
- __PRETTY_FUNCTION__,
- pim_str_sg_dump (sg),
- source_flags & PIM_RPT_BIT_MASK,
- source_flags & PIM_WILDCARD_BIT_MASK,
- up_str, holdtime, neigh_str, ifp->name);
- }
-
- pim_ifp = ifp->info;
- zassert(pim_ifp);
-
- ++pim_ifp->pim_ifstat_join_recv;
-
- /*
- * If the RPT and WC are set it's a (*,G)
- * and the source is the RP
- */
- if ((source_flags & PIM_RPT_BIT_MASK) &&
- (source_flags & PIM_WILDCARD_BIT_MASK))
- {
- struct pim_rpf *rp = RP (sg->grp);
-
- /*
- * If the RP sent in the message is not
- * our RP for the group, drop the message
- */
- if (sg->src.s_addr != rp->rpf_addr.u.prefix4.s_addr)
- return;
-
- sg->src.s_addr = INADDR_ANY;
- }
-
- /* Restart join expiry timer */
- pim_ifchannel_join_add(ifp, neigh->source_addr, upstream,
- sg, source_flags, holdtime);
-
+ struct pim_interface *pim_ifp = NULL;
+
+ if (PIM_DEBUG_PIM_TRACE) {
+ char up_str[INET_ADDRSTRLEN];
+ char neigh_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<upstream?>", upstream, up_str, sizeof(up_str));
+ pim_inet4_dump("<neigh?>", neigh->source_addr, neigh_str,
+ sizeof(neigh_str));
+ zlog_warn(
+ "%s: join (S,G)=%s rpt=%d wc=%d upstream=%s holdtime=%d from %s on %s",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(sg),
+ source_flags & PIM_RPT_BIT_MASK,
+ source_flags & PIM_WILDCARD_BIT_MASK, up_str, holdtime,
+ neigh_str, ifp->name);
+ }
+
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+
+ ++pim_ifp->pim_ifstat_join_recv;
+
+ /*
+ * If the RPT and WC are set it's a (*,G)
+ * and the source is the RP
+ */
+ if ((source_flags & PIM_RPT_BIT_MASK)
+ && (source_flags & PIM_WILDCARD_BIT_MASK)) {
+ struct pim_rpf *rp = RP(sg->grp);
+
+ /*
+ * If the RP sent in the message is not
+ * our RP for the group, drop the message
+ */
+ if (sg->src.s_addr != rp->rpf_addr.u.prefix4.s_addr)
+ return;
+
+ sg->src.s_addr = INADDR_ANY;
+ }
+
+ /* Restart join expiry timer */
+ pim_ifchannel_join_add(ifp, neigh->source_addr, upstream, sg,
+ source_flags, holdtime);
}
-static void recv_prune(struct interface *ifp,
- struct pim_neighbor *neigh,
- uint16_t holdtime,
- struct in_addr upstream,
- struct prefix_sg *sg,
- uint8_t source_flags)
+static void recv_prune(struct interface *ifp, struct pim_neighbor *neigh,
+ uint16_t holdtime, struct in_addr upstream,
+ struct prefix_sg *sg, uint8_t source_flags)
{
- struct pim_interface *pim_ifp = NULL;
-
- if (PIM_DEBUG_PIM_TRACE) {
- char up_str[INET_ADDRSTRLEN];
- char neigh_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<upstream?>", upstream, up_str, sizeof(up_str));
- pim_inet4_dump("<neigh?>", neigh->source_addr, neigh_str, sizeof(neigh_str));
- zlog_warn("%s: prune (S,G)=%s rpt=%d wc=%d upstream=%s holdtime=%d from %s on %s",
- __PRETTY_FUNCTION__,
- pim_str_sg_dump (sg),
- source_flags & PIM_RPT_BIT_MASK,
- source_flags & PIM_WILDCARD_BIT_MASK,
- up_str, holdtime, neigh_str, ifp->name);
- }
-
- pim_ifp = ifp->info;
- zassert(pim_ifp);
-
- ++pim_ifp->pim_ifstat_prune_recv;
-
- if ((source_flags & PIM_RPT_BIT_MASK) &&
- (source_flags & PIM_WILDCARD_BIT_MASK))
- {
- struct pim_rpf *rp = RP (sg->grp);
-
- // Ignoring Prune *,G's at the moment.
- if (sg->src.s_addr != rp->rpf_addr.u.prefix4.s_addr)
- return;
-
- sg->src.s_addr = INADDR_ANY;
- }
-
- pim_ifchannel_prune(ifp, upstream, sg, source_flags, holdtime);
-
+ struct pim_interface *pim_ifp = NULL;
+
+ if (PIM_DEBUG_PIM_TRACE) {
+ char up_str[INET_ADDRSTRLEN];
+ char neigh_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<upstream?>", upstream, up_str, sizeof(up_str));
+ pim_inet4_dump("<neigh?>", neigh->source_addr, neigh_str,
+ sizeof(neigh_str));
+ zlog_warn(
+ "%s: prune (S,G)=%s rpt=%d wc=%d upstream=%s holdtime=%d from %s on %s",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(sg),
+ source_flags & PIM_RPT_BIT_MASK,
+ source_flags & PIM_WILDCARD_BIT_MASK, up_str, holdtime,
+ neigh_str, ifp->name);
+ }
+
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+
+ ++pim_ifp->pim_ifstat_prune_recv;
+
+ if ((source_flags & PIM_RPT_BIT_MASK)
+ && (source_flags & PIM_WILDCARD_BIT_MASK)) {
+ struct pim_rpf *rp = RP(sg->grp);
+
+ // Ignoring Prune *,G's at the moment.
+ if (sg->src.s_addr != rp->rpf_addr.u.prefix4.s_addr)
+ return;
+
+ sg->src.s_addr = INADDR_ANY;
+ }
+
+ pim_ifchannel_prune(ifp, upstream, sg, source_flags, holdtime);
}
-int pim_joinprune_recv(struct interface *ifp,
- struct pim_neighbor *neigh,
- struct in_addr src_addr,
- uint8_t *tlv_buf, int tlv_buf_size)
+int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
+ struct in_addr src_addr, uint8_t *tlv_buf,
+ int tlv_buf_size)
{
- struct prefix msg_upstream_addr;
- uint8_t msg_num_groups;
- uint16_t msg_holdtime;
- int addr_offset;
- uint8_t *buf;
- uint8_t *pastend;
- int remain;
- int group;
-
- buf = tlv_buf;
- pastend = tlv_buf + tlv_buf_size;
-
- /*
- Parse ucast addr
- */
- addr_offset = pim_parse_addr_ucast (&msg_upstream_addr,
- buf, pastend - buf);
- if (addr_offset < 1) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_warn("%s: pim_parse_addr_ucast() failure: from %s on %s",
- __PRETTY_FUNCTION__,
- src_str, ifp->name);
- return -1;
- }
- buf += addr_offset;
-
- /*
- Check upstream address family
- */
- if (msg_upstream_addr.family != AF_INET) {
- if (PIM_DEBUG_PIM_J_P) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_warn("%s: ignoring join/prune directed to unexpected addr family=%d from %s on %s",
- __PRETTY_FUNCTION__,
- msg_upstream_addr.family, src_str, ifp->name);
- }
- return -2;
- }
-
- remain = pastend - buf;
- if (remain < 4) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_warn("%s: short join/prune message buffer for group list: size=%d minimum=%d from %s on %s",
- __PRETTY_FUNCTION__,
- remain, 4, src_str, ifp->name);
- return -4;
- }
-
- ++buf; /* skip reserved byte */
- msg_num_groups = *(const uint8_t *) buf;
- ++buf;
- msg_holdtime = ntohs(*(const uint16_t *) buf);
- ++buf;
- ++buf;
-
- if (PIM_DEBUG_PIM_J_P) {
- char src_str[INET_ADDRSTRLEN];
- char upstream_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<addr?>", msg_upstream_addr.u.prefix4,
- upstream_str, sizeof(upstream_str));
- zlog_debug ("%s: join/prune upstream=%s groups=%d holdtime=%d from %s on %s",
- __PRETTY_FUNCTION__,
- upstream_str, msg_num_groups, msg_holdtime,
- src_str, ifp->name);
- }
-
- /* Scan groups */
- for (group = 0; group < msg_num_groups; ++group) {
- struct prefix_sg sg;
- uint8_t msg_source_flags;
- uint16_t msg_num_joined_sources;
- uint16_t msg_num_pruned_sources;
- int source;
- struct pim_ifchannel *starg_ch = NULL, *sg_ch = NULL;
- uint8_t starg_alone = 0;
-
- memset (&sg, 0, sizeof (struct prefix_sg));
- addr_offset = pim_parse_addr_group (&sg,
- buf, pastend - buf);
- if (addr_offset < 1) {
- return -5;
- }
- buf += addr_offset;
-
- remain = pastend - buf;
- if (remain < 4) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_warn("%s: short join/prune buffer for source list: size=%d minimum=%d from %s on %s",
- __PRETTY_FUNCTION__,
- remain, 4, src_str, ifp->name);
- return -6;
- }
-
- msg_num_joined_sources = ntohs(*(const uint16_t *) buf);
- buf += 2;
- msg_num_pruned_sources = ntohs(*(const uint16_t *) buf);
- buf += 2;
-
- if (PIM_DEBUG_PIM_J_P) {
- char src_str[INET_ADDRSTRLEN];
- char upstream_str[INET_ADDRSTRLEN];
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<addr?>", msg_upstream_addr.u.prefix4,
- upstream_str, sizeof(upstream_str));
- pim_inet4_dump("<grp?>", sg.grp,
- group_str, sizeof(group_str));
- zlog_warn("%s: join/prune upstream=%s group=%s/32 join_src=%d prune_src=%d from %s on %s",
- __PRETTY_FUNCTION__,
- upstream_str, group_str,
- msg_num_joined_sources, msg_num_pruned_sources,
- src_str, ifp->name);
- }
-
- /* Scan joined sources */
- for (source = 0; source < msg_num_joined_sources; ++source) {
- addr_offset = pim_parse_addr_source (&sg,
- &msg_source_flags,
- buf, pastend - buf);
- if (addr_offset < 1) {
- return -7;
- }
-
- buf += addr_offset;
-
- recv_join(ifp, neigh, msg_holdtime,
- msg_upstream_addr.u.prefix4,
- &sg,
- msg_source_flags);
-
- if (sg.src.s_addr == INADDR_ANY)
- {
- starg_alone = 1;
- starg_ch = pim_ifchannel_find (ifp, &sg);
- if (starg_ch)
- pim_ifchannel_set_star_g_join_state (starg_ch, 0, msg_source_flags, 1, starg_alone);
- }
- }
-
- /* Scan pruned sources */
- for (source = 0; source < msg_num_pruned_sources; ++source) {
- addr_offset = pim_parse_addr_source (&sg,
- &msg_source_flags,
- buf, pastend - buf);
- if (addr_offset < 1) {
- return -8;
- }
-
- sg_ch = pim_ifchannel_find (ifp, &sg);
-
- buf += addr_offset;
- starg_alone = 0;
- recv_prune(ifp, neigh, msg_holdtime,
- msg_upstream_addr.u.prefix4,
- &sg,
- msg_source_flags);
-
- /* Received SG-RPT Prune delete oif from specific S,G */
- if (starg_ch && sg_ch && (msg_source_flags & PIM_RPT_BIT_MASK)
- && !(msg_source_flags & PIM_WILDCARD_BIT_MASK))
- {
- struct pim_upstream *up = sg_ch->upstream;
- PIM_IF_FLAG_SET_S_G_RPT(sg_ch->flags);
- if (up)
- {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: SGRpt flag is set, del inherit oif from up %s",
- __PRETTY_FUNCTION__, up->sg_str);
- pim_channel_del_oif (up->channel_oil, starg_ch->interface, PIM_OIF_FLAG_PROTO_STAR);
- }
- }
- }
- if (starg_ch)
- pim_ifchannel_set_star_g_join_state (starg_ch, 1, msg_source_flags, 0, starg_alone);
- starg_ch = NULL;
- } /* scan groups */
-
- return 0;
+ struct prefix msg_upstream_addr;
+ uint8_t msg_num_groups;
+ uint16_t msg_holdtime;
+ int addr_offset;
+ uint8_t *buf;
+ uint8_t *pastend;
+ int remain;
+ int group;
+
+ buf = tlv_buf;
+ pastend = tlv_buf + tlv_buf_size;
+
+ /*
+ Parse ucast addr
+ */
+ addr_offset =
+ pim_parse_addr_ucast(&msg_upstream_addr, buf, pastend - buf);
+ if (addr_offset < 1) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ zlog_warn("%s: pim_parse_addr_ucast() failure: from %s on %s",
+ __PRETTY_FUNCTION__, src_str, ifp->name);
+ return -1;
+ }
+ buf += addr_offset;
+
+ /*
+ Check upstream address family
+ */
+ if (msg_upstream_addr.family != AF_INET) {
+ if (PIM_DEBUG_PIM_J_P) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str,
+ sizeof(src_str));
+ zlog_warn(
+ "%s: ignoring join/prune directed to unexpected addr family=%d from %s on %s",
+ __PRETTY_FUNCTION__, msg_upstream_addr.family,
+ src_str, ifp->name);
+ }
+ return -2;
+ }
+
+ remain = pastend - buf;
+ if (remain < 4) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ zlog_warn(
+ "%s: short join/prune message buffer for group list: size=%d minimum=%d from %s on %s",
+ __PRETTY_FUNCTION__, remain, 4, src_str, ifp->name);
+ return -4;
+ }
+
+ ++buf; /* skip reserved byte */
+ msg_num_groups = *(const uint8_t *)buf;
+ ++buf;
+ msg_holdtime = ntohs(*(const uint16_t *)buf);
+ ++buf;
+ ++buf;
+
+ if (PIM_DEBUG_PIM_J_P) {
+ char src_str[INET_ADDRSTRLEN];
+ char upstream_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ pim_inet4_dump("<addr?>", msg_upstream_addr.u.prefix4,
+ upstream_str, sizeof(upstream_str));
+ zlog_debug(
+ "%s: join/prune upstream=%s groups=%d holdtime=%d from %s on %s",
+ __PRETTY_FUNCTION__, upstream_str, msg_num_groups,
+ msg_holdtime, src_str, ifp->name);
+ }
+
+ /* Scan groups */
+ for (group = 0; group < msg_num_groups; ++group) {
+ struct prefix_sg sg;
+ uint8_t msg_source_flags;
+ uint16_t msg_num_joined_sources;
+ uint16_t msg_num_pruned_sources;
+ int source;
+ struct pim_ifchannel *starg_ch = NULL, *sg_ch = NULL;
+ uint8_t starg_alone = 0;
+
+ memset(&sg, 0, sizeof(struct prefix_sg));
+ addr_offset = pim_parse_addr_group(&sg, buf, pastend - buf);
+ if (addr_offset < 1) {
+ return -5;
+ }
+ buf += addr_offset;
+
+ remain = pastend - buf;
+ if (remain < 4) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str,
+ sizeof(src_str));
+ zlog_warn(
+ "%s: short join/prune buffer for source list: size=%d minimum=%d from %s on %s",
+ __PRETTY_FUNCTION__, remain, 4, src_str,
+ ifp->name);
+ return -6;
+ }
+
+ msg_num_joined_sources = ntohs(*(const uint16_t *)buf);
+ buf += 2;
+ msg_num_pruned_sources = ntohs(*(const uint16_t *)buf);
+ buf += 2;
+
+ if (PIM_DEBUG_PIM_J_P) {
+ char src_str[INET_ADDRSTRLEN];
+ char upstream_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str,
+ sizeof(src_str));
+ pim_inet4_dump("<addr?>", msg_upstream_addr.u.prefix4,
+ upstream_str, sizeof(upstream_str));
+ pim_inet4_dump("<grp?>", sg.grp, group_str,
+ sizeof(group_str));
+ zlog_warn(
+ "%s: join/prune upstream=%s group=%s/32 join_src=%d prune_src=%d from %s on %s",
+ __PRETTY_FUNCTION__, upstream_str, group_str,
+ msg_num_joined_sources, msg_num_pruned_sources,
+ src_str, ifp->name);
+ }
+
+ /* Scan joined sources */
+ for (source = 0; source < msg_num_joined_sources; ++source) {
+ addr_offset = pim_parse_addr_source(
+ &sg, &msg_source_flags, buf, pastend - buf);
+ if (addr_offset < 1) {
+ return -7;
+ }
+
+ buf += addr_offset;
+
+ recv_join(ifp, neigh, msg_holdtime,
+ msg_upstream_addr.u.prefix4, &sg,
+ msg_source_flags);
+
+ if (sg.src.s_addr == INADDR_ANY) {
+ starg_alone = 1;
+ starg_ch = pim_ifchannel_find(ifp, &sg);
+ if (starg_ch)
+ pim_ifchannel_set_star_g_join_state(
+ starg_ch, 0, msg_source_flags,
+ 1, starg_alone);
+ }
+ }
+
+ /* Scan pruned sources */
+ for (source = 0; source < msg_num_pruned_sources; ++source) {
+ addr_offset = pim_parse_addr_source(
+ &sg, &msg_source_flags, buf, pastend - buf);
+ if (addr_offset < 1) {
+ return -8;
+ }
+
+ sg_ch = pim_ifchannel_find(ifp, &sg);
+
+ buf += addr_offset;
+ starg_alone = 0;
+ recv_prune(ifp, neigh, msg_holdtime,
+ msg_upstream_addr.u.prefix4, &sg,
+ msg_source_flags);
+
+ /* Received SG-RPT Prune delete oif from specific S,G */
+ if (starg_ch && sg_ch
+ && (msg_source_flags & PIM_RPT_BIT_MASK)
+ && !(msg_source_flags & PIM_WILDCARD_BIT_MASK)) {
+ struct pim_upstream *up = sg_ch->upstream;
+ PIM_IF_FLAG_SET_S_G_RPT(sg_ch->flags);
+ if (up) {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug(
+ "%s: SGRpt flag is set, del inherit oif from up %s",
+ __PRETTY_FUNCTION__,
+ up->sg_str);
+ pim_channel_del_oif(
+ up->channel_oil,
+ starg_ch->interface,
+ PIM_OIF_FLAG_PROTO_STAR);
+ }
+ }
+ }
+ if (starg_ch)
+ pim_ifchannel_set_star_g_join_state(
+ starg_ch, 1, msg_source_flags, 0, starg_alone);
+ starg_ch = NULL;
+ } /* scan groups */
+
+ return 0;
}
/*
@@ -402,177 +396,187 @@ int pim_joinprune_recv(struct interface *ifp,
* | Pruned Source Address n (Encoded-Source format) |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
-int pim_joinprune_send(struct pim_rpf *rpf,
- struct list *groups)
+int pim_joinprune_send(struct pim_rpf *rpf, struct list *groups)
{
- struct pim_jp_agg_group *group;
- struct pim_interface *pim_ifp = NULL;
- struct pim_jp_groups *grp = NULL;
- struct pim_jp *msg;
- struct listnode *node, *nnode;
- uint8_t pim_msg[10000];
- uint8_t *curr_ptr = pim_msg;
- bool new_packet = true;
- size_t packet_left = 0;
- size_t packet_size = 0;
- size_t group_size = 0;
-
- on_trace (__PRETTY_FUNCTION__, rpf->source_nexthop.interface, rpf->rpf_addr.u.prefix4);
-
- if (rpf->source_nexthop.interface)
- pim_ifp = rpf->source_nexthop.interface->info;
- else
- {
- zlog_warn ("%s: RPF interface is not present", __PRETTY_FUNCTION__);
- return -1;
- }
-
- if (!pim_ifp)
- {
- zlog_warn ("%s: multicast not enabled on interface %s",
- __PRETTY_FUNCTION__,
- rpf->source_nexthop.interface->name);
- return -1;
- }
-
- if (PIM_INADDR_IS_ANY(rpf->rpf_addr.u.prefix4))
- {
- if (PIM_DEBUG_PIM_J_P) {
- char dst_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<dst?>", rpf->rpf_addr.u.prefix4, dst_str, sizeof(dst_str));
- zlog_debug("%s: upstream=%s is myself on interface %s",
- __PRETTY_FUNCTION__,
- dst_str, rpf->source_nexthop.interface->name);
- }
- return 0;
- }
-
- /*
- RFC 4601: 4.3.1. Sending Hello Messages
-
- Thus, if a router needs to send a Join/Prune or Assert message on
- an interface on which it has not yet sent a Hello message with the
- currently configured IP address, then it MUST immediately send the
- relevant Hello message without waiting for the Hello Timer to
- expire, followed by the Join/Prune or Assert message.
- */
- pim_hello_require(rpf->source_nexthop.interface);
-
- for (ALL_LIST_ELEMENTS(groups, node, nnode, group))
- {
- if (new_packet)
- {
- msg = (struct pim_jp *)pim_msg;
-
- memset(msg, 0, sizeof (*msg));
-
- pim_msg_addr_encode_ipv4_ucast ((uint8_t *)&msg->addr, rpf->rpf_addr.u.prefix4);
- msg->reserved = 0;
- msg->holdtime = htons(PIM_JP_HOLDTIME);
-
- new_packet = false;
-
- grp = &msg->groups[0];
- curr_ptr = (uint8_t *)grp;
- packet_size = sizeof (struct pim_msg_header);
- packet_size += sizeof (struct pim_encoded_ipv4_unicast);
- packet_size += 4; // reserved (1) + groups (1) + holdtime (2)
-
- packet_left = rpf->source_nexthop.interface->mtu - 24;
- packet_left -= packet_size;
- }
- if (PIM_DEBUG_PIM_J_P) {
- char dst_str[INET_ADDRSTRLEN];
- char grp_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<dst?>", rpf->rpf_addr.u.prefix4, dst_str, sizeof(dst_str));
- pim_inet4_dump("<grp?>", group->group, grp_str, sizeof(grp_str));
- zlog_debug("%s: sending (G)=%s to upstream=%s on interface %s",
- __PRETTY_FUNCTION__,
- grp_str, dst_str, rpf->source_nexthop.interface->name);
- }
-
- group_size = pim_msg_get_jp_group_size (group->sources);
- if (group_size > packet_left)
- {
- pim_msg_build_header (pim_msg, packet_size, PIM_MSG_TYPE_JOIN_PRUNE);
- if (pim_msg_send(pim_ifp->pim_sock_fd,
- pim_ifp->primary_address,
- qpim_all_pim_routers_addr,
- pim_msg,
- packet_size,
- rpf->source_nexthop.interface->name)) {
- zlog_warn("%s: could not send PIM message on interface %s",
- __PRETTY_FUNCTION__, rpf->source_nexthop.interface->name);
- }
-
- msg = (struct pim_jp *)pim_msg;
- memset(msg, 0, sizeof (*msg));
-
- pim_msg_addr_encode_ipv4_ucast ((uint8_t *)&msg->addr, rpf->rpf_addr.u.prefix4);
- msg->reserved = 0;
- msg->holdtime = htons(PIM_JP_HOLDTIME);
-
- new_packet = false;
-
- grp = &msg->groups[0];
- curr_ptr = (uint8_t *)grp;
- packet_size = sizeof (struct pim_msg_header);
- packet_size += sizeof (struct pim_encoded_ipv4_unicast);
- packet_size += 4; // reserved (1) + groups (1) + holdtime (2)
-
- packet_left = rpf->source_nexthop.interface->mtu - 24;
- packet_left -= packet_size;
- }
-
- msg->num_groups++;
- /*
- Build PIM message
- */
-
- curr_ptr += group_size;
- packet_left -= group_size;
- packet_size += group_size;
- pim_msg_build_jp_groups (grp, group, group_size);
-
- pim_ifp->pim_ifstat_join_send += ntohs(grp->joins);
- pim_ifp->pim_ifstat_prune_send += ntohs(grp->prunes);
-
- if (PIM_DEBUG_PIM_TRACE)
- zlog_debug ("%s: interface %s num_joins %u num_prunes %u", __PRETTY_FUNCTION__,
- rpf->source_nexthop.interface->name, ntohs(grp->joins), ntohs (grp->prunes));
-
- grp = (struct pim_jp_groups *)curr_ptr;
- if (packet_left < sizeof (struct pim_jp_groups) || msg->num_groups == 255)
- {
- pim_msg_build_header (pim_msg, packet_size, PIM_MSG_TYPE_JOIN_PRUNE);
- if (pim_msg_send(pim_ifp->pim_sock_fd,
- pim_ifp->primary_address,
- qpim_all_pim_routers_addr,
- pim_msg,
- packet_size,
- rpf->source_nexthop.interface->name)) {
- zlog_warn("%s: could not send PIM message on interface %s",
- __PRETTY_FUNCTION__, rpf->source_nexthop.interface->name);
- }
-
- new_packet = true;
- }
- }
-
-
- if (!new_packet)
- {
- //msg->num_groups = htons (msg->num_groups);
- pim_msg_build_header (pim_msg, packet_size, PIM_MSG_TYPE_JOIN_PRUNE);
- if (pim_msg_send(pim_ifp->pim_sock_fd,
- pim_ifp->primary_address,
- qpim_all_pim_routers_addr,
- pim_msg,
- packet_size,
- rpf->source_nexthop.interface->name)) {
- zlog_warn("%s: could not send PIM message on interface %s",
- __PRETTY_FUNCTION__, rpf->source_nexthop.interface->name);
- }
- }
- return 0;
+ struct pim_jp_agg_group *group;
+ struct pim_interface *pim_ifp = NULL;
+ struct pim_jp_groups *grp = NULL;
+ struct pim_jp *msg;
+ struct listnode *node, *nnode;
+ uint8_t pim_msg[10000];
+ uint8_t *curr_ptr = pim_msg;
+ bool new_packet = true;
+ size_t packet_left = 0;
+ size_t packet_size = 0;
+ size_t group_size = 0;
+
+ on_trace(__PRETTY_FUNCTION__, rpf->source_nexthop.interface,
+ rpf->rpf_addr.u.prefix4);
+
+ if (rpf->source_nexthop.interface)
+ pim_ifp = rpf->source_nexthop.interface->info;
+ else {
+ zlog_warn("%s: RPF interface is not present",
+ __PRETTY_FUNCTION__);
+ return -1;
+ }
+
+ if (!pim_ifp) {
+ zlog_warn("%s: multicast not enabled on interface %s",
+ __PRETTY_FUNCTION__,
+ rpf->source_nexthop.interface->name);
+ return -1;
+ }
+
+ if (PIM_INADDR_IS_ANY(rpf->rpf_addr.u.prefix4)) {
+ if (PIM_DEBUG_PIM_J_P) {
+ char dst_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<dst?>", rpf->rpf_addr.u.prefix4,
+ dst_str, sizeof(dst_str));
+ zlog_debug("%s: upstream=%s is myself on interface %s",
+ __PRETTY_FUNCTION__, dst_str,
+ rpf->source_nexthop.interface->name);
+ }
+ return 0;
+ }
+
+ /*
+ RFC 4601: 4.3.1. Sending Hello Messages
+
+ Thus, if a router needs to send a Join/Prune or Assert message on
+ an interface on which it has not yet sent a Hello message with the
+ currently configured IP address, then it MUST immediately send the
+ relevant Hello message without waiting for the Hello Timer to
+ expire, followed by the Join/Prune or Assert message.
+ */
+ pim_hello_require(rpf->source_nexthop.interface);
+
+ for (ALL_LIST_ELEMENTS(groups, node, nnode, group)) {
+ if (new_packet) {
+ msg = (struct pim_jp *)pim_msg;
+
+ memset(msg, 0, sizeof(*msg));
+
+ pim_msg_addr_encode_ipv4_ucast((uint8_t *)&msg->addr,
+ rpf->rpf_addr.u.prefix4);
+ msg->reserved = 0;
+ msg->holdtime = htons(PIM_JP_HOLDTIME);
+
+ new_packet = false;
+
+ grp = &msg->groups[0];
+ curr_ptr = (uint8_t *)grp;
+ packet_size = sizeof(struct pim_msg_header);
+ packet_size += sizeof(struct pim_encoded_ipv4_unicast);
+ packet_size +=
+ 4; // reserved (1) + groups (1) + holdtime (2)
+
+ packet_left = rpf->source_nexthop.interface->mtu - 24;
+ packet_left -= packet_size;
+ }
+ if (PIM_DEBUG_PIM_J_P) {
+ char dst_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<dst?>", rpf->rpf_addr.u.prefix4,
+ dst_str, sizeof(dst_str));
+ pim_inet4_dump("<grp?>", group->group, grp_str,
+ sizeof(grp_str));
+ zlog_debug(
+ "%s: sending (G)=%s to upstream=%s on interface %s",
+ __PRETTY_FUNCTION__, grp_str, dst_str,
+ rpf->source_nexthop.interface->name);
+ }
+
+ group_size = pim_msg_get_jp_group_size(group->sources);
+ if (group_size > packet_left) {
+ pim_msg_build_header(pim_msg, packet_size,
+ PIM_MSG_TYPE_JOIN_PRUNE);
+ if (pim_msg_send(pim_ifp->pim_sock_fd,
+ pim_ifp->primary_address,
+ qpim_all_pim_routers_addr, pim_msg,
+ packet_size,
+ rpf->source_nexthop.interface->name)) {
+ zlog_warn(
+ "%s: could not send PIM message on interface %s",
+ __PRETTY_FUNCTION__,
+ rpf->source_nexthop.interface->name);
+ }
+
+ msg = (struct pim_jp *)pim_msg;
+ memset(msg, 0, sizeof(*msg));
+
+ pim_msg_addr_encode_ipv4_ucast((uint8_t *)&msg->addr,
+ rpf->rpf_addr.u.prefix4);
+ msg->reserved = 0;
+ msg->holdtime = htons(PIM_JP_HOLDTIME);
+
+ new_packet = false;
+
+ grp = &msg->groups[0];
+ curr_ptr = (uint8_t *)grp;
+ packet_size = sizeof(struct pim_msg_header);
+ packet_size += sizeof(struct pim_encoded_ipv4_unicast);
+ packet_size +=
+ 4; // reserved (1) + groups (1) + holdtime (2)
+
+ packet_left = rpf->source_nexthop.interface->mtu - 24;
+ packet_left -= packet_size;
+ }
+
+ msg->num_groups++;
+ /*
+ Build PIM message
+ */
+
+ curr_ptr += group_size;
+ packet_left -= group_size;
+ packet_size += group_size;
+ pim_msg_build_jp_groups(grp, group, group_size);
+
+ pim_ifp->pim_ifstat_join_send += ntohs(grp->joins);
+ pim_ifp->pim_ifstat_prune_send += ntohs(grp->prunes);
+
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug(
+ "%s: interface %s num_joins %u num_prunes %u",
+ __PRETTY_FUNCTION__,
+ rpf->source_nexthop.interface->name,
+ ntohs(grp->joins), ntohs(grp->prunes));
+
+ grp = (struct pim_jp_groups *)curr_ptr;
+ if (packet_left < sizeof(struct pim_jp_groups)
+ || msg->num_groups == 255) {
+ pim_msg_build_header(pim_msg, packet_size,
+ PIM_MSG_TYPE_JOIN_PRUNE);
+ if (pim_msg_send(pim_ifp->pim_sock_fd,
+ pim_ifp->primary_address,
+ qpim_all_pim_routers_addr, pim_msg,
+ packet_size,
+ rpf->source_nexthop.interface->name)) {
+ zlog_warn(
+ "%s: could not send PIM message on interface %s",
+ __PRETTY_FUNCTION__,
+ rpf->source_nexthop.interface->name);
+ }
+
+ new_packet = true;
+ }
+ }
+
+
+ if (!new_packet) {
+ // msg->num_groups = htons (msg->num_groups);
+ pim_msg_build_header(pim_msg, packet_size,
+ PIM_MSG_TYPE_JOIN_PRUNE);
+ if (pim_msg_send(pim_ifp->pim_sock_fd, pim_ifp->primary_address,
+ qpim_all_pim_routers_addr, pim_msg,
+ packet_size,
+ rpf->source_nexthop.interface->name)) {
+ zlog_warn(
+ "%s: could not send PIM message on interface %s",
+ __PRETTY_FUNCTION__,
+ rpf->source_nexthop.interface->name);
+ }
+ }
+ return 0;
}
diff --git a/pimd/pim_join.h b/pimd/pim_join.h
index 6dc1b3e8f..5d28f2ba3 100644
--- a/pimd/pim_join.h
+++ b/pimd/pim_join.h
@@ -26,12 +26,10 @@
#include "pim_neighbor.h"
-int pim_joinprune_recv(struct interface *ifp,
- struct pim_neighbor *neigh,
- struct in_addr src_addr,
- uint8_t *tlv_buf, int tlv_buf_size);
+int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
+ struct in_addr src_addr, uint8_t *tlv_buf,
+ int tlv_buf_size);
-int pim_joinprune_send(struct pim_rpf *nexthop,
- struct list *groups);
+int pim_joinprune_send(struct pim_rpf *nexthop, struct list *groups);
#endif /* PIM_JOIN_H */
diff --git a/pimd/pim_jp_agg.c b/pimd/pim_jp_agg.c
index 25530f40b..16d55d7bf 100644
--- a/pimd/pim_jp_agg.c
+++ b/pimd/pim_jp_agg.c
@@ -30,65 +30,63 @@
#include "pim_join.h"
#include "pim_iface.h"
-void
-pim_jp_agg_group_list_free (struct pim_jp_agg_group *jag)
+void pim_jp_agg_group_list_free(struct pim_jp_agg_group *jag)
{
- list_delete(jag->sources);
+ list_delete(jag->sources);
- XFREE (MTYPE_PIM_JP_AGG_GROUP, jag);
+ XFREE(MTYPE_PIM_JP_AGG_GROUP, jag);
}
-static void
-pim_jp_agg_src_free (struct pim_jp_sources *js)
+static void pim_jp_agg_src_free(struct pim_jp_sources *js)
{
- struct pim_upstream *up = js->up;
-
- /*
- * When we are being called here, we know
- * that the neighbor is going away start
- * the normal j/p timer so that it can
- * pick this shit back up when the
- * nbr comes back alive
- */
- if (up)
- join_timer_start(js->up);
- XFREE (MTYPE_PIM_JP_AGG_SOURCE, js);
+ struct pim_upstream *up = js->up;
+
+ /*
+ * When we are being called here, we know
+ * that the neighbor is going away start
+ * the normal j/p timer so that it can
+ * pick this shit back up when the
+ * nbr comes back alive
+ */
+ if (up)
+ join_timer_start(js->up);
+ XFREE(MTYPE_PIM_JP_AGG_SOURCE, js);
}
-int
-pim_jp_agg_group_list_cmp (void *arg1, void *arg2)
+int pim_jp_agg_group_list_cmp(void *arg1, void *arg2)
{
- const struct pim_jp_agg_group *jag1 = (const struct pim_jp_agg_group *)arg1;
- const struct pim_jp_agg_group *jag2 = (const struct pim_jp_agg_group *)arg2;
+ const struct pim_jp_agg_group *jag1 =
+ (const struct pim_jp_agg_group *)arg1;
+ const struct pim_jp_agg_group *jag2 =
+ (const struct pim_jp_agg_group *)arg2;
- if (jag1->group.s_addr < jag2->group.s_addr)
- return -1;
+ if (jag1->group.s_addr < jag2->group.s_addr)
+ return -1;
- if (jag1->group.s_addr > jag2->group.s_addr)
- return 1;
+ if (jag1->group.s_addr > jag2->group.s_addr)
+ return 1;
- return 0;
+ return 0;
}
-static int
-pim_jp_agg_src_cmp (void *arg1, void *arg2)
+static int pim_jp_agg_src_cmp(void *arg1, void *arg2)
{
- const struct pim_jp_sources *js1 = (const struct pim_jp_sources *)arg1;
- const struct pim_jp_sources *js2 = (const struct pim_jp_sources *)arg2;
+ const struct pim_jp_sources *js1 = (const struct pim_jp_sources *)arg1;
+ const struct pim_jp_sources *js2 = (const struct pim_jp_sources *)arg2;
- if (js1->is_join && !js2->is_join)
- return -1;
+ if (js1->is_join && !js2->is_join)
+ return -1;
- if (!js1->is_join && js2->is_join)
- return 1;
+ if (!js1->is_join && js2->is_join)
+ return 1;
- if ((uint32_t)js1->up->sg.src.s_addr < (uint32_t)js2->up->sg.src.s_addr)
- return -1;
+ if ((uint32_t)js1->up->sg.src.s_addr < (uint32_t)js2->up->sg.src.s_addr)
+ return -1;
- if ((uint32_t)js1->up->sg.src.s_addr > (uint32_t)js2->up->sg.src.s_addr)
- return 1;
+ if ((uint32_t)js1->up->sg.src.s_addr > (uint32_t)js2->up->sg.src.s_addr)
+ return 1;
- return 0;
+ return 0;
}
/*
@@ -97,119 +95,107 @@ pim_jp_agg_src_cmp (void *arg1, void *arg2)
* figuring out where to send prunes
* and joins.
*/
-void
-pim_jp_agg_clear_group (struct list *group)
+void pim_jp_agg_clear_group(struct list *group)
{
- struct listnode *gnode, *gnnode;
- struct listnode *snode, *snnode;
- struct pim_jp_agg_group *jag;
- struct pim_jp_sources *js;
-
- for (ALL_LIST_ELEMENTS(group, gnode, gnnode, jag))
- {
- for (ALL_LIST_ELEMENTS(jag->sources, snode, snnode, js))
- {
- listnode_delete(jag->sources, js);
- js->up = NULL;
- XFREE(MTYPE_PIM_JP_AGG_SOURCE, js);
- }
- jag->sources = NULL;
- listnode_delete(group, jag);
- XFREE(MTYPE_PIM_JP_AGG_GROUP, jag);
- }
+ struct listnode *gnode, *gnnode;
+ struct listnode *snode, *snnode;
+ struct pim_jp_agg_group *jag;
+ struct pim_jp_sources *js;
+
+ for (ALL_LIST_ELEMENTS(group, gnode, gnnode, jag)) {
+ for (ALL_LIST_ELEMENTS(jag->sources, snode, snnode, js)) {
+ listnode_delete(jag->sources, js);
+ js->up = NULL;
+ XFREE(MTYPE_PIM_JP_AGG_SOURCE, js);
+ }
+ jag->sources = NULL;
+ listnode_delete(group, jag);
+ XFREE(MTYPE_PIM_JP_AGG_GROUP, jag);
+ }
}
static struct pim_iface_upstream_switch *
-pim_jp_agg_get_interface_upstream_switch_list (struct pim_rpf *rpf)
+pim_jp_agg_get_interface_upstream_switch_list(struct pim_rpf *rpf)
{
- struct pim_interface *pim_ifp = rpf->source_nexthop.interface->info;
- struct pim_iface_upstream_switch *pius;
- struct listnode *node, *nnode;
-
- /* Old interface is pim disabled */
- if (!pim_ifp)
- return NULL;
-
- for (ALL_LIST_ELEMENTS(pim_ifp->upstream_switch_list, node, nnode, pius))
- {
- if (pius->address.s_addr == rpf->rpf_addr.u.prefix4.s_addr)
- break;
- }
-
- if (!pius)
- {
- pius = XCALLOC(MTYPE_PIM_JP_AGG_GROUP, sizeof (struct pim_iface_upstream_switch));
- pius->address.s_addr = rpf->rpf_addr.u.prefix4.s_addr;
- pius->us = list_new();
- listnode_add_sort (pim_ifp->upstream_switch_list, pius);
- }
-
- return pius;
+ struct pim_interface *pim_ifp = rpf->source_nexthop.interface->info;
+ struct pim_iface_upstream_switch *pius;
+ struct listnode *node, *nnode;
+
+ /* Old interface is pim disabled */
+ if (!pim_ifp)
+ return NULL;
+
+ for (ALL_LIST_ELEMENTS(pim_ifp->upstream_switch_list, node, nnode,
+ pius)) {
+ if (pius->address.s_addr == rpf->rpf_addr.u.prefix4.s_addr)
+ break;
+ }
+
+ if (!pius) {
+ pius = XCALLOC(MTYPE_PIM_JP_AGG_GROUP,
+ sizeof(struct pim_iface_upstream_switch));
+ pius->address.s_addr = rpf->rpf_addr.u.prefix4.s_addr;
+ pius->us = list_new();
+ listnode_add_sort(pim_ifp->upstream_switch_list, pius);
+ }
+
+ return pius;
}
-void
-pim_jp_agg_remove_group (struct list *group, struct pim_upstream *up)
+void pim_jp_agg_remove_group(struct list *group, struct pim_upstream *up)
{
- struct listnode *node, *nnode;
- struct pim_jp_agg_group *jag = NULL;
- struct pim_jp_sources *js = NULL;
-
- for (ALL_LIST_ELEMENTS(group, node, nnode, jag))
- {
- if (jag->group.s_addr == up->sg.grp.s_addr)
- break;
- }
-
- if (!jag)
- return;
-
- for (ALL_LIST_ELEMENTS(jag->sources, node, nnode, js))
- {
- if (js->up == up)
- break;
- }
-
- if (js)
- {
- js->up = NULL;
- listnode_delete(jag->sources, js);
- XFREE(MTYPE_PIM_JP_AGG_SOURCE, js);
- }
-
- if (jag->sources->count == 0)
- {
- list_delete(jag->sources);
- jag->sources = NULL;
- listnode_delete(group, jag);
- XFREE(MTYPE_PIM_JP_AGG_GROUP, jag);
- }
-
+ struct listnode *node, *nnode;
+ struct pim_jp_agg_group *jag = NULL;
+ struct pim_jp_sources *js = NULL;
+
+ for (ALL_LIST_ELEMENTS(group, node, nnode, jag)) {
+ if (jag->group.s_addr == up->sg.grp.s_addr)
+ break;
+ }
+
+ if (!jag)
+ return;
+
+ for (ALL_LIST_ELEMENTS(jag->sources, node, nnode, js)) {
+ if (js->up == up)
+ break;
+ }
+
+ if (js) {
+ js->up = NULL;
+ listnode_delete(jag->sources, js);
+ XFREE(MTYPE_PIM_JP_AGG_SOURCE, js);
+ }
+
+ if (jag->sources->count == 0) {
+ list_delete(jag->sources);
+ jag->sources = NULL;
+ listnode_delete(group, jag);
+ XFREE(MTYPE_PIM_JP_AGG_GROUP, jag);
+ }
}
-int
-pim_jp_agg_is_in_list (struct list *group, struct pim_upstream *up)
+int pim_jp_agg_is_in_list(struct list *group, struct pim_upstream *up)
{
- struct listnode *node, *nnode;
- struct pim_jp_agg_group *jag = NULL;
- struct pim_jp_sources *js = NULL;
+ struct listnode *node, *nnode;
+ struct pim_jp_agg_group *jag = NULL;
+ struct pim_jp_sources *js = NULL;
- for (ALL_LIST_ELEMENTS (group, node, nnode, jag))
- {
- if (jag->group.s_addr == up->sg.grp.s_addr)
- break;
- }
+ for (ALL_LIST_ELEMENTS(group, node, nnode, jag)) {
+ if (jag->group.s_addr == up->sg.grp.s_addr)
+ break;
+ }
- if (!jag)
- return 0;
+ if (!jag)
+ return 0;
- for (ALL_LIST_ELEMENTS(jag->sources, node, nnode, js))
- {
- if (js->up == up)
- return 1;
- }
+ for (ALL_LIST_ELEMENTS(jag->sources, node, nnode, js)) {
+ if (js->up == up)
+ return 1;
+ }
- return 0;
- }
+ return 0;
+}
//#define PIM_JP_AGG_DEBUG 1
/*
@@ -224,148 +210,137 @@ pim_jp_agg_is_in_list (struct list *group, struct pim_upstream *up)
* can be safely compiled out in real
* builds
*/
-void
-pim_jp_agg_upstream_verification (struct pim_upstream *up, bool ignore)
+void pim_jp_agg_upstream_verification(struct pim_upstream *up, bool ignore)
{
#ifdef PIM_JP_AGG_DEBUG
- struct listnode *node;
- struct interface *ifp;
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
- {
- struct pim_interface *pim_ifp = ifp->info;
- struct listnode *nnode;
-
- if (ignore && ifp == up->rpf.source_nexthop.interface)
- continue;
-
- if (pim_ifp)
- {
- struct pim_neighbor *neigh;
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, nnode, neigh))
- {
- assert (!pim_jp_agg_is_in_list(neigh->upstream_jp_agg, up));
- }
- }
- }
+ struct listnode *node;
+ struct interface *ifp;
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ struct pim_interface *pim_ifp = ifp->info;
+ struct listnode *nnode;
+
+ if (ignore && ifp == up->rpf.source_nexthop.interface)
+ continue;
+
+ if (pim_ifp) {
+ struct pim_neighbor *neigh;
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list,
+ nnode, neigh)) {
+ assert(!pim_jp_agg_is_in_list(
+ neigh->upstream_jp_agg, up));
+ }
+ }
+ }
#else
- return;
+ return;
#endif
}
-void
-pim_jp_agg_add_group (struct list *group, struct pim_upstream *up, bool is_join)
+void pim_jp_agg_add_group(struct list *group, struct pim_upstream *up,
+ bool is_join)
{
- struct listnode *node, *nnode;
- struct pim_jp_agg_group *jag = NULL;
- struct pim_jp_sources *js = NULL;
-
- for (ALL_LIST_ELEMENTS(group, node, nnode, jag))
- {
- if (jag->group.s_addr == up->sg.grp.s_addr)
- break;
- }
-
- if (!jag)
- {
- jag = XCALLOC(MTYPE_PIM_JP_AGG_GROUP, sizeof (struct pim_jp_agg_group));
- jag->group.s_addr = up->sg.grp.s_addr;
- jag->sources = list_new();
- jag->sources->cmp = pim_jp_agg_src_cmp;
- jag->sources->del = (void (*)(void *))pim_jp_agg_src_free;
- listnode_add_sort (group, jag);
- }
-
- for (ALL_LIST_ELEMENTS(jag->sources, node, nnode, js))
- {
- if (js->up == up)
- break;
- }
-
- if (!js)
- {
- js = XCALLOC(MTYPE_PIM_JP_AGG_SOURCE, sizeof (struct pim_jp_sources));
- js->up = up;
- js->is_join = is_join;
- listnode_add_sort (jag->sources, js);
- }
- else
- {
- if (js->is_join != is_join)
- {
- listnode_delete(jag->sources, js);
- js->is_join = is_join;
- listnode_add_sort (jag->sources, js);
- }
- }
+ struct listnode *node, *nnode;
+ struct pim_jp_agg_group *jag = NULL;
+ struct pim_jp_sources *js = NULL;
+
+ for (ALL_LIST_ELEMENTS(group, node, nnode, jag)) {
+ if (jag->group.s_addr == up->sg.grp.s_addr)
+ break;
+ }
+
+ if (!jag) {
+ jag = XCALLOC(MTYPE_PIM_JP_AGG_GROUP,
+ sizeof(struct pim_jp_agg_group));
+ jag->group.s_addr = up->sg.grp.s_addr;
+ jag->sources = list_new();
+ jag->sources->cmp = pim_jp_agg_src_cmp;
+ jag->sources->del = (void (*)(void *))pim_jp_agg_src_free;
+ listnode_add_sort(group, jag);
+ }
+
+ for (ALL_LIST_ELEMENTS(jag->sources, node, nnode, js)) {
+ if (js->up == up)
+ break;
+ }
+
+ if (!js) {
+ js = XCALLOC(MTYPE_PIM_JP_AGG_SOURCE,
+ sizeof(struct pim_jp_sources));
+ js->up = up;
+ js->is_join = is_join;
+ listnode_add_sort(jag->sources, js);
+ } else {
+ if (js->is_join != is_join) {
+ listnode_delete(jag->sources, js);
+ js->is_join = is_join;
+ listnode_add_sort(jag->sources, js);
+ }
+ }
}
-void
-pim_jp_agg_switch_interface (struct pim_rpf *orpf,
- struct pim_rpf *nrpf,
- struct pim_upstream *up)
+void pim_jp_agg_switch_interface(struct pim_rpf *orpf, struct pim_rpf *nrpf,
+ struct pim_upstream *up)
{
- struct pim_iface_upstream_switch *opius;
- struct pim_iface_upstream_switch *npius;
-
- opius = pim_jp_agg_get_interface_upstream_switch_list(orpf);
- npius = pim_jp_agg_get_interface_upstream_switch_list(nrpf);
-
- /*
- * RFC 4601: 4.5.7. Sending (S,G) Join/Prune Messages
- *
- * Transitions from Joined State
- *
- * RPF'(S,G) changes not due to an Assert
- *
- * The upstream (S,G) state machine remains in Joined
- * state. Send Join(S,G) to the new upstream neighbor, which is
- * the new value of RPF'(S,G). Send Prune(S,G) to the old
- * upstream neighbor, which is the old value of RPF'(S,G). Set
- * the Join Timer (JT) to expire after t_periodic seconds.
- */
-
- /* send Prune(S,G) to the old upstream neighbor */
- if (opius)
- pim_jp_agg_add_group (opius->us, up, false);
-
- /* send Join(S,G) to the current upstream neighbor */
- pim_jp_agg_add_group (npius->us, up, true);
-
+ struct pim_iface_upstream_switch *opius;
+ struct pim_iface_upstream_switch *npius;
+
+ opius = pim_jp_agg_get_interface_upstream_switch_list(orpf);
+ npius = pim_jp_agg_get_interface_upstream_switch_list(nrpf);
+
+ /*
+ * RFC 4601: 4.5.7. Sending (S,G) Join/Prune Messages
+ *
+ * Transitions from Joined State
+ *
+ * RPF'(S,G) changes not due to an Assert
+ *
+ * The upstream (S,G) state machine remains in Joined
+ * state. Send Join(S,G) to the new upstream neighbor, which is
+ * the new value of RPF'(S,G). Send Prune(S,G) to the old
+ * upstream neighbor, which is the old value of RPF'(S,G). Set
+ * the Join Timer (JT) to expire after t_periodic seconds.
+ */
+
+ /* send Prune(S,G) to the old upstream neighbor */
+ if (opius)
+ pim_jp_agg_add_group(opius->us, up, false);
+
+ /* send Join(S,G) to the current upstream neighbor */
+ pim_jp_agg_add_group(npius->us, up, true);
}
-void
-pim_jp_agg_single_upstream_send (struct pim_rpf *rpf,
- struct pim_upstream *up,
- bool is_join)
+void pim_jp_agg_single_upstream_send(struct pim_rpf *rpf,
+ struct pim_upstream *up, bool is_join)
{
- static struct list *groups = NULL;
- static struct pim_jp_agg_group jag;
- static struct pim_jp_sources js;
+ static struct list *groups = NULL;
+ static struct pim_jp_agg_group jag;
+ static struct pim_jp_sources js;
- static bool first = true;
+ static bool first = true;
- /* skip JP upstream messages if source is directly connected */
- if (!up || !rpf->source_nexthop.interface ||
- pim_if_connected_to_source (rpf->source_nexthop.interface, up->sg.src))
- return;
+ /* skip JP upstream messages if source is directly connected */
+ if (!up || !rpf->source_nexthop.interface || pim_if_connected_to_source(
+ rpf->source_nexthop
+ .interface,
+ up->sg.src))
+ return;
- if (first)
- {
- groups = list_new();
+ if (first) {
+ groups = list_new();
- jag.sources = list_new();
+ jag.sources = list_new();
- listnode_add(groups, &jag);
- listnode_add(jag.sources, &js);
+ listnode_add(groups, &jag);
+ listnode_add(jag.sources, &js);
- first = false;
- }
+ first = false;
+ }
- jag.group.s_addr = up->sg.grp.s_addr;
- js.up = up;
- js.is_join = is_join;
+ jag.group.s_addr = up->sg.grp.s_addr;
+ js.up = up;
+ js.is_join = is_join;
- pim_joinprune_send(rpf, groups);
+ pim_joinprune_send(rpf, groups);
}
diff --git a/pimd/pim_jp_agg.h b/pimd/pim_jp_agg.h
index c3955f32f..aa21aa981 100644
--- a/pimd/pim_jp_agg.h
+++ b/pimd/pim_jp_agg.h
@@ -20,35 +20,31 @@
#ifndef __PIM_JP_AGG_H__
#define __PIM_JP_AGG_H__
-struct pim_jp_sources
-{
- struct pim_upstream *up;
- int is_join;
+struct pim_jp_sources {
+ struct pim_upstream *up;
+ int is_join;
};
-struct pim_jp_agg_group
-{
- struct in_addr group;
- struct list *sources;
+struct pim_jp_agg_group {
+ struct in_addr group;
+ struct list *sources;
};
-void pim_jp_agg_upstream_verification (struct pim_upstream *up, bool ignore);
-int pim_jp_agg_is_in_list (struct list *group, struct pim_upstream *up);
+void pim_jp_agg_upstream_verification(struct pim_upstream *up, bool ignore);
+int pim_jp_agg_is_in_list(struct list *group, struct pim_upstream *up);
-void pim_jp_agg_group_list_free (struct pim_jp_agg_group *jag);
-int pim_jp_agg_group_list_cmp (void *arg1, void *arg2);
+void pim_jp_agg_group_list_free(struct pim_jp_agg_group *jag);
+int pim_jp_agg_group_list_cmp(void *arg1, void *arg2);
-void pim_jp_agg_clear_group (struct list *group);
-void pim_jp_agg_remove_group (struct list *group, struct pim_upstream *up);
+void pim_jp_agg_clear_group(struct list *group);
+void pim_jp_agg_remove_group(struct list *group, struct pim_upstream *up);
-void pim_jp_agg_add_group (struct list *group,
- struct pim_upstream *up, bool is_join);
+void pim_jp_agg_add_group(struct list *group, struct pim_upstream *up,
+ bool is_join);
-void pim_jp_agg_switch_interface (struct pim_rpf *orpf,
- struct pim_rpf *nrpf,
- struct pim_upstream *up);
+void pim_jp_agg_switch_interface(struct pim_rpf *orpf, struct pim_rpf *nrpf,
+ struct pim_upstream *up);
-void pim_jp_agg_single_upstream_send (struct pim_rpf *rpf,
- struct pim_upstream *up,
- bool is_join);
+void pim_jp_agg_single_upstream_send(struct pim_rpf *rpf,
+ struct pim_upstream *up, bool is_join);
#endif
diff --git a/pimd/pim_macro.c b/pimd/pim_macro.c
index 1f3b29554..13f4240db 100644
--- a/pimd/pim_macro.c
+++ b/pimd/pim_macro.c
@@ -39,20 +39,19 @@
*/
static int downstream_jpstate_isjoined(const struct pim_ifchannel *ch)
{
- switch (ch->ifjoin_state)
- {
- case PIM_IFJOIN_NOINFO:
- case PIM_IFJOIN_PRUNE:
- case PIM_IFJOIN_PRUNE_TMP:
- case PIM_IFJOIN_PRUNE_PENDING_TMP:
- return 0;
- break;
- case PIM_IFJOIN_JOIN:
- case PIM_IFJOIN_PRUNE_PENDING:
- return 1;
- break;
- }
- return 0;
+ switch (ch->ifjoin_state) {
+ case PIM_IFJOIN_NOINFO:
+ case PIM_IFJOIN_PRUNE:
+ case PIM_IFJOIN_PRUNE_TMP:
+ case PIM_IFJOIN_PRUNE_PENDING_TMP:
+ return 0;
+ break;
+ case PIM_IFJOIN_JOIN:
+ case PIM_IFJOIN_PRUNE_PENDING:
+ return 1;
+ break;
+ }
+ return 0;
}
/*
@@ -63,8 +62,8 @@ static int downstream_jpstate_isjoined(const struct pim_ifchannel *ch)
*/
static int local_receiver_include(const struct pim_ifchannel *ch)
{
- /* local_receiver_include(S,G,I) ? */
- return ch->local_ifmembership == PIM_IFMEMBERSHIP_INCLUDE;
+ /* local_receiver_include(S,G,I) ? */
+ return ch->local_ifmembership == PIM_IFMEMBERSHIP_INCLUDE;
}
/*
@@ -75,13 +74,13 @@ static int local_receiver_include(const struct pim_ifchannel *ch)
joins(S,G) =
{ all interfaces I such that
- DownstreamJPState(S,G,I) is either Join or Prune-Pending }
+ DownstreamJPState(S,G,I) is either Join or Prune-Pending }
DownstreamJPState(S,G,I) is either Join or Prune-Pending ?
*/
int pim_macro_chisin_joins(const struct pim_ifchannel *ch)
{
- return downstream_jpstate_isjoined(ch);
+ return downstream_jpstate_isjoined(ch);
}
/*
@@ -92,16 +91,16 @@ int pim_macro_chisin_joins(const struct pim_ifchannel *ch)
lost_assert(S,G) =
{ all interfaces I such that
- lost_assert(S,G,I) == TRUE }
+ lost_assert(S,G,I) == TRUE }
bool lost_assert(S,G,I) {
if ( RPF_interface(S) == I ) {
- return FALSE
+ return FALSE
} else {
- return ( AssertWinner(S,G,I) != NULL AND
- AssertWinner(S,G,I) != me AND
- (AssertWinnerMetric(S,G,I) is better
- than spt_assert_metric(S,I) )
+ return ( AssertWinner(S,G,I) != NULL AND
+ AssertWinner(S,G,I) != me AND
+ (AssertWinnerMetric(S,G,I) is better
+ than spt_assert_metric(S,I) )
}
}
@@ -110,42 +109,40 @@ int pim_macro_chisin_joins(const struct pim_ifchannel *ch)
*/
int pim_macro_ch_lost_assert(const struct pim_ifchannel *ch)
{
- struct interface *ifp;
- struct pim_interface *pim_ifp;
- struct pim_assert_metric spt_assert_metric;
-
- ifp = ch->interface;
- if (!ifp) {
- zlog_warn("%s: (S,G)=%s: null interface",
- __PRETTY_FUNCTION__,
- ch->sg_str);
- return 0; /* false */
- }
-
- /* RPF_interface(S) == I ? */
- if (ch->upstream->rpf.source_nexthop.interface == ifp)
- return 0; /* false */
-
- pim_ifp = ifp->info;
- if (!pim_ifp) {
- zlog_warn("%s: (S,G)=%s: multicast not enabled on interface %s",
- __PRETTY_FUNCTION__,
- ch->sg_str, ifp->name);
- return 0; /* false */
- }
-
- if (PIM_INADDR_IS_ANY(ch->ifassert_winner))
- return 0; /* false */
-
- /* AssertWinner(S,G,I) == me ? */
- if (ch->ifassert_winner.s_addr == pim_ifp->primary_address.s_addr)
- return 0; /* false */
-
- spt_assert_metric = pim_macro_spt_assert_metric(&ch->upstream->rpf,
- pim_ifp->primary_address);
-
- return pim_assert_metric_better(&ch->ifassert_winner_metric,
- &spt_assert_metric);
+ struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ struct pim_assert_metric spt_assert_metric;
+
+ ifp = ch->interface;
+ if (!ifp) {
+ zlog_warn("%s: (S,G)=%s: null interface", __PRETTY_FUNCTION__,
+ ch->sg_str);
+ return 0; /* false */
+ }
+
+ /* RPF_interface(S) == I ? */
+ if (ch->upstream->rpf.source_nexthop.interface == ifp)
+ return 0; /* false */
+
+ pim_ifp = ifp->info;
+ if (!pim_ifp) {
+ zlog_warn("%s: (S,G)=%s: multicast not enabled on interface %s",
+ __PRETTY_FUNCTION__, ch->sg_str, ifp->name);
+ return 0; /* false */
+ }
+
+ if (PIM_INADDR_IS_ANY(ch->ifassert_winner))
+ return 0; /* false */
+
+ /* AssertWinner(S,G,I) == me ? */
+ if (ch->ifassert_winner.s_addr == pim_ifp->primary_address.s_addr)
+ return 0; /* false */
+
+ spt_assert_metric = pim_macro_spt_assert_metric(
+ &ch->upstream->rpf, pim_ifp->primary_address);
+
+ return pim_assert_metric_better(&ch->ifassert_winner_metric,
+ &spt_assert_metric);
}
/*
@@ -153,47 +150,44 @@ int pim_macro_ch_lost_assert(const struct pim_ifchannel *ch)
pim_include(S,G) =
{ all interfaces I such that:
- ( (I_am_DR( I ) AND lost_assert(S,G,I) == FALSE )
- OR AssertWinner(S,G,I) == me )
- AND local_receiver_include(S,G,I) }
+ ( (I_am_DR( I ) AND lost_assert(S,G,I) == FALSE )
+ OR AssertWinner(S,G,I) == me )
+ AND local_receiver_include(S,G,I) }
AssertWinner(S,G,I) is the IP source address of the Assert(S,G)
packet that won an Assert.
*/
int pim_macro_chisin_pim_include(const struct pim_ifchannel *ch)
{
- struct pim_interface *pim_ifp = ch->interface->info;
-
- if (!pim_ifp) {
- zlog_warn("%s: (S,G)=%s: multicast not enabled on interface %s",
- __PRETTY_FUNCTION__,
- ch->sg_str, ch->interface->name);
- return 0; /* false */
- }
-
- /* local_receiver_include(S,G,I) ? */
- if (!local_receiver_include(ch))
- return 0; /* false */
-
- /* OR AssertWinner(S,G,I) == me ? */
- if (ch->ifassert_winner.s_addr == pim_ifp->primary_address.s_addr)
- return 1; /* true */
-
- return (
- /* I_am_DR( I ) ? */
- PIM_I_am_DR(pim_ifp)
- &&
- /* lost_assert(S,G,I) == FALSE ? */
- (!pim_macro_ch_lost_assert(ch))
- );
+ struct pim_interface *pim_ifp = ch->interface->info;
+
+ if (!pim_ifp) {
+ zlog_warn("%s: (S,G)=%s: multicast not enabled on interface %s",
+ __PRETTY_FUNCTION__, ch->sg_str, ch->interface->name);
+ return 0; /* false */
+ }
+
+ /* local_receiver_include(S,G,I) ? */
+ if (!local_receiver_include(ch))
+ return 0; /* false */
+
+ /* OR AssertWinner(S,G,I) == me ? */
+ if (ch->ifassert_winner.s_addr == pim_ifp->primary_address.s_addr)
+ return 1; /* true */
+
+ return (
+ /* I_am_DR( I ) ? */
+ PIM_I_am_DR(pim_ifp) &&
+ /* lost_assert(S,G,I) == FALSE ? */
+ (!pim_macro_ch_lost_assert(ch)));
}
int pim_macro_chisin_joins_or_include(const struct pim_ifchannel *ch)
{
- if (pim_macro_chisin_joins(ch))
- return 1; /* true */
+ if (pim_macro_chisin_joins(ch))
+ return 1; /* true */
- return pim_macro_chisin_pim_include(ch);
+ return pim_macro_chisin_pim_include(ch);
}
/*
@@ -203,9 +197,9 @@ int pim_macro_chisin_joins_or_include(const struct pim_ifchannel *ch)
SPTbit(S,G)==TRUE
AND (RPF_interface(S) != I)
AND (I in ( ( joins(*,*,RP(G)) (+) joins(*,G) (-) prunes(S,G,rpt) )
- (+) ( pim_include(*,G) (-) pim_exclude(S,G) )
- (-) lost_assert(*,G)
- (+) joins(S,G) (+) pim_include(S,G) ) )
+ (+) ( pim_include(*,G) (-) pim_exclude(S,G) )
+ (-) lost_assert(*,G)
+ (+) joins(S,G) (+) pim_include(S,G) ) )
CouldAssert(S,G,I) is true for downstream interfaces that would be in
the inherited_olist(S,G) if (S,G) assert information was not taken
@@ -225,25 +219,25 @@ int pim_macro_chisin_joins_or_include(const struct pim_ifchannel *ch)
*/
int pim_macro_ch_could_assert_eval(const struct pim_ifchannel *ch)
{
- struct interface *ifp;
+ struct interface *ifp;
- ifp = ch->interface;
- if (!ifp) {
- zlog_warn("%s: (S,G)=%s: null interface",
- __PRETTY_FUNCTION__, ch->sg_str);
- return 0; /* false */
- }
+ ifp = ch->interface;
+ if (!ifp) {
+ zlog_warn("%s: (S,G)=%s: null interface", __PRETTY_FUNCTION__,
+ ch->sg_str);
+ return 0; /* false */
+ }
- /* SPTbit(S,G) == TRUE */
- if (ch->upstream->sptbit == PIM_UPSTREAM_SPTBIT_FALSE)
- return 0; /* false */
+ /* SPTbit(S,G) == TRUE */
+ if (ch->upstream->sptbit == PIM_UPSTREAM_SPTBIT_FALSE)
+ return 0; /* false */
- /* RPF_interface(S) != I ? */
- if (ch->upstream->rpf.source_nexthop.interface == ifp)
- return 0; /* false */
+ /* RPF_interface(S) != I ? */
+ if (ch->upstream->rpf.source_nexthop.interface == ifp)
+ return 0; /* false */
- /* I in joins(S,G) (+) pim_include(S,G) ? */
- return pim_macro_chisin_joins_or_include(ch);
+ /* I in joins(S,G) (+) pim_include(S,G) ? */
+ return pim_macro_chisin_joins_or_include(ch);
}
/*
@@ -260,14 +254,14 @@ int pim_macro_ch_could_assert_eval(const struct pim_ifchannel *ch)
struct pim_assert_metric pim_macro_spt_assert_metric(const struct pim_rpf *rpf,
struct in_addr ifaddr)
{
- struct pim_assert_metric metric;
+ struct pim_assert_metric metric;
- metric.rpt_bit_flag = 0;
- metric.metric_preference = rpf->source_nexthop.mrib_metric_preference;
- metric.route_metric = rpf->source_nexthop.mrib_route_metric;
- metric.ip_address = ifaddr;
+ metric.rpt_bit_flag = 0;
+ metric.metric_preference = rpf->source_nexthop.mrib_metric_preference;
+ metric.route_metric = rpf->source_nexthop.mrib_route_metric;
+ metric.ip_address = ifaddr;
- return metric;
+ return metric;
}
/*
@@ -287,24 +281,26 @@ struct pim_assert_metric pim_macro_spt_assert_metric(const struct pim_rpf *rpf,
}
}
*/
-struct pim_assert_metric pim_macro_ch_my_assert_metric_eval(const struct pim_ifchannel *ch)
+struct pim_assert_metric
+pim_macro_ch_my_assert_metric_eval(const struct pim_ifchannel *ch)
{
- struct pim_interface *pim_ifp;
+ struct pim_interface *pim_ifp;
- pim_ifp = ch->interface->info;
+ pim_ifp = ch->interface->info;
- if (pim_ifp) {
- if (PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags)) {
- return pim_macro_spt_assert_metric(&ch->upstream->rpf, pim_ifp->primary_address);
- }
- }
+ if (pim_ifp) {
+ if (PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags)) {
+ return pim_macro_spt_assert_metric(
+ &ch->upstream->rpf, pim_ifp->primary_address);
+ }
+ }
- return qpim_infinite_assert_metric;
+ return qpim_infinite_assert_metric;
}
/*
RFC 4601 4.2. Data Packet Forwarding Rules
-
+
Macro:
inherited_olist(S,G) =
inherited_olist(S,G,rpt) (+)
@@ -312,10 +308,10 @@ struct pim_assert_metric pim_macro_ch_my_assert_metric_eval(const struct pim_ifc
*/
static int pim_macro_chisin_inherited_olist(const struct pim_ifchannel *ch)
{
- if (pim_macro_ch_lost_assert(ch))
- return 0; /* false */
+ if (pim_macro_ch_lost_assert(ch))
+ return 0; /* false */
- return pim_macro_chisin_joins_or_include(ch);
+ return pim_macro_chisin_joins_or_include(ch);
}
/*
@@ -324,7 +320,7 @@ static int pim_macro_chisin_inherited_olist(const struct pim_ifchannel *ch)
Additionally, the Packet forwarding rules of Section 4.2 can be
simplified in a PIM-SSM-only router:
-
+
iif is the incoming interface of the packet.
oiflist = NULL
if (iif == RPF_interface(S) AND UpstreamJPState(S,G) == Joined) {
@@ -334,7 +330,7 @@ static int pim_macro_chisin_inherited_olist(const struct pim_ifchannel *ch)
}
oiflist = oiflist (-) iif
forward packet on all interfaces in oiflist
-
+
Macro:
inherited_olist(S,G) =
joins(S,G) (+) pim_include(S,G) (-) lost_assert(S,G)
@@ -349,16 +345,16 @@ static int pim_macro_chisin_inherited_olist(const struct pim_ifchannel *ch)
*/
int pim_macro_chisin_oiflist(const struct pim_ifchannel *ch)
{
- if (ch->upstream->join_state == PIM_UPSTREAM_NOTJOINED) {
- /* oiflist is NULL */
- return 0; /* false */
- }
+ if (ch->upstream->join_state == PIM_UPSTREAM_NOTJOINED) {
+ /* oiflist is NULL */
+ return 0; /* false */
+ }
- /* oiflist = oiflist (-) iif */
- if (ch->interface == ch->upstream->rpf.source_nexthop.interface)
- return 0; /* false */
+ /* oiflist = oiflist (-) iif */
+ if (ch->interface == ch->upstream->rpf.source_nexthop.interface)
+ return 0; /* false */
- return pim_macro_chisin_inherited_olist(ch);
+ return pim_macro_chisin_inherited_olist(ch);
}
/*
@@ -380,45 +376,45 @@ int pim_macro_chisin_oiflist(const struct pim_ifchannel *ch)
*/
int pim_macro_assert_tracking_desired_eval(const struct pim_ifchannel *ch)
{
- struct pim_interface *pim_ifp;
- struct interface *ifp;
-
- ifp = ch->interface;
- if (!ifp) {
- zlog_warn("%s: (S,G)=%s: null interface",
- __PRETTY_FUNCTION__, ch->sg_str);
- return 0; /* false */
- }
-
- pim_ifp = ifp->info;
- if (!pim_ifp) {
- zlog_warn("%s: (S,G)=%s: multicast not enabled on interface %s",
- __PRETTY_FUNCTION__, ch->sg_str, ch->interface->name);
- return 0; /* false */
- }
-
- /* I in joins(S,G) ? */
- if (pim_macro_chisin_joins(ch))
- return 1; /* true */
-
- /* local_receiver_include(S,G,I) ? */
- if (local_receiver_include(ch)) {
- /* I_am_DR(I) ? */
- if (PIM_I_am_DR(pim_ifp))
- return 1; /* true */
-
- /* AssertWinner(S,G,I) == me ? */
- if (ch->ifassert_winner.s_addr == pim_ifp->primary_address.s_addr)
- return 1; /* true */
- }
-
- /* RPF_interface(S) == I ? */
- if (ch->upstream->rpf.source_nexthop.interface == ifp) {
- /* JoinDesired(S,G) ? */
- if (PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(ch->upstream->flags))
- return 1; /* true */
- }
-
- return 0; /* false */
+ struct pim_interface *pim_ifp;
+ struct interface *ifp;
+
+ ifp = ch->interface;
+ if (!ifp) {
+ zlog_warn("%s: (S,G)=%s: null interface", __PRETTY_FUNCTION__,
+ ch->sg_str);
+ return 0; /* false */
+ }
+
+ pim_ifp = ifp->info;
+ if (!pim_ifp) {
+ zlog_warn("%s: (S,G)=%s: multicast not enabled on interface %s",
+ __PRETTY_FUNCTION__, ch->sg_str, ch->interface->name);
+ return 0; /* false */
+ }
+
+ /* I in joins(S,G) ? */
+ if (pim_macro_chisin_joins(ch))
+ return 1; /* true */
+
+ /* local_receiver_include(S,G,I) ? */
+ if (local_receiver_include(ch)) {
+ /* I_am_DR(I) ? */
+ if (PIM_I_am_DR(pim_ifp))
+ return 1; /* true */
+
+ /* AssertWinner(S,G,I) == me ? */
+ if (ch->ifassert_winner.s_addr
+ == pim_ifp->primary_address.s_addr)
+ return 1; /* true */
+ }
+
+ /* RPF_interface(S) == I ? */
+ if (ch->upstream->rpf.source_nexthop.interface == ifp) {
+ /* JoinDesired(S,G) ? */
+ if (PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(ch->upstream->flags))
+ return 1; /* true */
+ }
+
+ return 0; /* false */
}
-
diff --git a/pimd/pim_macro.h b/pimd/pim_macro.h
index e07b2ece9..f310e244e 100644
--- a/pimd/pim_macro.h
+++ b/pimd/pim_macro.h
@@ -34,7 +34,8 @@ int pim_macro_chisin_joins_or_include(const struct pim_ifchannel *ch);
int pim_macro_ch_could_assert_eval(const struct pim_ifchannel *ch);
struct pim_assert_metric pim_macro_spt_assert_metric(const struct pim_rpf *rpf,
struct in_addr ifaddr);
-struct pim_assert_metric pim_macro_ch_my_assert_metric_eval(const struct pim_ifchannel *ch);
+struct pim_assert_metric
+pim_macro_ch_my_assert_metric_eval(const struct pim_ifchannel *ch);
int pim_macro_chisin_oiflist(const struct pim_ifchannel *ch);
int pim_macro_assert_tracking_desired_eval(const struct pim_ifchannel *ch);
diff --git a/pimd/pim_main.c b/pimd/pim_main.c
index a80059535..b8e6d8ad3 100644
--- a/pimd/pim_main.c
+++ b/pimd/pim_main.c
@@ -20,7 +20,7 @@
#include <zebra.h>
#include "log.h"
-#include "privs.h"
+#include "privs.h"
#include "version.h"
#include <getopt.h>
#include "command.h"
@@ -49,115 +49,109 @@
extern struct host host;
-struct option longopts[] = {
- { 0 }
-};
+struct option longopts[] = {{0}};
/* pimd privileges */
-zebra_capabilities_t _caps_p [] =
-{
- ZCAP_NET_ADMIN,
- ZCAP_SYS_ADMIN,
- ZCAP_NET_RAW,
- ZCAP_BIND,
+zebra_capabilities_t _caps_p[] = {
+ ZCAP_NET_ADMIN, ZCAP_SYS_ADMIN, ZCAP_NET_RAW, ZCAP_BIND,
};
/* pimd privileges to run with */
-struct zebra_privs_t pimd_privs =
-{
+struct zebra_privs_t pimd_privs = {
#if defined(FRR_USER) && defined(FRR_GROUP)
- .user = FRR_USER,
- .group = FRR_GROUP,
+ .user = FRR_USER,
+ .group = FRR_GROUP,
#endif
#ifdef VTY_GROUP
- .vty_group = VTY_GROUP,
+ .vty_group = VTY_GROUP,
#endif
- .caps_p = _caps_p,
- .cap_num_p = sizeof(_caps_p)/sizeof(_caps_p[0]),
- .cap_num_i = 0
-};
-
-FRR_DAEMON_INFO(pimd, PIM,
- .vty_port = PIMD_VTY_PORT,
-
- .proghelp = "Implementation of the PIM routing protocol.",
-
- .signals = pimd_signals,
- .n_signals = 4 /* XXX array_size(pimd_signals) XXX*/,
+ .caps_p = _caps_p,
+ .cap_num_p = sizeof(_caps_p) / sizeof(_caps_p[0]),
+ .cap_num_i = 0};
- .privs = &pimd_privs,
-)
+FRR_DAEMON_INFO(pimd, PIM, .vty_port = PIMD_VTY_PORT,
+ .proghelp = "Implementation of the PIM routing protocol.",
-int main(int argc, char** argv, char** envp) {
- frr_preinit(&pimd_di, argc, argv);
- frr_opt_add("", longopts, "");
+ .signals = pimd_signals,
+ .n_signals = 4 /* XXX array_size(pimd_signals) XXX*/,
- /* this while just reads the options */
- while (1) {
- int opt;
+ .privs = &pimd_privs, )
- opt = frr_getopt(argc, argv, NULL);
- if (opt == EOF)
- break;
-
- switch (opt) {
- case 0:
- break;
- default:
- frr_help_exit (1);
- break;
- }
- }
-
- master = frr_init();
-
- /*
- * Initializations
- */
- pim_vrf_init ();
- access_list_init();
- prefix_list_init ();
- prefix_list_add_hook (pim_prefix_list_update);
- prefix_list_delete_hook (pim_prefix_list_update);
-
- pim_route_map_init ();
- pim_init();
- pim_msdp_init (master);
-
- /*
- * Initialize zclient "update" and "lookup" sockets
- */
- pim_zebra_init();
- pim_bfd_init ();
-
- frr_config_fork();
+int main(int argc, char **argv, char **envp)
+{
+ frr_preinit(&pimd_di, argc, argv);
+ frr_opt_add("", longopts, "");
+
+ /* this while just reads the options */
+ while (1) {
+ int opt;
+
+ opt = frr_getopt(argc, argv, NULL);
+
+ if (opt == EOF)
+ break;
+
+ switch (opt) {
+ case 0:
+ break;
+ default:
+ frr_help_exit(1);
+ break;
+ }
+ }
+
+ master = frr_init();
+
+ /*
+ * Initializations
+ */
+ pim_vrf_init();
+ access_list_init();
+ prefix_list_init();
+ prefix_list_add_hook(pim_prefix_list_update);
+ prefix_list_delete_hook(pim_prefix_list_update);
+
+ pim_route_map_init();
+ pim_init();
+ pim_msdp_init(master);
+
+ /*
+ * Initialize zclient "update" and "lookup" sockets
+ */
+ pim_zebra_init();
+ pim_bfd_init();
+
+ frr_config_fork();
#ifdef PIM_DEBUG_BYDEFAULT
- zlog_notice("PIM_DEBUG_BYDEFAULT: Enabling all debug commands");
- PIM_DO_DEBUG_PIM_EVENTS;
- PIM_DO_DEBUG_PIM_PACKETS;
- PIM_DO_DEBUG_PIM_TRACE;
- PIM_DO_DEBUG_IGMP_EVENTS;
- PIM_DO_DEBUG_IGMP_PACKETS;
- PIM_DO_DEBUG_IGMP_TRACE;
- PIM_DO_DEBUG_ZEBRA;
+ zlog_notice("PIM_DEBUG_BYDEFAULT: Enabling all debug commands");
+ PIM_DO_DEBUG_PIM_EVENTS;
+ PIM_DO_DEBUG_PIM_PACKETS;
+ PIM_DO_DEBUG_PIM_TRACE;
+ PIM_DO_DEBUG_IGMP_EVENTS;
+ PIM_DO_DEBUG_IGMP_PACKETS;
+ PIM_DO_DEBUG_IGMP_TRACE;
+ PIM_DO_DEBUG_ZEBRA;
#endif
#ifdef PIM_CHECK_RECV_IFINDEX_SANITY
- zlog_notice("PIM_CHECK_RECV_IFINDEX_SANITY: will match sock/recv ifindex");
+ zlog_notice(
+ "PIM_CHECK_RECV_IFINDEX_SANITY: will match sock/recv ifindex");
#ifdef PIM_REPORT_RECV_IFINDEX_MISMATCH
- zlog_notice("PIM_REPORT_RECV_IFINDEX_MISMATCH: will report sock/recv ifindex mismatch");
+ zlog_notice(
+ "PIM_REPORT_RECV_IFINDEX_MISMATCH: will report sock/recv ifindex mismatch");
#endif
#endif
#ifdef PIM_UNEXPECTED_KERNEL_UPCALL
- zlog_notice("PIM_UNEXPECTED_KERNEL_UPCALL: report unexpected kernel upcall");
+ zlog_notice(
+ "PIM_UNEXPECTED_KERNEL_UPCALL: report unexpected kernel upcall");
#endif
- frr_run(master);
+ frr_run(master);
- /* never reached */
- return 0;
+ /* never reached */
+ return 0;
}
diff --git a/pimd/pim_memory.c b/pimd/pim_memory.c
index d18b7f0c8..dff16c416 100644
--- a/pimd/pim_memory.c
+++ b/pimd/pim_memory.c
@@ -26,29 +26,29 @@
#include "pim_memory.h"
DEFINE_MGROUP(PIMD, "pimd")
-DEFINE_MTYPE(PIMD, PIM_CHANNEL_OIL, "PIM SSM (S,G) channel OIL")
-DEFINE_MTYPE(PIMD, PIM_INTERFACE, "PIM interface")
-DEFINE_MTYPE(PIMD, PIM_IGMP_JOIN, "PIM interface IGMP static join")
-DEFINE_MTYPE(PIMD, PIM_IGMP_SOCKET, "PIM interface IGMP socket")
-DEFINE_MTYPE(PIMD, PIM_IGMP_GROUP, "PIM interface IGMP group")
+DEFINE_MTYPE(PIMD, PIM_CHANNEL_OIL, "PIM SSM (S,G) channel OIL")
+DEFINE_MTYPE(PIMD, PIM_INTERFACE, "PIM interface")
+DEFINE_MTYPE(PIMD, PIM_IGMP_JOIN, "PIM interface IGMP static join")
+DEFINE_MTYPE(PIMD, PIM_IGMP_SOCKET, "PIM interface IGMP socket")
+DEFINE_MTYPE(PIMD, PIM_IGMP_GROUP, "PIM interface IGMP group")
DEFINE_MTYPE(PIMD, PIM_IGMP_GROUP_SOURCE, "PIM interface IGMP source")
-DEFINE_MTYPE(PIMD, PIM_NEIGHBOR, "PIM interface neighbor")
-DEFINE_MTYPE(PIMD, PIM_IFCHANNEL, "PIM interface (S,G) state")
-DEFINE_MTYPE(PIMD, PIM_UPSTREAM, "PIM upstream (S,G) state")
-DEFINE_MTYPE(PIMD, PIM_SSMPINGD, "PIM sspimgd socket")
-DEFINE_MTYPE(PIMD, PIM_STATIC_ROUTE, "PIM Static Route")
-DEFINE_MTYPE(PIMD, PIM_BR, "PIM Bridge Router info")
-DEFINE_MTYPE(PIMD, PIM_RP, "PIM RP info")
-DEFINE_MTYPE(PIMD, PIM_FILTER_NAME, "PIM RP filter info")
-DEFINE_MTYPE(PIMD, PIM_MSDP_PEER, "PIM MSDP peer")
-DEFINE_MTYPE(PIMD, PIM_MSDP_MG_NAME, "PIM MSDP mesh-group name")
-DEFINE_MTYPE(PIMD, PIM_MSDP_SA, "PIM MSDP source-active cache")
-DEFINE_MTYPE(PIMD, PIM_MSDP_MG, "PIM MSDP mesh group")
-DEFINE_MTYPE(PIMD, PIM_MSDP_MG_MBR, "PIM MSDP mesh group mbr")
-DEFINE_MTYPE(PIMD, PIM_SEC_ADDR, "PIM secondary address")
-DEFINE_MTYPE(PIMD, PIM_JP_AGG_GROUP, "PIM JP AGG Group")
-DEFINE_MTYPE(PIMD, PIM_JP_AGG_SOURCE, "PIM JP AGG Source")
-DEFINE_MTYPE(PIMD, PIM_PIM_INSTANCE, "PIM global state")
-DEFINE_MTYPE(PIMD, PIM_NEXTHOP_CACHE, "PIM nexthop cache state")
-DEFINE_MTYPE(PIMD, PIM_SSM_INFO, "PIM SSM configuration")
-DEFINE_MTYPE(PIMD, PIM_SPT_PLIST_NAME, "PIM SPT Prefix List Name")
+DEFINE_MTYPE(PIMD, PIM_NEIGHBOR, "PIM interface neighbor")
+DEFINE_MTYPE(PIMD, PIM_IFCHANNEL, "PIM interface (S,G) state")
+DEFINE_MTYPE(PIMD, PIM_UPSTREAM, "PIM upstream (S,G) state")
+DEFINE_MTYPE(PIMD, PIM_SSMPINGD, "PIM sspimgd socket")
+DEFINE_MTYPE(PIMD, PIM_STATIC_ROUTE, "PIM Static Route")
+DEFINE_MTYPE(PIMD, PIM_BR, "PIM Bridge Router info")
+DEFINE_MTYPE(PIMD, PIM_RP, "PIM RP info")
+DEFINE_MTYPE(PIMD, PIM_FILTER_NAME, "PIM RP filter info")
+DEFINE_MTYPE(PIMD, PIM_MSDP_PEER, "PIM MSDP peer")
+DEFINE_MTYPE(PIMD, PIM_MSDP_MG_NAME, "PIM MSDP mesh-group name")
+DEFINE_MTYPE(PIMD, PIM_MSDP_SA, "PIM MSDP source-active cache")
+DEFINE_MTYPE(PIMD, PIM_MSDP_MG, "PIM MSDP mesh group")
+DEFINE_MTYPE(PIMD, PIM_MSDP_MG_MBR, "PIM MSDP mesh group mbr")
+DEFINE_MTYPE(PIMD, PIM_SEC_ADDR, "PIM secondary address")
+DEFINE_MTYPE(PIMD, PIM_JP_AGG_GROUP, "PIM JP AGG Group")
+DEFINE_MTYPE(PIMD, PIM_JP_AGG_SOURCE, "PIM JP AGG Source")
+DEFINE_MTYPE(PIMD, PIM_PIM_INSTANCE, "PIM global state")
+DEFINE_MTYPE(PIMD, PIM_NEXTHOP_CACHE, "PIM nexthop cache state")
+DEFINE_MTYPE(PIMD, PIM_SSM_INFO, "PIM SSM configuration")
+DEFINE_MTYPE(PIMD, PIM_SPT_PLIST_NAME, "PIM SPT Prefix List Name")
diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c
index 01747268a..a92b01ca0 100644
--- a/pimd/pim_mroute.c
+++ b/pimd/pim_mroute.c
@@ -47,358 +47,360 @@ static void mroute_read_on(void);
static int pim_mroute_set(int fd, int enable)
{
- int err;
- int opt = enable ? MRT_INIT : MRT_DONE;
- socklen_t opt_len = sizeof(opt);
- int rcvbuf = 1024 * 1024 * 8;
- long flags;
-
- err = setsockopt(fd, IPPROTO_IP, opt, &opt, opt_len);
- if (err) {
- zlog_warn("%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,%s=%d): errno=%d: %s",
- __FILE__, __PRETTY_FUNCTION__,
- fd, enable ? "MRT_INIT" : "MRT_DONE", opt, errno, safe_strerror(errno));
- return -1;
- }
-
- err = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
- if (err) {
- zlog_warn("%s: failure: setsockopt(fd=%d, SOL_SOCKET, %d): errno=%d: %s",
- __PRETTY_FUNCTION__, fd, rcvbuf, errno, safe_strerror(errno));
- }
-
- flags = fcntl(fd, F_GETFL, 0);
- if (flags < 0)
- {
- zlog_warn("Could not get flags on socket fd:%d %d %s",
- fd, errno, safe_strerror(errno));
- close (fd);
- return -1;
- }
- if (fcntl(fd, F_SETFL, flags | O_NONBLOCK))
- {
- zlog_warn("Could not set O_NONBLOCK on socket fd:%d %d %s",
- fd, errno, safe_strerror(errno));
- close(fd);
- return -1;
- }
+ int err;
+ int opt = enable ? MRT_INIT : MRT_DONE;
+ socklen_t opt_len = sizeof(opt);
+ int rcvbuf = 1024 * 1024 * 8;
+ long flags;
+
+ err = setsockopt(fd, IPPROTO_IP, opt, &opt, opt_len);
+ if (err) {
+ zlog_warn(
+ "%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,%s=%d): errno=%d: %s",
+ __FILE__, __PRETTY_FUNCTION__, fd,
+ enable ? "MRT_INIT" : "MRT_DONE", opt, errno,
+ safe_strerror(errno));
+ return -1;
+ }
- if (enable)
- {
+ err = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
+ if (err) {
+ zlog_warn(
+ "%s: failure: setsockopt(fd=%d, SOL_SOCKET, %d): errno=%d: %s",
+ __PRETTY_FUNCTION__, fd, rcvbuf, errno,
+ safe_strerror(errno));
+ }
+
+ flags = fcntl(fd, F_GETFL, 0);
+ if (flags < 0) {
+ zlog_warn("Could not get flags on socket fd:%d %d %s", fd,
+ errno, safe_strerror(errno));
+ close(fd);
+ return -1;
+ }
+ if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) {
+ zlog_warn("Could not set O_NONBLOCK on socket fd:%d %d %s", fd,
+ errno, safe_strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+ if (enable) {
#if defined linux
- int upcalls = IGMPMSG_WRVIFWHOLE;
- opt = MRT_PIM;
-
- err = setsockopt (fd, IPPROTO_IP, opt, &upcalls, sizeof (upcalls));
- if (err)
- {
- zlog_warn ("Failure to register for VIFWHOLE and WRONGVIF upcalls %d %s",
- errno, safe_strerror (errno));
- return -1;
- }
+ int upcalls = IGMPMSG_WRVIFWHOLE;
+ opt = MRT_PIM;
+
+ err = setsockopt(fd, IPPROTO_IP, opt, &upcalls,
+ sizeof(upcalls));
+ if (err) {
+ zlog_warn(
+ "Failure to register for VIFWHOLE and WRONGVIF upcalls %d %s",
+ errno, safe_strerror(errno));
+ return -1;
+ }
#else
- zlog_warn ("PIM-SM will not work properly on this platform, until the ability to receive the WRVIFWHOLE upcall");
+ zlog_warn(
+ "PIM-SM will not work properly on this platform, until the ability to receive the WRVIFWHOLE upcall");
#endif
- }
-
- return 0;
+ }
+
+ return 0;
}
static const char *igmpmsgtype2str[IGMPMSG_WRVIFWHOLE + 1] = {
- "<unknown_upcall?>",
- "NOCACHE",
- "WRONGVIF",
- "WHOLEPKT",
- "WRVIFWHOLE" };
-
-static int
-pim_mroute_msg_nocache (int fd, struct interface *ifp, const struct igmpmsg *msg)
+ "<unknown_upcall?>", "NOCACHE", "WRONGVIF", "WHOLEPKT", "WRVIFWHOLE"};
+
+static int pim_mroute_msg_nocache(int fd, struct interface *ifp,
+ const struct igmpmsg *msg)
{
- struct pim_interface *pim_ifp = ifp->info;
- struct pim_upstream *up;
- struct pim_rpf *rpg;
- struct prefix_sg sg;
-
- rpg = RP(msg->im_dst);
- /*
- * If the incoming interface is unknown OR
- * the Interface type is SSM we don't need to
- * do anything here
- */
- if ((pim_rpf_addr_is_inaddr_none (rpg)) ||
- (!pim_ifp) ||
- (!(PIM_I_am_DR(pim_ifp))))
- {
- if (PIM_DEBUG_MROUTE_DETAIL)
- zlog_debug ("%s: Interface is not configured correctly to handle incoming packet: Could be !DR, !pim_ifp, !SM, !RP",
- __PRETTY_FUNCTION__);
- return 0;
- }
+ struct pim_interface *pim_ifp = ifp->info;
+ struct pim_upstream *up;
+ struct pim_rpf *rpg;
+ struct prefix_sg sg;
+
+ rpg = RP(msg->im_dst);
+ /*
+ * If the incoming interface is unknown OR
+ * the Interface type is SSM we don't need to
+ * do anything here
+ */
+ if ((pim_rpf_addr_is_inaddr_none(rpg)) || (!pim_ifp)
+ || (!(PIM_I_am_DR(pim_ifp)))) {
+ if (PIM_DEBUG_MROUTE_DETAIL)
+ zlog_debug(
+ "%s: Interface is not configured correctly to handle incoming packet: Could be !DR, !pim_ifp, !SM, !RP",
+ __PRETTY_FUNCTION__);
+ return 0;
+ }
- /*
- * If we've received a multicast packet that isn't connected to
- * us
- */
- if (!pim_if_connected_to_source (ifp, msg->im_src))
- {
- if (PIM_DEBUG_MROUTE_DETAIL)
- zlog_debug ("%s: Received incoming packet that doesn't originate on our seg",
- __PRETTY_FUNCTION__);
- return 0;
- }
+ /*
+ * If we've received a multicast packet that isn't connected to
+ * us
+ */
+ if (!pim_if_connected_to_source(ifp, msg->im_src)) {
+ if (PIM_DEBUG_MROUTE_DETAIL)
+ zlog_debug(
+ "%s: Received incoming packet that doesn't originate on our seg",
+ __PRETTY_FUNCTION__);
+ return 0;
+ }
- memset (&sg, 0, sizeof (struct prefix_sg));
- sg.src = msg->im_src;
- sg.grp = msg->im_dst;
+ memset(&sg, 0, sizeof(struct prefix_sg));
+ sg.src = msg->im_src;
+ sg.grp = msg->im_dst;
+
+ up = pim_upstream_find_or_add(&sg, ifp, PIM_UPSTREAM_FLAG_MASK_FHR,
+ __PRETTY_FUNCTION__);
+ if (!up) {
+ if (PIM_DEBUG_MROUTE) {
+ zlog_debug(
+ "%s: Failure to add upstream information for %s",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(&sg));
+ }
+ return 0;
+ }
- up = pim_upstream_find_or_add (&sg, ifp, PIM_UPSTREAM_FLAG_MASK_FHR, __PRETTY_FUNCTION__);
- if (!up)
- {
- if (PIM_DEBUG_MROUTE)
- {
- zlog_debug("%s: Failure to add upstream information for %s",
- __PRETTY_FUNCTION__,
- pim_str_sg_dump (&sg));
- }
- return 0;
- }
+ /*
+ * I moved this debug till after the actual add because
+ * I want to take advantage of the up->sg_str being filled in.
+ */
+ if (PIM_DEBUG_MROUTE) {
+ zlog_debug("%s: Adding a Route %s for WHOLEPKT consumption",
+ __PRETTY_FUNCTION__, up->sg_str);
+ }
- /*
- * I moved this debug till after the actual add because
- * I want to take advantage of the up->sg_str being filled in.
- */
- if (PIM_DEBUG_MROUTE) {
- zlog_debug("%s: Adding a Route %s for WHOLEPKT consumption",
- __PRETTY_FUNCTION__, up->sg_str);
- }
-
- PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags);
- pim_upstream_keep_alive_timer_start (up, qpim_keep_alive_time);
-
- up->channel_oil->cc.pktcnt++;
- PIM_UPSTREAM_FLAG_SET_FHR(up->flags);
- // resolve mfcc_parent prior to mroute_add in channel_add_oif
- if (up->channel_oil->oil.mfcc_parent >= MAXVIFS)
- {
- int vif_index = 0;
- vif_index =
- pim_if_find_vifindex_by_ifindex (up->rpf.source_nexthop.
- interface->ifindex);
- up->channel_oil->oil.mfcc_parent = vif_index;
- }
- pim_register_join (up);
+ PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags);
+ pim_upstream_keep_alive_timer_start(up, qpim_keep_alive_time);
+
+ up->channel_oil->cc.pktcnt++;
+ PIM_UPSTREAM_FLAG_SET_FHR(up->flags);
+ // resolve mfcc_parent prior to mroute_add in channel_add_oif
+ if (up->channel_oil->oil.mfcc_parent >= MAXVIFS) {
+ int vif_index = 0;
+ vif_index = pim_if_find_vifindex_by_ifindex(
+ up->rpf.source_nexthop.interface->ifindex);
+ up->channel_oil->oil.mfcc_parent = vif_index;
+ }
+ pim_register_join(up);
- return 0;
+ return 0;
}
-static int
-pim_mroute_msg_wholepkt (int fd, struct interface *ifp, const char *buf)
+static int pim_mroute_msg_wholepkt(int fd, struct interface *ifp,
+ const char *buf)
{
- struct pim_interface *pim_ifp;
- struct prefix_sg sg;
- struct pim_rpf *rpg;
- const struct ip *ip_hdr;
- struct pim_upstream *up;
-
- ip_hdr = (const struct ip *)buf;
-
- memset (&sg, 0, sizeof (struct prefix_sg));
- sg.src = ip_hdr->ip_src;
- sg.grp = ip_hdr->ip_dst;
-
- up = pim_upstream_find(&sg);
- if (!up) {
- struct prefix_sg star = sg;
- star.src.s_addr = INADDR_ANY;
-
- up = pim_upstream_find(&star);
-
- if (up && PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(up->flags))
- {
- up = pim_upstream_add (&sg, ifp, PIM_UPSTREAM_FLAG_MASK_SRC_LHR, __PRETTY_FUNCTION__);
- if (!up)
- {
- if (PIM_DEBUG_MROUTE)
- zlog_debug ("%s: Unable to create upstream information for %s",
- __PRETTY_FUNCTION__, pim_str_sg_dump (&sg));
- return 0;
- }
- pim_upstream_keep_alive_timer_start (up, qpim_keep_alive_time);
- pim_upstream_inherited_olist (up);
- pim_upstream_switch(up, PIM_UPSTREAM_JOINED);
-
- if (PIM_DEBUG_MROUTE)
- zlog_debug ("%s: Creating %s upstream on LHR",
- __PRETTY_FUNCTION__, up->sg_str);
- return 0;
- }
- if (PIM_DEBUG_MROUTE_DETAIL) {
- zlog_debug("%s: Unable to find upstream channel WHOLEPKT%s",
- __PRETTY_FUNCTION__, pim_str_sg_dump (&sg));
- }
- return 0;
- }
+ struct pim_interface *pim_ifp;
+ struct prefix_sg sg;
+ struct pim_rpf *rpg;
+ const struct ip *ip_hdr;
+ struct pim_upstream *up;
+
+ ip_hdr = (const struct ip *)buf;
+
+ memset(&sg, 0, sizeof(struct prefix_sg));
+ sg.src = ip_hdr->ip_src;
+ sg.grp = ip_hdr->ip_dst;
+
+ up = pim_upstream_find(&sg);
+ if (!up) {
+ struct prefix_sg star = sg;
+ star.src.s_addr = INADDR_ANY;
+
+ up = pim_upstream_find(&star);
+
+ if (up && PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(up->flags)) {
+ up = pim_upstream_add(&sg, ifp,
+ PIM_UPSTREAM_FLAG_MASK_SRC_LHR,
+ __PRETTY_FUNCTION__);
+ if (!up) {
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug(
+ "%s: Unable to create upstream information for %s",
+ __PRETTY_FUNCTION__,
+ pim_str_sg_dump(&sg));
+ return 0;
+ }
+ pim_upstream_keep_alive_timer_start(
+ up, qpim_keep_alive_time);
+ pim_upstream_inherited_olist(up);
+ pim_upstream_switch(up, PIM_UPSTREAM_JOINED);
+
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug("%s: Creating %s upstream on LHR",
+ __PRETTY_FUNCTION__, up->sg_str);
+ return 0;
+ }
+ if (PIM_DEBUG_MROUTE_DETAIL) {
+ zlog_debug(
+ "%s: Unable to find upstream channel WHOLEPKT%s",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(&sg));
+ }
+ return 0;
+ }
- pim_ifp = up->rpf.source_nexthop.interface->info;
+ pim_ifp = up->rpf.source_nexthop.interface->info;
- rpg = RP(sg.grp);
+ rpg = RP(sg.grp);
- if ((pim_rpf_addr_is_inaddr_none (rpg)) ||
- (!pim_ifp) ||
- (!(PIM_I_am_DR(pim_ifp)))) {
- if (PIM_DEBUG_MROUTE) {
- zlog_debug("%s: Failed Check send packet", __PRETTY_FUNCTION__);
- }
- return 0;
- }
+ if ((pim_rpf_addr_is_inaddr_none(rpg)) || (!pim_ifp)
+ || (!(PIM_I_am_DR(pim_ifp)))) {
+ if (PIM_DEBUG_MROUTE) {
+ zlog_debug("%s: Failed Check send packet",
+ __PRETTY_FUNCTION__);
+ }
+ return 0;
+ }
- /*
- * If we've received a register suppress
- */
- if (!up->t_rs_timer)
- {
- if (pim_is_grp_ssm (sg.grp))
- {
- if (PIM_DEBUG_PIM_REG)
- zlog_debug ("%s register forward skipped as group is SSM",
- pim_str_sg_dump (&sg));
- return 0;
- }
- pim_register_send((uint8_t *)buf + sizeof(struct ip),
- ntohs (ip_hdr->ip_len) - sizeof (struct ip),
- pim_ifp->primary_address, rpg, 0, up);
- }
- return 0;
+ /*
+ * If we've received a register suppress
+ */
+ if (!up->t_rs_timer) {
+ if (pim_is_grp_ssm(sg.grp)) {
+ if (PIM_DEBUG_PIM_REG)
+ zlog_debug(
+ "%s register forward skipped as group is SSM",
+ pim_str_sg_dump(&sg));
+ return 0;
+ }
+ pim_register_send((uint8_t *)buf + sizeof(struct ip),
+ ntohs(ip_hdr->ip_len) - sizeof(struct ip),
+ pim_ifp->primary_address, rpg, 0, up);
+ }
+ return 0;
}
-static int
-pim_mroute_msg_wrongvif (int fd, struct interface *ifp, const struct igmpmsg *msg)
+static int pim_mroute_msg_wrongvif(int fd, struct interface *ifp,
+ const struct igmpmsg *msg)
{
- struct pim_ifchannel *ch;
- struct pim_interface *pim_ifp;
- struct prefix_sg sg;
+ struct pim_ifchannel *ch;
+ struct pim_interface *pim_ifp;
+ struct prefix_sg sg;
+
+ memset(&sg, 0, sizeof(struct prefix_sg));
+ sg.src = msg->im_src;
+ sg.grp = msg->im_dst;
+
+ /*
+ Send Assert(S,G) on iif as response to WRONGVIF kernel upcall.
+
+ RFC 4601 4.8.2. PIM-SSM-Only Routers
+
+ iif is the incoming interface of the packet.
+ if (iif is in inherited_olist(S,G)) {
+ send Assert(S,G) on iif
+ }
+ */
+
+ if (!ifp) {
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug(
+ "%s: WRONGVIF (S,G)=%s could not find input interface for input_vif_index=%d",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(&sg),
+ msg->im_vif);
+ return -1;
+ }
- memset (&sg, 0, sizeof (struct prefix_sg));
- sg.src = msg->im_src;
- sg.grp = msg->im_dst;
+ pim_ifp = ifp->info;
+ if (!pim_ifp) {
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug(
+ "%s: WRONGVIF (S,G)=%s multicast not enabled on interface %s",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(&sg),
+ ifp->name);
+ return -2;
+ }
- /*
- Send Assert(S,G) on iif as response to WRONGVIF kernel upcall.
+ ch = pim_ifchannel_find(ifp, &sg);
+ if (!ch) {
+ struct prefix_sg star_g = sg;
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug(
+ "%s: WRONGVIF (S,G)=%s could not find channel on interface %s",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(&sg),
+ ifp->name);
+
+ star_g.src.s_addr = INADDR_ANY;
+ ch = pim_ifchannel_find(ifp, &star_g);
+ if (!ch) {
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug(
+ "%s: WRONGVIF (*,G)=%s could not find channel on interface %s",
+ __PRETTY_FUNCTION__,
+ pim_str_sg_dump(&star_g), ifp->name);
+ return -3;
+ }
+ }
- RFC 4601 4.8.2. PIM-SSM-Only Routers
+ /*
+ RFC 4601: 4.6.1. (S,G) Assert Message State Machine
+
+ Transitions from NoInfo State
+
+ An (S,G) data packet arrives on interface I, AND
+ CouldAssert(S,G,I)==TRUE An (S,G) data packet arrived on an
+ downstream interface that is in our (S,G) outgoing interface
+ list. We optimistically assume that we will be the assert
+ winner for this (S,G), and so we transition to the "I am Assert
+ Winner" state and perform Actions A1 (below), which will
+ initiate the assert negotiation for (S,G).
+ */
+
+ if (ch->ifassert_state != PIM_IFASSERT_NOINFO) {
+ if (PIM_DEBUG_MROUTE) {
+ zlog_debug(
+ "%s: WRONGVIF (S,G)=%s channel is not on Assert NoInfo state for interface %s",
+ __PRETTY_FUNCTION__, ch->sg_str, ifp->name);
+ }
+ return -4;
+ }
- iif is the incoming interface of the packet.
- if (iif is in inherited_olist(S,G)) {
- send Assert(S,G) on iif
- }
- */
-
- if (!ifp) {
- if (PIM_DEBUG_MROUTE)
- zlog_debug("%s: WRONGVIF (S,G)=%s could not find input interface for input_vif_index=%d",
- __PRETTY_FUNCTION__,
- pim_str_sg_dump (&sg), msg->im_vif);
- return -1;
- }
-
- pim_ifp = ifp->info;
- if (!pim_ifp) {
- if (PIM_DEBUG_MROUTE)
- zlog_debug("%s: WRONGVIF (S,G)=%s multicast not enabled on interface %s",
- __PRETTY_FUNCTION__,
- pim_str_sg_dump (&sg), ifp->name);
- return -2;
- }
-
- ch = pim_ifchannel_find(ifp, &sg);
- if (!ch) {
- struct prefix_sg star_g = sg;
- if (PIM_DEBUG_MROUTE)
- zlog_debug("%s: WRONGVIF (S,G)=%s could not find channel on interface %s",
- __PRETTY_FUNCTION__,
- pim_str_sg_dump(&sg), ifp->name);
-
- star_g.src.s_addr = INADDR_ANY;
- ch = pim_ifchannel_find(ifp, &star_g);
- if (!ch) {
- if (PIM_DEBUG_MROUTE)
- zlog_debug("%s: WRONGVIF (*,G)=%s could not find channel on interface %s",
- __PRETTY_FUNCTION__,
- pim_str_sg_dump(&star_g), ifp->name);
- return -3;
- }
- }
-
- /*
- RFC 4601: 4.6.1. (S,G) Assert Message State Machine
-
- Transitions from NoInfo State
-
- An (S,G) data packet arrives on interface I, AND
- CouldAssert(S,G,I)==TRUE An (S,G) data packet arrived on an
- downstream interface that is in our (S,G) outgoing interface
- list. We optimistically assume that we will be the assert
- winner for this (S,G), and so we transition to the "I am Assert
- Winner" state and perform Actions A1 (below), which will
- initiate the assert negotiation for (S,G).
- */
-
- if (ch->ifassert_state != PIM_IFASSERT_NOINFO) {
- if (PIM_DEBUG_MROUTE) {
- zlog_debug("%s: WRONGVIF (S,G)=%s channel is not on Assert NoInfo state for interface %s",
- __PRETTY_FUNCTION__,
- ch->sg_str, ifp->name);
- }
- return -4;
- }
-
- if (!PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags)) {
- if (PIM_DEBUG_MROUTE) {
- zlog_debug("%s: WRONGVIF (S,G)=%s interface %s is not downstream for channel",
- __PRETTY_FUNCTION__,
- ch->sg_str, ifp->name);
- }
- return -5;
- }
-
- if (assert_action_a1(ch)) {
- if (PIM_DEBUG_MROUTE) {
- zlog_debug("%s: WRONGVIF (S,G)=%s assert_action_a1 failure on interface %s",
- __PRETTY_FUNCTION__,
- ch->sg_str, ifp->name);
- }
- return -6;
- }
+ if (!PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags)) {
+ if (PIM_DEBUG_MROUTE) {
+ zlog_debug(
+ "%s: WRONGVIF (S,G)=%s interface %s is not downstream for channel",
+ __PRETTY_FUNCTION__, ch->sg_str, ifp->name);
+ }
+ return -5;
+ }
+
+ if (assert_action_a1(ch)) {
+ if (PIM_DEBUG_MROUTE) {
+ zlog_debug(
+ "%s: WRONGVIF (S,G)=%s assert_action_a1 failure on interface %s",
+ __PRETTY_FUNCTION__, ch->sg_str, ifp->name);
+ }
+ return -6;
+ }
- return 0;
+ return 0;
}
-static int
-pim_mroute_msg_wrvifwhole (int fd, struct interface *ifp, const char *buf)
+static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp,
+ const char *buf)
{
- const struct ip *ip_hdr = (const struct ip *)buf;
- struct pim_interface *pim_ifp;
- struct pim_ifchannel *ch;
- struct pim_upstream *up;
- struct prefix_sg star_g;
- struct prefix_sg sg;
- struct channel_oil *oil;
-
- memset (&sg, 0, sizeof (struct prefix_sg));
- sg.src = ip_hdr->ip_src;
- sg.grp = ip_hdr->ip_dst;
-
- ch = pim_ifchannel_find(ifp, &sg);
- if (ch)
- {
- if (PIM_DEBUG_MROUTE)
- zlog_debug ("WRVIFWHOLE (S,G)=%s found ifchannel on interface %s",
- ch->sg_str, ifp->name);
- return -1;
- }
+ const struct ip *ip_hdr = (const struct ip *)buf;
+ struct pim_interface *pim_ifp;
+ struct pim_ifchannel *ch;
+ struct pim_upstream *up;
+ struct prefix_sg star_g;
+ struct prefix_sg sg;
+ struct channel_oil *oil;
+
+ memset(&sg, 0, sizeof(struct prefix_sg));
+ sg.src = ip_hdr->ip_src;
+ sg.grp = ip_hdr->ip_dst;
+
+ ch = pim_ifchannel_find(ifp, &sg);
+ if (ch) {
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug(
+ "WRVIFWHOLE (S,G)=%s found ifchannel on interface %s",
+ ch->sg_str, ifp->name);
+ return -1;
+ }
- star_g = sg;
- star_g.src.s_addr = INADDR_ANY;
+ star_g = sg;
+ star_g.src.s_addr = INADDR_ANY;
#if 0
ch = pim_ifchannel_find(ifp, &star_g);
if (ch)
@@ -410,290 +412,313 @@ pim_mroute_msg_wrvifwhole (int fd, struct interface *ifp, const char *buf)
}
#endif
- up = pim_upstream_find (&sg);
- if (up)
- {
- struct pim_upstream *parent;
- struct pim_nexthop source;
- struct pim_rpf *rpf = RP (sg.grp);
- if (!rpf || !rpf->source_nexthop.interface)
- return 0;
-
- /*
- * If we have received a WRVIFWHOLE and are at this
- * point, we could be receiving the packet on the *,G
- * tree, let's check and if so we can safely drop
- * it.
- */
- parent = pim_upstream_find (&star_g);
- if (parent && parent->rpf.source_nexthop.interface == ifp)
- return 0;
-
- pim_ifp = rpf->source_nexthop.interface->info;
-
- memset (&source, 0, sizeof (source));
- /*
- * If we are the fhr that means we are getting a callback during
- * the pimreg period, so I believe we can ignore this packet
- */
- if (!PIM_UPSTREAM_FLAG_TEST_FHR(up->flags))
- {
- //No if channel, but upstream we are at the RP.
- if (pim_nexthop_lookup (&source, up->upstream_register, 0) == 0)
- pim_register_stop_send(source.interface, &sg, pim_ifp->primary_address, up->upstream_register);
- if (!up->channel_oil)
- up->channel_oil = pim_channel_oil_add (&sg, pim_ifp->mroute_vif_index);
- pim_upstream_inherited_olist (up);
- if (!up->channel_oil->installed)
- pim_mroute_add (up->channel_oil, __PRETTY_FUNCTION__);
- pim_upstream_set_sptbit (up, ifp);
- }
- else
- {
- if (I_am_RP (up->sg.grp))
- {
- if (pim_nexthop_lookup (&source, up->upstream_register, 0) == 0)
- pim_register_stop_send(source.interface, &sg, pim_ifp->primary_address, up->upstream_register);
- up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
- }
- pim_upstream_keep_alive_timer_start (up, qpim_keep_alive_time);
- pim_upstream_inherited_olist (up);
- pim_mroute_msg_wholepkt (fd, ifp, buf);
- }
- return 0;
- }
+ up = pim_upstream_find(&sg);
+ if (up) {
+ struct pim_upstream *parent;
+ struct pim_nexthop source;
+ struct pim_rpf *rpf = RP(sg.grp);
+ if (!rpf || !rpf->source_nexthop.interface)
+ return 0;
+
+ /*
+ * If we have received a WRVIFWHOLE and are at this
+ * point, we could be receiving the packet on the *,G
+ * tree, let's check and if so we can safely drop
+ * it.
+ */
+ parent = pim_upstream_find(&star_g);
+ if (parent && parent->rpf.source_nexthop.interface == ifp)
+ return 0;
+
+ pim_ifp = rpf->source_nexthop.interface->info;
+
+ memset(&source, 0, sizeof(source));
+ /*
+ * If we are the fhr that means we are getting a callback during
+ * the pimreg period, so I believe we can ignore this packet
+ */
+ if (!PIM_UPSTREAM_FLAG_TEST_FHR(up->flags)) {
+ // No if channel, but upstream we are at the RP.
+ if (pim_nexthop_lookup(&source, up->upstream_register,
+ 0)
+ == 0)
+ pim_register_stop_send(source.interface, &sg,
+ pim_ifp->primary_address,
+ up->upstream_register);
+ if (!up->channel_oil)
+ up->channel_oil = pim_channel_oil_add(
+ &sg, pim_ifp->mroute_vif_index);
+ pim_upstream_inherited_olist(up);
+ if (!up->channel_oil->installed)
+ pim_mroute_add(up->channel_oil,
+ __PRETTY_FUNCTION__);
+ pim_upstream_set_sptbit(up, ifp);
+ } else {
+ if (I_am_RP(up->sg.grp)) {
+ if (pim_nexthop_lookup(&source,
+ up->upstream_register, 0)
+ == 0)
+ pim_register_stop_send(
+ source.interface, &sg,
+ pim_ifp->primary_address,
+ up->upstream_register);
+ up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
+ }
+ pim_upstream_keep_alive_timer_start(
+ up, qpim_keep_alive_time);
+ pim_upstream_inherited_olist(up);
+ pim_mroute_msg_wholepkt(fd, ifp, buf);
+ }
+ return 0;
+ }
- pim_ifp = ifp->info;
- oil = pim_channel_oil_add (&sg, pim_ifp->mroute_vif_index);
- if (!oil->installed)
- pim_mroute_add (oil, __PRETTY_FUNCTION__);
- if (pim_if_connected_to_source (ifp, sg.src))
- {
- up = pim_upstream_add (&sg, ifp, PIM_UPSTREAM_FLAG_MASK_FHR, __PRETTY_FUNCTION__);
- if (!up)
- {
- if (PIM_DEBUG_MROUTE)
- zlog_debug ("%s: WRONGVIF%s unable to create upstream on interface",
- pim_str_sg_dump (&sg), ifp->name);
- return -2;
- }
- PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags);
- pim_upstream_keep_alive_timer_start (up, qpim_keep_alive_time);
- up->channel_oil = oil;
- up->channel_oil->cc.pktcnt++;
- pim_register_join (up);
- pim_upstream_inherited_olist (up);
-
- // Send the packet to the RP
- pim_mroute_msg_wholepkt (fd, ifp, buf);
- }
+ pim_ifp = ifp->info;
+ oil = pim_channel_oil_add(&sg, pim_ifp->mroute_vif_index);
+ if (!oil->installed)
+ pim_mroute_add(oil, __PRETTY_FUNCTION__);
+ if (pim_if_connected_to_source(ifp, sg.src)) {
+ up = pim_upstream_add(&sg, ifp, PIM_UPSTREAM_FLAG_MASK_FHR,
+ __PRETTY_FUNCTION__);
+ if (!up) {
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug(
+ "%s: WRONGVIF%s unable to create upstream on interface",
+ pim_str_sg_dump(&sg), ifp->name);
+ return -2;
+ }
+ PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags);
+ pim_upstream_keep_alive_timer_start(up, qpim_keep_alive_time);
+ up->channel_oil = oil;
+ up->channel_oil->cc.pktcnt++;
+ pim_register_join(up);
+ pim_upstream_inherited_olist(up);
+
+ // Send the packet to the RP
+ pim_mroute_msg_wholepkt(fd, ifp, buf);
+ }
- return 0;
+ return 0;
}
int pim_mroute_msg(int fd, const char *buf, int buf_size)
{
- struct interface *ifp;
- struct pim_interface *pim_ifp;
- const struct ip *ip_hdr;
- const struct igmpmsg *msg;
- char ip_src_str[INET_ADDRSTRLEN] = "";
- char ip_dst_str[INET_ADDRSTRLEN] = "";
- char src_str[INET_ADDRSTRLEN] = "<src?>";
- char grp_str[INET_ADDRSTRLEN] = "<grp?>";
- struct in_addr ifaddr;
- struct igmp_sock *igmp;
-
- ip_hdr = (const struct ip *) buf;
-
- if (ip_hdr->ip_p == IPPROTO_IGMP) {
-
- /* We have the IP packet but we do not know which interface this packet was
- * received on. Find the interface that is on the same subnet as the source
- * of the IP packet.
- */
- ifp = pim_if_lookup_address_vrf (ip_hdr->ip_src, VRF_DEFAULT);
-
- if (!ifp) {
- if (PIM_DEBUG_MROUTE_DETAIL) {
- pim_inet4_dump("<src?>", ip_hdr->ip_src, ip_src_str, sizeof(ip_src_str));
- pim_inet4_dump("<dst?>", ip_hdr->ip_dst, ip_dst_str, sizeof(ip_dst_str));
-
- zlog_warn("%s: igmp kernel upcall could not find usable interface for %s -> %s",
- __PRETTY_FUNCTION__,
- ip_src_str,
- ip_dst_str);
- }
- return 0;
- }
- pim_ifp = ifp->info;
- ifaddr = pim_find_primary_addr(ifp);
- igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->igmp_socket_list, ifaddr);
-
- if (PIM_DEBUG_MROUTE) {
- pim_inet4_dump("<src?>", ip_hdr->ip_src, ip_src_str, sizeof(ip_src_str));
- pim_inet4_dump("<dst?>", ip_hdr->ip_dst, ip_dst_str, sizeof(ip_dst_str));
-
- zlog_warn("%s: igmp kernel upcall on %s(%p) for %s -> %s",
- __PRETTY_FUNCTION__, ifp->name, igmp, ip_src_str, ip_dst_str);
- }
- if (igmp)
- pim_igmp_packet(igmp, (char *)buf, buf_size);
-
- } else if (ip_hdr->ip_p) {
- if (PIM_DEBUG_MROUTE_DETAIL) {
- pim_inet4_dump("<src?>", ip_hdr->ip_src, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", ip_hdr->ip_dst, grp_str, sizeof(grp_str));
- zlog_debug("%s: no kernel upcall proto=%d src: %s dst: %s msg_size=%d",
- __PRETTY_FUNCTION__, ip_hdr->ip_p, src_str, grp_str, buf_size);
- }
-
- } else {
- msg = (const struct igmpmsg *) buf;
-
- ifp = pim_if_find_by_vif_index(msg->im_vif);
-
- if (!ifp)
- return 0;
- if (PIM_DEBUG_MROUTE) {
- pim_inet4_dump("<src?>", msg->im_src, src_str, sizeof(src_str));
- pim_inet4_dump("<grp?>", msg->im_dst, grp_str, sizeof(grp_str));
- zlog_warn("%s: pim kernel upcall %s type=%d ip_p=%d from fd=%d for (S,G)=(%s,%s) on %s vifi=%d size=%d",
- __PRETTY_FUNCTION__,
- igmpmsgtype2str[msg->im_msgtype],
- msg->im_msgtype,
- ip_hdr->ip_p,
- fd,
- src_str,
- grp_str,
- ifp->name,
- msg->im_vif, buf_size);
- }
-
- switch (msg->im_msgtype) {
- case IGMPMSG_WRONGVIF:
- return pim_mroute_msg_wrongvif(fd, ifp, msg);
- break;
- case IGMPMSG_NOCACHE:
- return pim_mroute_msg_nocache(fd, ifp, msg);
- break;
- case IGMPMSG_WHOLEPKT:
- return pim_mroute_msg_wholepkt(fd, ifp, (const char *)msg);
- break;
- case IGMPMSG_WRVIFWHOLE:
- return pim_mroute_msg_wrvifwhole (fd, ifp, (const char *)msg);
- break;
- default:
- break;
- }
- }
+ struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ const struct ip *ip_hdr;
+ const struct igmpmsg *msg;
+ char ip_src_str[INET_ADDRSTRLEN] = "";
+ char ip_dst_str[INET_ADDRSTRLEN] = "";
+ char src_str[INET_ADDRSTRLEN] = "<src?>";
+ char grp_str[INET_ADDRSTRLEN] = "<grp?>";
+ struct in_addr ifaddr;
+ struct igmp_sock *igmp;
+
+ ip_hdr = (const struct ip *)buf;
+
+ if (ip_hdr->ip_p == IPPROTO_IGMP) {
+
+ /* We have the IP packet but we do not know which interface this
+ * packet was
+ * received on. Find the interface that is on the same subnet as
+ * the source
+ * of the IP packet.
+ */
+ ifp = pim_if_lookup_address_vrf(ip_hdr->ip_src, VRF_DEFAULT);
+
+ if (!ifp) {
+ if (PIM_DEBUG_MROUTE_DETAIL) {
+ pim_inet4_dump("<src?>", ip_hdr->ip_src,
+ ip_src_str, sizeof(ip_src_str));
+ pim_inet4_dump("<dst?>", ip_hdr->ip_dst,
+ ip_dst_str, sizeof(ip_dst_str));
+
+ zlog_warn(
+ "%s: igmp kernel upcall could not find usable interface for %s -> %s",
+ __PRETTY_FUNCTION__, ip_src_str,
+ ip_dst_str);
+ }
+ return 0;
+ }
+ pim_ifp = ifp->info;
+ ifaddr = pim_find_primary_addr(ifp);
+ igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->igmp_socket_list,
+ ifaddr);
+
+ if (PIM_DEBUG_MROUTE) {
+ pim_inet4_dump("<src?>", ip_hdr->ip_src, ip_src_str,
+ sizeof(ip_src_str));
+ pim_inet4_dump("<dst?>", ip_hdr->ip_dst, ip_dst_str,
+ sizeof(ip_dst_str));
+
+ zlog_warn(
+ "%s: igmp kernel upcall on %s(%p) for %s -> %s",
+ __PRETTY_FUNCTION__, ifp->name, igmp,
+ ip_src_str, ip_dst_str);
+ }
+ if (igmp)
+ pim_igmp_packet(igmp, (char *)buf, buf_size);
+
+ } else if (ip_hdr->ip_p) {
+ if (PIM_DEBUG_MROUTE_DETAIL) {
+ pim_inet4_dump("<src?>", ip_hdr->ip_src, src_str,
+ sizeof(src_str));
+ pim_inet4_dump("<grp?>", ip_hdr->ip_dst, grp_str,
+ sizeof(grp_str));
+ zlog_debug(
+ "%s: no kernel upcall proto=%d src: %s dst: %s msg_size=%d",
+ __PRETTY_FUNCTION__, ip_hdr->ip_p, src_str,
+ grp_str, buf_size);
+ }
+
+ } else {
+ msg = (const struct igmpmsg *)buf;
+
+ ifp = pim_if_find_by_vif_index(msg->im_vif);
+
+ if (!ifp)
+ return 0;
+ if (PIM_DEBUG_MROUTE) {
+ pim_inet4_dump("<src?>", msg->im_src, src_str,
+ sizeof(src_str));
+ pim_inet4_dump("<grp?>", msg->im_dst, grp_str,
+ sizeof(grp_str));
+ zlog_warn(
+ "%s: pim kernel upcall %s type=%d ip_p=%d from fd=%d for (S,G)=(%s,%s) on %s vifi=%d size=%d",
+ __PRETTY_FUNCTION__,
+ igmpmsgtype2str[msg->im_msgtype],
+ msg->im_msgtype, ip_hdr->ip_p, fd, src_str,
+ grp_str, ifp->name, msg->im_vif, buf_size);
+ }
+
+ switch (msg->im_msgtype) {
+ case IGMPMSG_WRONGVIF:
+ return pim_mroute_msg_wrongvif(fd, ifp, msg);
+ break;
+ case IGMPMSG_NOCACHE:
+ return pim_mroute_msg_nocache(fd, ifp, msg);
+ break;
+ case IGMPMSG_WHOLEPKT:
+ return pim_mroute_msg_wholepkt(fd, ifp,
+ (const char *)msg);
+ break;
+ case IGMPMSG_WRVIFWHOLE:
+ return pim_mroute_msg_wrvifwhole(fd, ifp,
+ (const char *)msg);
+ break;
+ default:
+ break;
+ }
+ }
- return 0;
+ return 0;
}
static int mroute_read(struct thread *t)
{
- static long long count;
- char buf[10000];
- int result = 0;
- int cont = 1;
- int fd;
- int rd;
-
- fd = THREAD_FD(t);
-
- while (cont)
- {
- rd = read(fd, buf, sizeof(buf));
- if (rd < 0) {
- if (errno == EINTR)
- continue;
- if (errno == EWOULDBLOCK || errno == EAGAIN)
- break;
-
- if (PIM_DEBUG_MROUTE)
- zlog_warn("%s: failure reading fd=%d: errno=%d: %s",
- __PRETTY_FUNCTION__, fd, errno, safe_strerror(errno));
- goto done;
- }
-
- result = pim_mroute_msg(fd, buf, rd);
-
- count++;
- if (count % qpim_packet_process == 0)
- cont = 0;
- }
- /* Keep reading */
- done:
- mroute_read_on();
+ static long long count;
+ char buf[10000];
+ int result = 0;
+ int cont = 1;
+ int fd;
+ int rd;
+
+ fd = THREAD_FD(t);
+
+ while (cont) {
+ rd = read(fd, buf, sizeof(buf));
+ if (rd < 0) {
+ if (errno == EINTR)
+ continue;
+ if (errno == EWOULDBLOCK || errno == EAGAIN)
+ break;
+
+ if (PIM_DEBUG_MROUTE)
+ zlog_warn(
+ "%s: failure reading fd=%d: errno=%d: %s",
+ __PRETTY_FUNCTION__, fd, errno,
+ safe_strerror(errno));
+ goto done;
+ }
+
+ result = pim_mroute_msg(fd, buf, rd);
+
+ count++;
+ if (count % qpim_packet_process == 0)
+ cont = 0;
+ }
+/* Keep reading */
+done:
+ mroute_read_on();
- return result;
+ return result;
}
static void mroute_read_on()
{
- thread_add_read(master, mroute_read, 0, qpim_mroute_socket_fd,
- &qpim_mroute_socket_reader);
+ thread_add_read(master, mroute_read, 0, qpim_mroute_socket_fd,
+ &qpim_mroute_socket_reader);
}
static void mroute_read_off()
{
- THREAD_OFF(qpim_mroute_socket_reader);
+ THREAD_OFF(qpim_mroute_socket_reader);
}
int pim_mroute_socket_enable()
{
- int fd;
+ int fd;
- if ( pimd_privs.change (ZPRIVS_RAISE) )
- zlog_err ("pim_mroute_socket_enable: could not raise privs, %s",
- safe_strerror (errno) );
+ if (pimd_privs.change(ZPRIVS_RAISE))
+ zlog_err("pim_mroute_socket_enable: could not raise privs, %s",
+ safe_strerror(errno));
- fd = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP);
+ fd = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP);
- if ( pimd_privs.change (ZPRIVS_LOWER) )
- zlog_err ("pim_mroute_socket_enable: could not lower privs, %s",
- safe_strerror (errno) );
+ if (pimd_privs.change(ZPRIVS_LOWER))
+ zlog_err("pim_mroute_socket_enable: could not lower privs, %s",
+ safe_strerror(errno));
- if (fd < 0) {
- zlog_warn("Could not create mroute socket: errno=%d: %s",
- errno, safe_strerror(errno));
- return -2;
- }
+ if (fd < 0) {
+ zlog_warn("Could not create mroute socket: errno=%d: %s", errno,
+ safe_strerror(errno));
+ return -2;
+ }
- if (pim_mroute_set(fd, 1)) {
- zlog_warn("Could not enable mroute on socket fd=%d: errno=%d: %s",
- fd, errno, safe_strerror(errno));
- close(fd);
- return -3;
- }
+ if (pim_mroute_set(fd, 1)) {
+ zlog_warn(
+ "Could not enable mroute on socket fd=%d: errno=%d: %s",
+ fd, errno, safe_strerror(errno));
+ close(fd);
+ return -3;
+ }
- qpim_mroute_socket_fd = fd;
+ qpim_mroute_socket_fd = fd;
- qpim_mroute_socket_creation = pim_time_monotonic_sec();
- mroute_read_on();
+ qpim_mroute_socket_creation = pim_time_monotonic_sec();
+ mroute_read_on();
- return 0;
+ return 0;
}
int pim_mroute_socket_disable()
{
- if (pim_mroute_set(qpim_mroute_socket_fd, 0)) {
- zlog_warn("Could not disable mroute on socket fd=%d: errno=%d: %s",
- qpim_mroute_socket_fd, errno, safe_strerror(errno));
- return -2;
- }
-
- if (close(qpim_mroute_socket_fd)) {
- zlog_warn("Failure closing mroute socket: fd=%d errno=%d: %s",
- qpim_mroute_socket_fd, errno, safe_strerror(errno));
- return -3;
- }
-
- mroute_read_off();
- qpim_mroute_socket_fd = -1;
-
- return 0;
+ if (pim_mroute_set(qpim_mroute_socket_fd, 0)) {
+ zlog_warn(
+ "Could not disable mroute on socket fd=%d: errno=%d: %s",
+ qpim_mroute_socket_fd, errno, safe_strerror(errno));
+ return -2;
+ }
+
+ if (close(qpim_mroute_socket_fd)) {
+ zlog_warn("Failure closing mroute socket: fd=%d errno=%d: %s",
+ qpim_mroute_socket_fd, errno, safe_strerror(errno));
+ return -3;
+ }
+
+ mroute_read_off();
+ qpim_mroute_socket_fd = -1;
+
+ return 0;
}
/*
@@ -701,249 +726,248 @@ int pim_mroute_socket_disable()
would be used for multicast forwarding, a corresponding multicast
interface must be added to the kernel.
*/
-int pim_mroute_add_vif(struct interface *ifp, struct in_addr ifaddr, unsigned char flags)
+int pim_mroute_add_vif(struct interface *ifp, struct in_addr ifaddr,
+ unsigned char flags)
{
- struct pim_interface *pim_ifp = ifp->info;
- struct vifctl vc;
- int err;
+ struct pim_interface *pim_ifp = ifp->info;
+ struct vifctl vc;
+ int err;
- memset(&vc, 0, sizeof(vc));
- vc.vifc_vifi = pim_ifp->mroute_vif_index;
+ memset(&vc, 0, sizeof(vc));
+ vc.vifc_vifi = pim_ifp->mroute_vif_index;
#ifdef VIFF_USE_IFINDEX
- vc.vifc_lcl_ifindex = ifp->ifindex;
+ vc.vifc_lcl_ifindex = ifp->ifindex;
#else
- if (ifaddr.s_addr == INADDR_ANY) {
- zlog_warn("%s: unnumbered interfaces are not supported on this platform",
- __PRETTY_FUNCTION__);
- return -1;
- }
- memcpy(&vc.vifc_lcl_addr, &ifaddr, sizeof(vc.vifc_lcl_addr));
+ if (ifaddr.s_addr == INADDR_ANY) {
+ zlog_warn(
+ "%s: unnumbered interfaces are not supported on this platform",
+ __PRETTY_FUNCTION__);
+ return -1;
+ }
+ memcpy(&vc.vifc_lcl_addr, &ifaddr, sizeof(vc.vifc_lcl_addr));
#endif
- vc.vifc_flags = flags;
- vc.vifc_threshold = PIM_MROUTE_MIN_TTL;
- vc.vifc_rate_limit = 0;
-
-#ifdef PIM_DVMRP_TUNNEL
- if (vc.vifc_flags & VIFF_TUNNEL) {
- memcpy(&vc.vifc_rmt_addr, &vif_remote_addr, sizeof(vc.vifc_rmt_addr));
- }
+ vc.vifc_flags = flags;
+ vc.vifc_threshold = PIM_MROUTE_MIN_TTL;
+ vc.vifc_rate_limit = 0;
+
+#ifdef PIM_DVMRP_TUNNEL
+ if (vc.vifc_flags & VIFF_TUNNEL) {
+ memcpy(&vc.vifc_rmt_addr, &vif_remote_addr,
+ sizeof(vc.vifc_rmt_addr));
+ }
#endif
- err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_ADD_VIF, (void*) &vc, sizeof(vc));
- if (err) {
- char ifaddr_str[INET_ADDRSTRLEN];
+ err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_ADD_VIF,
+ (void *)&vc, sizeof(vc));
+ if (err) {
+ char ifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", ifaddr, ifaddr_str, sizeof(ifaddr_str));
+ pim_inet4_dump("<ifaddr?>", ifaddr, ifaddr_str,
+ sizeof(ifaddr_str));
- zlog_warn("%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_ADD_VIF,vif_index=%d,ifaddr=%s,flag=%d): errno=%d: %s",
- __FILE__, __PRETTY_FUNCTION__,
- qpim_mroute_socket_fd, ifp->ifindex, ifaddr_str, flags,
- errno, safe_strerror(errno));
- return -2;
- }
+ zlog_warn(
+ "%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_ADD_VIF,vif_index=%d,ifaddr=%s,flag=%d): errno=%d: %s",
+ __FILE__, __PRETTY_FUNCTION__, qpim_mroute_socket_fd,
+ ifp->ifindex, ifaddr_str, flags, errno,
+ safe_strerror(errno));
+ return -2;
+ }
- return 0;
+ return 0;
}
int pim_mroute_del_vif(int vif_index)
{
- struct vifctl vc;
- int err;
-
- if (PIM_DEBUG_MROUTE)
- {
- struct interface *ifp = pim_if_find_by_vif_index (vif_index);
- zlog_debug ("%s %s: Del Vif %d (%s) ", __FILE__,
- __PRETTY_FUNCTION__, vif_index, ifp ? ifp->name : "NULL");
- }
-
- memset(&vc, 0, sizeof(vc));
- vc.vifc_vifi = vif_index;
+ struct vifctl vc;
+ int err;
+
+ if (PIM_DEBUG_MROUTE) {
+ struct interface *ifp = pim_if_find_by_vif_index(vif_index);
+ zlog_debug("%s %s: Del Vif %d (%s) ", __FILE__,
+ __PRETTY_FUNCTION__, vif_index,
+ ifp ? ifp->name : "NULL");
+ }
- err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_DEL_VIF, (void*) &vc, sizeof(vc));
- if (err) {
- zlog_warn("%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_DEL_VIF,vif_index=%d): errno=%d: %s",
- __FILE__, __PRETTY_FUNCTION__,
- qpim_mroute_socket_fd, vif_index,
- errno, safe_strerror(errno));
- return -2;
- }
+ memset(&vc, 0, sizeof(vc));
+ vc.vifc_vifi = vif_index;
+
+ err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_DEL_VIF,
+ (void *)&vc, sizeof(vc));
+ if (err) {
+ zlog_warn(
+ "%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_DEL_VIF,vif_index=%d): errno=%d: %s",
+ __FILE__, __PRETTY_FUNCTION__, qpim_mroute_socket_fd,
+ vif_index, errno, safe_strerror(errno));
+ return -2;
+ }
- return 0;
+ return 0;
}
int pim_mroute_add(struct channel_oil *c_oil, const char *name)
{
- int err;
- int orig = 0;
- int orig_iif_vif = 0;
-
- qpim_mroute_add_last = pim_time_monotonic_sec();
- ++qpim_mroute_add_events;
-
- /* Do not install route if incoming interface is undefined. */
- if (c_oil->oil.mfcc_parent >= MAXVIFS)
- {
- if (PIM_DEBUG_MROUTE)
- {
- char buf[1000];
- zlog_debug("%s(%s) %s Attempting to add vifi that is invalid to mroute table",
- __PRETTY_FUNCTION__, name, pim_channel_oil_dump (c_oil, buf, sizeof(buf)));
- }
- return -2;
- }
-
- /* The linux kernel *expects* the incoming
- * vif to be part of the outgoing list
- * in the case of a (*,G).
- */
- if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
- {
- orig = c_oil->oil.mfcc_ttls[c_oil->oil.mfcc_parent];
- c_oil->oil.mfcc_ttls[c_oil->oil.mfcc_parent] = 1;
- }
+ int err;
+ int orig = 0;
+ int orig_iif_vif = 0;
+
+ qpim_mroute_add_last = pim_time_monotonic_sec();
+ ++qpim_mroute_add_events;
+
+ /* Do not install route if incoming interface is undefined. */
+ if (c_oil->oil.mfcc_parent >= MAXVIFS) {
+ if (PIM_DEBUG_MROUTE) {
+ char buf[1000];
+ zlog_debug(
+ "%s(%s) %s Attempting to add vifi that is invalid to mroute table",
+ __PRETTY_FUNCTION__, name,
+ pim_channel_oil_dump(c_oil, buf, sizeof(buf)));
+ }
+ return -2;
+ }
- /*
- * If we have an unresolved cache entry for the S,G
- * it is owned by the pimreg for the incoming IIF
- * So set pimreg as the IIF temporarily to cause
- * the packets to be forwarded. Then set it
- * to the correct IIF afterwords.
- */
- if (!c_oil->installed && c_oil->oil.mfcc_origin.s_addr != INADDR_ANY &&
- c_oil->oil.mfcc_parent != 0)
- {
- orig_iif_vif = c_oil->oil.mfcc_parent;
- c_oil->oil.mfcc_parent = 0;
- }
- err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_ADD_MFC,
- &c_oil->oil, sizeof(c_oil->oil));
+ /* The linux kernel *expects* the incoming
+ * vif to be part of the outgoing list
+ * in the case of a (*,G).
+ */
+ if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY) {
+ orig = c_oil->oil.mfcc_ttls[c_oil->oil.mfcc_parent];
+ c_oil->oil.mfcc_ttls[c_oil->oil.mfcc_parent] = 1;
+ }
- if (!err && !c_oil->installed && c_oil->oil.mfcc_origin.s_addr != INADDR_ANY &&
- orig_iif_vif != 0)
- {
- c_oil->oil.mfcc_parent = orig_iif_vif;
- err = setsockopt (qpim_mroute_socket_fd, IPPROTO_IP, MRT_ADD_MFC,
- &c_oil->oil, sizeof (c_oil->oil));
- }
+ /*
+ * If we have an unresolved cache entry for the S,G
+ * it is owned by the pimreg for the incoming IIF
+ * So set pimreg as the IIF temporarily to cause
+ * the packets to be forwarded. Then set it
+ * to the correct IIF afterwords.
+ */
+ if (!c_oil->installed && c_oil->oil.mfcc_origin.s_addr != INADDR_ANY
+ && c_oil->oil.mfcc_parent != 0) {
+ orig_iif_vif = c_oil->oil.mfcc_parent;
+ c_oil->oil.mfcc_parent = 0;
+ }
+ err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_ADD_MFC,
+ &c_oil->oil, sizeof(c_oil->oil));
+
+ if (!err && !c_oil->installed
+ && c_oil->oil.mfcc_origin.s_addr != INADDR_ANY
+ && orig_iif_vif != 0) {
+ c_oil->oil.mfcc_parent = orig_iif_vif;
+ err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_ADD_MFC,
+ &c_oil->oil, sizeof(c_oil->oil));
+ }
- if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
- c_oil->oil.mfcc_ttls[c_oil->oil.mfcc_parent] = orig;
+ if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
+ c_oil->oil.mfcc_ttls[c_oil->oil.mfcc_parent] = orig;
- if (err) {
- zlog_warn("%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_ADD_MFC): errno=%d: %s",
- __FILE__, __PRETTY_FUNCTION__,
- qpim_mroute_socket_fd,
- errno, safe_strerror(errno));
- return -2;
- }
+ if (err) {
+ zlog_warn(
+ "%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_ADD_MFC): errno=%d: %s",
+ __FILE__, __PRETTY_FUNCTION__, qpim_mroute_socket_fd,
+ errno, safe_strerror(errno));
+ return -2;
+ }
- if (PIM_DEBUG_MROUTE)
- {
- char buf[1000];
- zlog_debug("%s(%s), Added Route: %s",
- __PRETTY_FUNCTION__, name,
- pim_channel_oil_dump (c_oil, buf, sizeof(buf)));
- }
+ if (PIM_DEBUG_MROUTE) {
+ char buf[1000];
+ zlog_debug("%s(%s), Added Route: %s", __PRETTY_FUNCTION__, name,
+ pim_channel_oil_dump(c_oil, buf, sizeof(buf)));
+ }
- c_oil->installed = 1;
- return 0;
+ c_oil->installed = 1;
+ return 0;
}
-int pim_mroute_del (struct channel_oil *c_oil, const char *name)
+int pim_mroute_del(struct channel_oil *c_oil, const char *name)
{
- int err;
-
- qpim_mroute_del_last = pim_time_monotonic_sec();
- ++qpim_mroute_del_events;
+ int err;
+
+ qpim_mroute_del_last = pim_time_monotonic_sec();
+ ++qpim_mroute_del_events;
+
+ if (!c_oil->installed) {
+ if (PIM_DEBUG_MROUTE) {
+ char buf[1000];
+ zlog_debug(
+ "%s %s: vifi %d for route is %s not installed, do not need to send del req. ",
+ __FILE__, __PRETTY_FUNCTION__,
+ c_oil->oil.mfcc_parent,
+ pim_channel_oil_dump(c_oil, buf, sizeof(buf)));
+ }
+ return -2;
+ }
- if (!c_oil->installed)
- {
- if (PIM_DEBUG_MROUTE)
- {
- char buf[1000];
- zlog_debug("%s %s: vifi %d for route is %s not installed, do not need to send del req. ",
- __FILE__, __PRETTY_FUNCTION__, c_oil->oil.mfcc_parent,
- pim_channel_oil_dump (c_oil, buf, sizeof(buf)));
- }
- return -2;
- }
+ err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_DEL_MFC,
+ &c_oil->oil, sizeof(c_oil->oil));
+ if (err) {
+ if (PIM_DEBUG_MROUTE)
+ zlog_warn(
+ "%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_DEL_MFC): errno=%d: %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ qpim_mroute_socket_fd, errno,
+ safe_strerror(errno));
+ return -2;
+ }
- err = setsockopt(qpim_mroute_socket_fd, IPPROTO_IP, MRT_DEL_MFC, &c_oil->oil, sizeof(c_oil->oil));
- if (err) {
- if (PIM_DEBUG_MROUTE)
- zlog_warn("%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_DEL_MFC): errno=%d: %s",
- __FILE__, __PRETTY_FUNCTION__,
- qpim_mroute_socket_fd,
- errno, safe_strerror(errno));
- return -2;
- }
-
- if (PIM_DEBUG_MROUTE)
- {
- char buf[1000];
- zlog_debug("%s(%s), Deleted Route: %s",
- __PRETTY_FUNCTION__, name,
- pim_channel_oil_dump (c_oil, buf, sizeof(buf)));
- }
+ if (PIM_DEBUG_MROUTE) {
+ char buf[1000];
+ zlog_debug("%s(%s), Deleted Route: %s", __PRETTY_FUNCTION__,
+ name, pim_channel_oil_dump(c_oil, buf, sizeof(buf)));
+ }
- //Reset kernel installed flag
- c_oil->installed = 0;
+ // Reset kernel installed flag
+ c_oil->installed = 0;
- return 0;
+ return 0;
}
-void
-pim_mroute_update_counters (struct channel_oil *c_oil)
+void pim_mroute_update_counters(struct channel_oil *c_oil)
{
- struct sioc_sg_req sgreq;
-
- c_oil->cc.oldpktcnt = c_oil->cc.pktcnt;
- c_oil->cc.oldbytecnt = c_oil->cc.bytecnt;
- c_oil->cc.oldwrong_if = c_oil->cc.wrong_if;
-
- if (!c_oil->installed)
- {
- c_oil->cc.lastused = 100 * qpim_keep_alive_time;
- if (PIM_DEBUG_MROUTE)
- {
- struct prefix_sg sg;
-
- sg.src = c_oil->oil.mfcc_origin;
- sg.grp = c_oil->oil.mfcc_mcastgrp;
- if (PIM_DEBUG_MROUTE)
- zlog_debug("Channel(%s) is not installed no need to collect data from kernel",
- pim_str_sg_dump (&sg));
+ struct sioc_sg_req sgreq;
+
+ c_oil->cc.oldpktcnt = c_oil->cc.pktcnt;
+ c_oil->cc.oldbytecnt = c_oil->cc.bytecnt;
+ c_oil->cc.oldwrong_if = c_oil->cc.wrong_if;
+
+ if (!c_oil->installed) {
+ c_oil->cc.lastused = 100 * qpim_keep_alive_time;
+ if (PIM_DEBUG_MROUTE) {
+ struct prefix_sg sg;
+
+ sg.src = c_oil->oil.mfcc_origin;
+ sg.grp = c_oil->oil.mfcc_mcastgrp;
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug(
+ "Channel(%s) is not installed no need to collect data from kernel",
+ pim_str_sg_dump(&sg));
+ }
+ return;
}
- return;
- }
-
- memset (&sgreq, 0, sizeof(sgreq));
- sgreq.src = c_oil->oil.mfcc_origin;
- sgreq.grp = c_oil->oil.mfcc_mcastgrp;
-
- pim_zlookup_sg_statistics (c_oil);
- if (ioctl (qpim_mroute_socket_fd, SIOCGETSGCNT, &sgreq))
- {
- if (PIM_DEBUG_MROUTE)
- {
- struct prefix_sg sg;
- sg.src = c_oil->oil.mfcc_origin;
- sg.grp = c_oil->oil.mfcc_mcastgrp;
-
- zlog_warn ("ioctl(SIOCGETSGCNT=%lu) failure for (S,G)=(%s): errno=%d: %s",
- (unsigned long)SIOCGETSGCNT,
- pim_str_sg_dump (&sg),
- errno,
- safe_strerror(errno));
+ memset(&sgreq, 0, sizeof(sgreq));
+ sgreq.src = c_oil->oil.mfcc_origin;
+ sgreq.grp = c_oil->oil.mfcc_mcastgrp;
+
+ pim_zlookup_sg_statistics(c_oil);
+ if (ioctl(qpim_mroute_socket_fd, SIOCGETSGCNT, &sgreq)) {
+ if (PIM_DEBUG_MROUTE) {
+ struct prefix_sg sg;
+
+ sg.src = c_oil->oil.mfcc_origin;
+ sg.grp = c_oil->oil.mfcc_mcastgrp;
+
+ zlog_warn(
+ "ioctl(SIOCGETSGCNT=%lu) failure for (S,G)=(%s): errno=%d: %s",
+ (unsigned long)SIOCGETSGCNT,
+ pim_str_sg_dump(&sg), errno,
+ safe_strerror(errno));
+ }
+ return;
}
- return;
- }
- c_oil->cc.pktcnt = sgreq.pktcnt;
- c_oil->cc.bytecnt = sgreq.bytecnt;
- c_oil->cc.wrong_if = sgreq.wrong_if;
+ c_oil->cc.pktcnt = sgreq.pktcnt;
+ c_oil->cc.bytecnt = sgreq.bytecnt;
+ c_oil->cc.wrong_if = sgreq.wrong_if;
- return;
+ return;
}
diff --git a/pimd/pim_mroute.h b/pimd/pim_mroute.h
index 36dce8e61..eb6c40b67 100644
--- a/pimd/pim_mroute.h
+++ b/pimd/pim_mroute.h
@@ -73,25 +73,25 @@ typedef unsigned short vifi_t;
#ifndef HAVE_STRUCT_VIFCTL
struct vifctl {
- vifi_t vifc_vifi; /* Index of VIF */
- unsigned char vifc_flags; /* VIFF_ flags */
- unsigned char vifc_threshold; /* ttl limit */
- unsigned int vifc_rate_limit; /* Rate limiter values (NI) */
- struct in_addr vifc_lcl_addr; /* Our address */
- struct in_addr vifc_rmt_addr; /* IPIP tunnel addr */
+ vifi_t vifc_vifi; /* Index of VIF */
+ unsigned char vifc_flags; /* VIFF_ flags */
+ unsigned char vifc_threshold; /* ttl limit */
+ unsigned int vifc_rate_limit; /* Rate limiter values (NI) */
+ struct in_addr vifc_lcl_addr; /* Our address */
+ struct in_addr vifc_rmt_addr; /* IPIP tunnel addr */
};
#endif
#ifndef HAVE_STRUCT_MFCCTL
struct mfcctl {
- struct in_addr mfcc_origin; /* Origin of mcast */
- struct in_addr mfcc_mcastgrp; /* Group in question */
- vifi_t mfcc_parent; /* Where it arrived */
- unsigned char mfcc_ttls[MAXVIFS]; /* Where it is going */
- unsigned int mfcc_pkt_cnt; /* pkt count for src-grp */
- unsigned int mfcc_byte_cnt;
- unsigned int mfcc_wrong_if;
- int mfcc_expire;
+ struct in_addr mfcc_origin; /* Origin of mcast */
+ struct in_addr mfcc_mcastgrp; /* Group in question */
+ vifi_t mfcc_parent; /* Where it arrived */
+ unsigned char mfcc_ttls[MAXVIFS]; /* Where it is going */
+ unsigned int mfcc_pkt_cnt; /* pkt count for src-grp */
+ unsigned int mfcc_byte_cnt;
+ unsigned int mfcc_wrong_if;
+ int mfcc_expire;
};
#endif
@@ -107,11 +107,11 @@ struct mfcctl {
*/
#ifndef HAVE_STRUCT_SIOC_SG_REQ
struct sioc_sg_req {
- struct in_addr src;
- struct in_addr grp;
- unsigned long pktcnt;
- unsigned long bytecnt;
- unsigned long wrong_if;
+ struct in_addr src;
+ struct in_addr grp;
+ unsigned long pktcnt;
+ unsigned long bytecnt;
+ unsigned long wrong_if;
};
#endif
@@ -126,11 +126,11 @@ struct sioc_sg_req {
*/
#ifndef HAVE_STRUCT_SIOC_VIF_REQ
struct sioc_vif_req {
- vifi_t vifi; /* Which iface */
- unsigned long icount; /* In packets */
- unsigned long ocount; /* Out packets */
- unsigned long ibytes; /* In bytes */
- unsigned long obytes; /* Out bytes */
+ vifi_t vifi; /* Which iface */
+ unsigned long icount; /* In packets */
+ unsigned long ocount; /* Out packets */
+ unsigned long ibytes; /* In bytes */
+ unsigned long obytes; /* Out bytes */
};
#endif
@@ -144,14 +144,13 @@ struct sioc_vif_req {
#endif
#ifndef HAVE_STRUCT_IGMPMSG
-struct igmpmsg
-{
- uint32_t unused1,unused2;
- unsigned char im_msgtype; /* What is this */
- unsigned char im_mbz; /* Must be zero */
- unsigned char im_vif; /* Interface (this ought to be a vifi_t!) */
- unsigned char unused3;
- struct in_addr im_src,im_dst;
+struct igmpmsg {
+ uint32_t unused1, unused2;
+ unsigned char im_msgtype; /* What is this */
+ unsigned char im_mbz; /* Must be zero */
+ unsigned char im_vif; /* Interface (this ought to be a vifi_t!) */
+ unsigned char unused3;
+ struct in_addr im_src, im_dst;
};
#endif
#endif
@@ -167,7 +166,8 @@ struct igmpmsg
int pim_mroute_socket_enable(void);
int pim_mroute_socket_disable(void);
-int pim_mroute_add_vif(struct interface *ifp, struct in_addr ifaddr, unsigned char flags);
+int pim_mroute_add_vif(struct interface *ifp, struct in_addr ifaddr,
+ unsigned char flags);
int pim_mroute_del_vif(int vif_index);
int pim_mroute_add(struct channel_oil *c_oil, const char *name);
@@ -175,5 +175,5 @@ int pim_mroute_del(struct channel_oil *c_oil, const char *name);
int pim_mroute_msg(int fd, const char *buf, int buf_size);
-void pim_mroute_update_counters (struct channel_oil *c_oil);
+void pim_mroute_update_counters(struct channel_oil *c_oil);
#endif /* PIM_MROUTE_H */
diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c
index 170692e7f..0f653e70a 100644
--- a/pimd/pim_msdp.c
+++ b/pimd/pim_msdp.c
@@ -47,119 +47,119 @@ struct pim_msdp pim_msdp, *msdp = &pim_msdp;
static void pim_msdp_peer_listen(struct pim_msdp_peer *mp);
static void pim_msdp_peer_cr_timer_setup(struct pim_msdp_peer *mp, bool start);
static void pim_msdp_peer_ka_timer_setup(struct pim_msdp_peer *mp, bool start);
-static void pim_msdp_peer_hold_timer_setup(struct pim_msdp_peer *mp, bool start);
+static void pim_msdp_peer_hold_timer_setup(struct pim_msdp_peer *mp,
+ bool start);
static void pim_msdp_peer_free(struct pim_msdp_peer *mp);
static void pim_msdp_enable(void);
static void pim_msdp_sa_adv_timer_setup(bool start);
-static void pim_msdp_sa_deref(struct pim_msdp_sa *sa, enum pim_msdp_sa_flags flags);
+static void pim_msdp_sa_deref(struct pim_msdp_sa *sa,
+ enum pim_msdp_sa_flags flags);
static int pim_msdp_mg_mbr_comp(const void *p1, const void *p2);
static void pim_msdp_mg_mbr_free(struct pim_msdp_mg_mbr *mbr);
-static void pim_msdp_mg_mbr_do_del(struct pim_msdp_mg *mg, struct pim_msdp_mg_mbr *mbr);
+static void pim_msdp_mg_mbr_do_del(struct pim_msdp_mg *mg,
+ struct pim_msdp_mg_mbr *mbr);
/************************ SA cache management ******************************/
-static void
-pim_msdp_sa_timer_expiry_log(struct pim_msdp_sa *sa, const char *timer_str)
+static void pim_msdp_sa_timer_expiry_log(struct pim_msdp_sa *sa,
+ const char *timer_str)
{
- zlog_debug("MSDP SA %s %s timer expired", sa->sg_str, timer_str);
+ zlog_debug("MSDP SA %s %s timer expired", sa->sg_str, timer_str);
}
/* RFC-3618:Sec-5.1 - global active source advertisement timer */
-static int
-pim_msdp_sa_adv_timer_cb(struct thread *t)
+static int pim_msdp_sa_adv_timer_cb(struct thread *t)
{
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA advertisment timer expired");
- }
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP SA advertisment timer expired");
+ }
- pim_msdp_sa_adv_timer_setup(true /* start */);
- pim_msdp_pkt_sa_tx();
- return 0;
+ pim_msdp_sa_adv_timer_setup(true /* start */);
+ pim_msdp_pkt_sa_tx();
+ return 0;
}
-static void
-pim_msdp_sa_adv_timer_setup(bool start)
+static void pim_msdp_sa_adv_timer_setup(bool start)
{
- THREAD_OFF(msdp->sa_adv_timer);
- if (start) {
- thread_add_timer(msdp->master, pim_msdp_sa_adv_timer_cb, NULL,
- PIM_MSDP_SA_ADVERTISMENT_TIME, &msdp->sa_adv_timer);
- }
+ THREAD_OFF(msdp->sa_adv_timer);
+ if (start) {
+ thread_add_timer(msdp->master, pim_msdp_sa_adv_timer_cb, NULL,
+ PIM_MSDP_SA_ADVERTISMENT_TIME,
+ &msdp->sa_adv_timer);
+ }
}
/* RFC-3618:Sec-5.3 - SA cache state timer */
-static int
-pim_msdp_sa_state_timer_cb(struct thread *t)
+static int pim_msdp_sa_state_timer_cb(struct thread *t)
{
- struct pim_msdp_sa *sa;
+ struct pim_msdp_sa *sa;
- sa = THREAD_ARG(t);
+ sa = THREAD_ARG(t);
- if (PIM_DEBUG_MSDP_EVENTS) {
- pim_msdp_sa_timer_expiry_log(sa, "state");
- }
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ pim_msdp_sa_timer_expiry_log(sa, "state");
+ }
- pim_msdp_sa_deref(sa, PIM_MSDP_SAF_PEER);
- return 0;
+ pim_msdp_sa_deref(sa, PIM_MSDP_SAF_PEER);
+ return 0;
}
-static void
-pim_msdp_sa_state_timer_setup(struct pim_msdp_sa *sa, bool start)
+static void pim_msdp_sa_state_timer_setup(struct pim_msdp_sa *sa, bool start)
{
- THREAD_OFF(sa->sa_state_timer);
- if (start) {
- thread_add_timer(msdp->master, pim_msdp_sa_state_timer_cb, sa,
- PIM_MSDP_SA_HOLD_TIME, &sa->sa_state_timer);
- }
+ THREAD_OFF(sa->sa_state_timer);
+ if (start) {
+ thread_add_timer(msdp->master, pim_msdp_sa_state_timer_cb, sa,
+ PIM_MSDP_SA_HOLD_TIME, &sa->sa_state_timer);
+ }
}
-static void
-pim_msdp_sa_upstream_del(struct pim_msdp_sa *sa)
+static void pim_msdp_sa_upstream_del(struct pim_msdp_sa *sa)
{
- struct pim_upstream *up = sa->up;
- if (!up) {
- return;
- }
+ struct pim_upstream *up = sa->up;
+ if (!up) {
+ return;
+ }
- sa->up = NULL;
- if (PIM_UPSTREAM_FLAG_TEST_SRC_MSDP(up->flags)) {
- PIM_UPSTREAM_FLAG_UNSET_SRC_MSDP(up->flags);
- sa->flags |= PIM_MSDP_SAF_UP_DEL_IN_PROG;
- pim_upstream_del(up, __PRETTY_FUNCTION__);
- sa->flags &= ~PIM_MSDP_SAF_UP_DEL_IN_PROG;
- }
+ sa->up = NULL;
+ if (PIM_UPSTREAM_FLAG_TEST_SRC_MSDP(up->flags)) {
+ PIM_UPSTREAM_FLAG_UNSET_SRC_MSDP(up->flags);
+ sa->flags |= PIM_MSDP_SAF_UP_DEL_IN_PROG;
+ pim_upstream_del(up, __PRETTY_FUNCTION__);
+ sa->flags &= ~PIM_MSDP_SAF_UP_DEL_IN_PROG;
+ }
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA %s de-referenced SPT", sa->sg_str);
- }
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP SA %s de-referenced SPT", sa->sg_str);
+ }
}
-static bool
-pim_msdp_sa_upstream_add_ok(struct pim_msdp_sa *sa, struct pim_upstream *xg_up)
+static bool pim_msdp_sa_upstream_add_ok(struct pim_msdp_sa *sa,
+ struct pim_upstream *xg_up)
{
- if (!(sa->flags & PIM_MSDP_SAF_PEER)) {
- /* SA should have been rxed from a peer */
- return false;
- }
- /* check if we are RP */
- if (!I_am_RP(sa->sg.grp)) {
- return false;
- }
+ if (!(sa->flags & PIM_MSDP_SAF_PEER)) {
+ /* SA should have been rxed from a peer */
+ return false;
+ }
+ /* check if we are RP */
+ if (!I_am_RP(sa->sg.grp)) {
+ return false;
+ }
- /* check if we have a (*, G) with a non-empty immediate OIL */
- if (!xg_up) {
- struct prefix_sg sg;
+ /* check if we have a (*, G) with a non-empty immediate OIL */
+ if (!xg_up) {
+ struct prefix_sg sg;
- memset(&sg, 0, sizeof(sg));
- sg.grp = sa->sg.grp;
+ memset(&sg, 0, sizeof(sg));
+ sg.grp = sa->sg.grp;
- xg_up = pim_upstream_find(&sg);
- }
- if (!xg_up || (xg_up->join_state != PIM_UPSTREAM_JOINED)) {
- /* join desired will be true for such (*, G) entries so we will
- * just look at join_state and let the PIM state machine do the rest of
- * the magic */
- return false;
- }
+ xg_up = pim_upstream_find(&sg);
+ }
+ if (!xg_up || (xg_up->join_state != PIM_UPSTREAM_JOINED)) {
+ /* join desired will be true for such (*, G) entries so we will
+ * just look at join_state and let the PIM state machine do the
+ * rest of
+ * the magic */
+ return false;
+ }
- return true;
+ return true;
}
/* Upstream add evaluation needs to happen everytime -
@@ -170,164 +170,164 @@ pim_msdp_sa_upstream_add_ok(struct pim_msdp_sa *sa, struct pim_upstream *xg_up)
* (considering #4); but just in case an entry gets nuked without
* upstream state transition
* */
-static void
-pim_msdp_sa_upstream_update(struct pim_msdp_sa *sa,
- struct pim_upstream *xg_up, const char *ctx)
-{
- struct pim_upstream *up;
-
- if (!pim_msdp_sa_upstream_add_ok(sa, xg_up)) {
- pim_msdp_sa_upstream_del(sa);
- return;
- }
-
- if (sa->up) {
- /* nothing to do */
- return;
- }
-
- up = pim_upstream_find(&sa->sg);
- if (up && (PIM_UPSTREAM_FLAG_TEST_SRC_MSDP(up->flags))) {
- /* somehow we lost track of the upstream ptr? best log it */
- sa->up = up;
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA %s SPT reference missing", sa->sg_str);
- }
- return;
- }
-
- /* RFC3618: "RP triggers a (S, G) join event towards the data source
- * as if a JP message was rxed addressed to the RP itself." */
- up = pim_upstream_add(&sa->sg, NULL /* iif */,
- PIM_UPSTREAM_FLAG_MASK_SRC_MSDP,
- __PRETTY_FUNCTION__);
-
- sa->up = up;
- if (up) {
- /* update inherited oil */
- pim_upstream_inherited_olist(up);
- /* should we also start the kat in parallel? we will need it when the
- * SA ages out */
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA %s referenced SPT", sa->sg_str);
- }
- } else {
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA %s SPT reference failed", sa->sg_str);
- }
- }
+static void pim_msdp_sa_upstream_update(struct pim_msdp_sa *sa,
+ struct pim_upstream *xg_up,
+ const char *ctx)
+{
+ struct pim_upstream *up;
+
+ if (!pim_msdp_sa_upstream_add_ok(sa, xg_up)) {
+ pim_msdp_sa_upstream_del(sa);
+ return;
+ }
+
+ if (sa->up) {
+ /* nothing to do */
+ return;
+ }
+
+ up = pim_upstream_find(&sa->sg);
+ if (up && (PIM_UPSTREAM_FLAG_TEST_SRC_MSDP(up->flags))) {
+ /* somehow we lost track of the upstream ptr? best log it */
+ sa->up = up;
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP SA %s SPT reference missing",
+ sa->sg_str);
+ }
+ return;
+ }
+
+ /* RFC3618: "RP triggers a (S, G) join event towards the data source
+ * as if a JP message was rxed addressed to the RP itself." */
+ up = pim_upstream_add(&sa->sg, NULL /* iif */,
+ PIM_UPSTREAM_FLAG_MASK_SRC_MSDP,
+ __PRETTY_FUNCTION__);
+
+ sa->up = up;
+ if (up) {
+ /* update inherited oil */
+ pim_upstream_inherited_olist(up);
+ /* should we also start the kat in parallel? we will need it
+ * when the
+ * SA ages out */
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP SA %s referenced SPT", sa->sg_str);
+ }
+ } else {
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP SA %s SPT reference failed",
+ sa->sg_str);
+ }
+ }
}
/* release all mem associated with a sa */
-static void
-pim_msdp_sa_free(struct pim_msdp_sa *sa)
+static void pim_msdp_sa_free(struct pim_msdp_sa *sa)
{
- XFREE(MTYPE_PIM_MSDP_SA, sa);
+ XFREE(MTYPE_PIM_MSDP_SA, sa);
}
-static struct pim_msdp_sa *
-pim_msdp_sa_new(struct prefix_sg *sg, struct in_addr rp)
+static struct pim_msdp_sa *pim_msdp_sa_new(struct prefix_sg *sg,
+ struct in_addr rp)
{
- struct pim_msdp_sa *sa;
+ struct pim_msdp_sa *sa;
- sa = XCALLOC(MTYPE_PIM_MSDP_SA, sizeof(*sa));
- if (!sa) {
- zlog_err("%s: PIM XCALLOC(%zu) failure",
- __PRETTY_FUNCTION__, sizeof(*sa));
- return NULL;
- }
+ sa = XCALLOC(MTYPE_PIM_MSDP_SA, sizeof(*sa));
+ if (!sa) {
+ zlog_err("%s: PIM XCALLOC(%zu) failure", __PRETTY_FUNCTION__,
+ sizeof(*sa));
+ return NULL;
+ }
- sa->sg = *sg;
- pim_str_sg_set(sg, sa->sg_str);
- sa->rp = rp;
- sa->uptime = pim_time_monotonic_sec();
+ sa->sg = *sg;
+ pim_str_sg_set(sg, sa->sg_str);
+ sa->rp = rp;
+ sa->uptime = pim_time_monotonic_sec();
- /* insert into misc tables for easy access */
- sa = hash_get(msdp->sa_hash, sa, hash_alloc_intern);
- if (!sa) {
- zlog_err("%s: PIM hash get failure", __PRETTY_FUNCTION__);
- pim_msdp_sa_free(sa);
- return NULL;
- }
- listnode_add_sort(msdp->sa_list, sa);
+ /* insert into misc tables for easy access */
+ sa = hash_get(msdp->sa_hash, sa, hash_alloc_intern);
+ if (!sa) {
+ zlog_err("%s: PIM hash get failure", __PRETTY_FUNCTION__);
+ pim_msdp_sa_free(sa);
+ return NULL;
+ }
+ listnode_add_sort(msdp->sa_list, sa);
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA %s created", sa->sg_str);
- }
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP SA %s created", sa->sg_str);
+ }
- return sa;
+ return sa;
}
-static struct pim_msdp_sa *
-pim_msdp_sa_find(struct prefix_sg *sg)
+static struct pim_msdp_sa *pim_msdp_sa_find(struct prefix_sg *sg)
{
- struct pim_msdp_sa lookup;
+ struct pim_msdp_sa lookup;
- lookup.sg = *sg;
- return hash_lookup(msdp->sa_hash, &lookup);
+ lookup.sg = *sg;
+ return hash_lookup(msdp->sa_hash, &lookup);
}
-static struct pim_msdp_sa *
-pim_msdp_sa_add(struct prefix_sg *sg, struct in_addr rp)
+static struct pim_msdp_sa *pim_msdp_sa_add(struct prefix_sg *sg,
+ struct in_addr rp)
{
- struct pim_msdp_sa *sa;
+ struct pim_msdp_sa *sa;
- sa = pim_msdp_sa_find(sg);
- if (sa) {
- return sa;
- }
+ sa = pim_msdp_sa_find(sg);
+ if (sa) {
+ return sa;
+ }
- return pim_msdp_sa_new(sg, rp);
+ return pim_msdp_sa_new(sg, rp);
}
-static void
-pim_msdp_sa_del(struct pim_msdp_sa * sa)
+static void pim_msdp_sa_del(struct pim_msdp_sa *sa)
{
- /* this is somewhat redundant - still want to be careful not to leave
- * stale upstream references */
- pim_msdp_sa_upstream_del(sa);
+ /* this is somewhat redundant - still want to be careful not to leave
+ * stale upstream references */
+ pim_msdp_sa_upstream_del(sa);
- /* stop timers */
- pim_msdp_sa_state_timer_setup(sa, false /* start */);
+ /* stop timers */
+ pim_msdp_sa_state_timer_setup(sa, false /* start */);
- /* remove the entry from various tables */
- listnode_delete(msdp->sa_list, sa);
- hash_release(msdp->sa_hash, sa);
+ /* remove the entry from various tables */
+ listnode_delete(msdp->sa_list, sa);
+ hash_release(msdp->sa_hash, sa);
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA %s deleted", sa->sg_str);
- }
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP SA %s deleted", sa->sg_str);
+ }
- /* free up any associated memory */
- pim_msdp_sa_free(sa);
+ /* free up any associated memory */
+ pim_msdp_sa_free(sa);
}
-static void
-pim_msdp_sa_peer_ip_set(struct pim_msdp_sa *sa, struct pim_msdp_peer *mp, struct in_addr rp)
+static void pim_msdp_sa_peer_ip_set(struct pim_msdp_sa *sa,
+ struct pim_msdp_peer *mp, struct in_addr rp)
{
- struct pim_msdp_peer *old_mp;
+ struct pim_msdp_peer *old_mp;
- /* optimize the "no change" case as it will happen
- * frequently/periodically */
- if (mp && (sa->peer.s_addr == mp->peer.s_addr)) {
- return;
- }
+ /* optimize the "no change" case as it will happen
+ * frequently/periodically */
+ if (mp && (sa->peer.s_addr == mp->peer.s_addr)) {
+ return;
+ }
- /* any time the peer ip changes also update the rp address */
- if (PIM_INADDR_ISNOT_ANY(sa->peer)) {
- old_mp = pim_msdp_peer_find(sa->peer);
- if (old_mp && old_mp->sa_cnt) {
- --old_mp->sa_cnt;
- }
- }
+ /* any time the peer ip changes also update the rp address */
+ if (PIM_INADDR_ISNOT_ANY(sa->peer)) {
+ old_mp = pim_msdp_peer_find(sa->peer);
+ if (old_mp && old_mp->sa_cnt) {
+ --old_mp->sa_cnt;
+ }
+ }
- if (mp) {
- ++mp->sa_cnt;
- sa->peer = mp->peer;
- } else {
- sa->peer.s_addr = PIM_NET_INADDR_ANY;
- }
- sa->rp = rp;
+ if (mp) {
+ ++mp->sa_cnt;
+ sa->peer = mp->peer;
+ } else {
+ sa->peer.s_addr = PIM_NET_INADDR_ANY;
+ }
+ sa->rp = rp;
}
/* When a local active-source is removed there is no way to withdraw the
@@ -335,88 +335,93 @@ pim_msdp_sa_peer_ip_set(struct pim_msdp_sa *sa, struct pim_msdp_peer *mp, struct
* not be sent in supsequent SA updates. Peers will consequently timeout the
* SA.
* Similarly a "peer-added" SA is never explicitly deleted. It is simply
- * aged out overtime if not seen in the SA updates from the peers.
+ * aged out overtime if not seen in the SA updates from the peers.
* XXX: should we provide a knob to drop entries learnt from a peer when the
* peer goes down? */
-static void
-pim_msdp_sa_deref(struct pim_msdp_sa *sa, enum pim_msdp_sa_flags flags)
-{
- bool update_up = false;
-
- if ((sa->flags &PIM_MSDP_SAF_LOCAL)) {
- if (flags & PIM_MSDP_SAF_LOCAL) {
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA %s local reference removed", sa->sg_str);
- }
- if (msdp->local_cnt)
- --msdp->local_cnt;
- }
- }
-
- if ((sa->flags &PIM_MSDP_SAF_PEER)) {
- if (flags & PIM_MSDP_SAF_PEER) {
- struct in_addr rp;
-
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA %s peer reference removed", sa->sg_str);
- }
- pim_msdp_sa_state_timer_setup(sa, false /* start */);
- rp.s_addr = INADDR_ANY;
- pim_msdp_sa_peer_ip_set(sa, NULL /* mp */, rp);
- /* if peer ref was removed we need to remove the msdp reference on the
- * msdp entry */
- update_up = true;
- }
- }
-
- sa->flags &= ~flags;
- if (update_up) {
- pim_msdp_sa_upstream_update(sa, NULL /* xg_up */, "sa-deref");
- }
-
- if (!(sa->flags & PIM_MSDP_SAF_REF)) {
- pim_msdp_sa_del(sa);
- }
-}
-
-void
-pim_msdp_sa_ref(struct pim_msdp_peer *mp, struct prefix_sg *sg,
- struct in_addr rp)
-{
- struct pim_msdp_sa *sa;
-
- sa = pim_msdp_sa_add(sg, rp);
- if (!sa) {
- return;
- }
-
- /* reference it */
- if (mp) {
- if (!(sa->flags & PIM_MSDP_SAF_PEER)) {
- sa->flags |= PIM_MSDP_SAF_PEER;
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA %s added by peer", sa->sg_str);
- }
- }
- pim_msdp_sa_peer_ip_set(sa, mp, rp);
- /* start/re-start the state timer to prevent cache expiry */
- pim_msdp_sa_state_timer_setup(sa, true /* start */);
- /* We re-evaluate SA "SPT-trigger" everytime we hear abt it from a
- * peer. XXX: If this becomes too much of a periodic overhead we
- * can make it event based */
- pim_msdp_sa_upstream_update(sa, NULL /* xg_up */, "peer-ref");
- } else {
- if (!(sa->flags & PIM_MSDP_SAF_LOCAL)) {
- sa->flags |= PIM_MSDP_SAF_LOCAL;
- ++msdp->local_cnt;
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA %s added locally", sa->sg_str);
- }
- /* send an immediate SA update to peers */
- pim_msdp_pkt_sa_tx_one(sa);
- }
- sa->flags &= ~PIM_MSDP_SAF_STALE;
- }
+static void pim_msdp_sa_deref(struct pim_msdp_sa *sa,
+ enum pim_msdp_sa_flags flags)
+{
+ bool update_up = false;
+
+ if ((sa->flags & PIM_MSDP_SAF_LOCAL)) {
+ if (flags & PIM_MSDP_SAF_LOCAL) {
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP SA %s local reference removed",
+ sa->sg_str);
+ }
+ if (msdp->local_cnt)
+ --msdp->local_cnt;
+ }
+ }
+
+ if ((sa->flags & PIM_MSDP_SAF_PEER)) {
+ if (flags & PIM_MSDP_SAF_PEER) {
+ struct in_addr rp;
+
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP SA %s peer reference removed",
+ sa->sg_str);
+ }
+ pim_msdp_sa_state_timer_setup(sa, false /* start */);
+ rp.s_addr = INADDR_ANY;
+ pim_msdp_sa_peer_ip_set(sa, NULL /* mp */, rp);
+ /* if peer ref was removed we need to remove the msdp
+ * reference on the
+ * msdp entry */
+ update_up = true;
+ }
+ }
+
+ sa->flags &= ~flags;
+ if (update_up) {
+ pim_msdp_sa_upstream_update(sa, NULL /* xg_up */, "sa-deref");
+ }
+
+ if (!(sa->flags & PIM_MSDP_SAF_REF)) {
+ pim_msdp_sa_del(sa);
+ }
+}
+
+void pim_msdp_sa_ref(struct pim_msdp_peer *mp, struct prefix_sg *sg,
+ struct in_addr rp)
+{
+ struct pim_msdp_sa *sa;
+
+ sa = pim_msdp_sa_add(sg, rp);
+ if (!sa) {
+ return;
+ }
+
+ /* reference it */
+ if (mp) {
+ if (!(sa->flags & PIM_MSDP_SAF_PEER)) {
+ sa->flags |= PIM_MSDP_SAF_PEER;
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP SA %s added by peer",
+ sa->sg_str);
+ }
+ }
+ pim_msdp_sa_peer_ip_set(sa, mp, rp);
+ /* start/re-start the state timer to prevent cache expiry */
+ pim_msdp_sa_state_timer_setup(sa, true /* start */);
+ /* We re-evaluate SA "SPT-trigger" everytime we hear abt it from
+ * a
+ * peer. XXX: If this becomes too much of a periodic overhead we
+ * can make it event based */
+ pim_msdp_sa_upstream_update(sa, NULL /* xg_up */, "peer-ref");
+ } else {
+ if (!(sa->flags & PIM_MSDP_SAF_LOCAL)) {
+ sa->flags |= PIM_MSDP_SAF_LOCAL;
+ ++msdp->local_cnt;
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP SA %s added locally",
+ sa->sg_str);
+ }
+ /* send an immediate SA update to peers */
+ pim_msdp_pkt_sa_tx_one(sa);
+ }
+ sa->flags &= ~PIM_MSDP_SAF_STALE;
+ }
}
/* The following criteria must be met to originate an SA from the MSDP
@@ -431,93 +436,100 @@ pim_msdp_sa_ref(struct pim_msdp_peer *mp, struct prefix_sg *sg,
* b. We rxed a pim register (null or data encapsulated) within the last
* (3 * (1.5 * register_suppression_timer))).
*/
-static bool
-pim_msdp_sa_local_add_ok(struct pim_upstream *up)
+static bool pim_msdp_sa_local_add_ok(struct pim_upstream *up)
{
- if (!(msdp->flags & PIM_MSDPF_ENABLE)) {
- return false;
- }
+ if (!(msdp->flags & PIM_MSDPF_ENABLE)) {
+ return false;
+ }
- if (!up->t_ka_timer) {
- /* stream is not active */
- return false;
- }
+ if (!up->t_ka_timer) {
+ /* stream is not active */
+ return false;
+ }
- if (!I_am_RP(up->sg.grp)) {
- /* we are not RP for the group */
- return false;
- }
+ if (!I_am_RP(up->sg.grp)) {
+ /* we are not RP for the group */
+ return false;
+ }
- /* we are the FHR-DR for this stream or we are RP and have seen registers
- * from a FHR for this source */
- if (PIM_UPSTREAM_FLAG_TEST_FHR(up->flags) || up->t_msdp_reg_timer) {
- return true;
- }
+ /* we are the FHR-DR for this stream or we are RP and have seen
+ * registers
+ * from a FHR for this source */
+ if (PIM_UPSTREAM_FLAG_TEST_FHR(up->flags) || up->t_msdp_reg_timer) {
+ return true;
+ }
- return false;
+ return false;
}
-static void
-pim_msdp_sa_local_add(struct prefix_sg *sg)
+static void pim_msdp_sa_local_add(struct prefix_sg *sg)
{
- struct in_addr rp;
- rp.s_addr = 0;
- pim_msdp_sa_ref(NULL /* mp */, sg, rp);
+ struct in_addr rp;
+ rp.s_addr = 0;
+ pim_msdp_sa_ref(NULL /* mp */, sg, rp);
}
-void
-pim_msdp_sa_local_del(struct prefix_sg *sg)
+void pim_msdp_sa_local_del(struct prefix_sg *sg)
{
- struct pim_msdp_sa *sa;
+ struct pim_msdp_sa *sa;
- sa = pim_msdp_sa_find(sg);
- if (sa) {
- pim_msdp_sa_deref(sa, PIM_MSDP_SAF_LOCAL);
- }
+ sa = pim_msdp_sa_find(sg);
+ if (sa) {
+ pim_msdp_sa_deref(sa, PIM_MSDP_SAF_LOCAL);
+ }
}
/* we need to be very cautious with this API as SA del too can trigger an
* upstream del and we will get stuck in a simple loop */
-static void
-pim_msdp_sa_local_del_on_up_del(struct prefix_sg *sg)
-{
- struct pim_msdp_sa *sa;
-
- sa = pim_msdp_sa_find(sg);
- if (sa) {
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP local sa %s del on up del", sa->sg_str);
- }
-
- /* if there is no local reference escape */
- if (!(sa->flags & PIM_MSDP_SAF_LOCAL)) {
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP local sa %s del; no local ref", sa->sg_str);
- }
- return;
- }
-
- if (sa->flags & PIM_MSDP_SAF_UP_DEL_IN_PROG) {
- /* MSDP is the one that triggered the upstream del. if this happens
- * we most certainly have a bug in the PIM upstream state machine. We
- * will not have a local reference unless the KAT is running. And if the
- * KAT is running there MUST be an additional source-stream reference to
- * the flow. Accounting for such cases requires lot of changes; perhaps
- * address this in the next release? - XXX */
- zlog_err("MSDP sa %s SPT teardown is causing the local entry to be removed", sa->sg_str);
- return;
- }
-
- /* we are dropping the sa on upstream del we should not have an
- * upstream reference */
- if (sa->up) {
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP local sa %s del; up non-NULL", sa->sg_str);
- }
- sa->up = NULL;
- }
- pim_msdp_sa_deref(sa, PIM_MSDP_SAF_LOCAL);
- }
+static void pim_msdp_sa_local_del_on_up_del(struct prefix_sg *sg)
+{
+ struct pim_msdp_sa *sa;
+
+ sa = pim_msdp_sa_find(sg);
+ if (sa) {
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP local sa %s del on up del",
+ sa->sg_str);
+ }
+
+ /* if there is no local reference escape */
+ if (!(sa->flags & PIM_MSDP_SAF_LOCAL)) {
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP local sa %s del; no local ref",
+ sa->sg_str);
+ }
+ return;
+ }
+
+ if (sa->flags & PIM_MSDP_SAF_UP_DEL_IN_PROG) {
+ /* MSDP is the one that triggered the upstream del. if
+ * this happens
+ * we most certainly have a bug in the PIM upstream
+ * state machine. We
+ * will not have a local reference unless the KAT is
+ * running. And if the
+ * KAT is running there MUST be an additional
+ * source-stream reference to
+ * the flow. Accounting for such cases requires lot of
+ * changes; perhaps
+ * address this in the next release? - XXX */
+ zlog_err(
+ "MSDP sa %s SPT teardown is causing the local entry to be removed",
+ sa->sg_str);
+ return;
+ }
+
+ /* we are dropping the sa on upstream del we should not have an
+ * upstream reference */
+ if (sa->up) {
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP local sa %s del; up non-NULL",
+ sa->sg_str);
+ }
+ sa->up = NULL;
+ }
+ pim_msdp_sa_deref(sa, PIM_MSDP_SAF_LOCAL);
+ }
}
/* Local SA qualification needs to be re-evaluated when -
@@ -529,1072 +541,1045 @@ pim_msdp_sa_local_del_on_up_del(struct prefix_sg *sg)
* FHR is also the RP.
* 4. When msdp_reg timer is started or stopped
*/
-void
-pim_msdp_sa_local_update(struct pim_upstream *up)
+void pim_msdp_sa_local_update(struct pim_upstream *up)
{
- if (pim_msdp_sa_local_add_ok(up)) {
- pim_msdp_sa_local_add(&up->sg);
- } else {
- pim_msdp_sa_local_del(&up->sg);
- }
+ if (pim_msdp_sa_local_add_ok(up)) {
+ pim_msdp_sa_local_add(&up->sg);
+ } else {
+ pim_msdp_sa_local_del(&up->sg);
+ }
}
-static void
-pim_msdp_sa_local_setup(void)
+static void pim_msdp_sa_local_setup(void)
{
- struct pim_upstream *up;
- struct listnode *up_node;
+ struct pim_upstream *up;
+ struct listnode *up_node;
- for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, up_node, up)) {
- pim_msdp_sa_local_update(up);
- }
+ for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, up_node, up)) {
+ pim_msdp_sa_local_update(up);
+ }
}
/* whenever the RP changes we need to re-evaluate the "local" SA-cache */
/* XXX: needs to be tested */
-void
-pim_msdp_i_am_rp_changed(void)
-{
- struct listnode *sanode;
- struct listnode *nextnode;
- struct pim_msdp_sa *sa;
-
- if (!(msdp->flags & PIM_MSDPF_ENABLE)) {
- /* if the feature is not enabled do nothing */
- return;
- }
-
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP i_am_rp changed");
- }
-
- /* mark all local entries as stale */
- for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
- if (sa->flags & PIM_MSDP_SAF_LOCAL) {
- sa->flags |= PIM_MSDP_SAF_STALE;
- }
- }
-
- /* re-setup local SA entries */
- pim_msdp_sa_local_setup();
-
- for (ALL_LIST_ELEMENTS(msdp->sa_list, sanode, nextnode, sa)) {
- /* purge stale SA entries */
- if (sa->flags & PIM_MSDP_SAF_STALE) {
- /* clear the stale flag; the entry may be kept even after
- * "local-deref" */
- sa->flags &= ~PIM_MSDP_SAF_STALE;
- /* sa_deref can end up freeing the sa; so don't access contents after */
- pim_msdp_sa_deref(sa, PIM_MSDP_SAF_LOCAL);
- } else {
- /* if the souce is still active check if we can influence SPT */
- pim_msdp_sa_upstream_update(sa, NULL /* xg_up */, "rp-change");
- }
- }
+void pim_msdp_i_am_rp_changed(void)
+{
+ struct listnode *sanode;
+ struct listnode *nextnode;
+ struct pim_msdp_sa *sa;
+
+ if (!(msdp->flags & PIM_MSDPF_ENABLE)) {
+ /* if the feature is not enabled do nothing */
+ return;
+ }
+
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP i_am_rp changed");
+ }
+
+ /* mark all local entries as stale */
+ for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
+ if (sa->flags & PIM_MSDP_SAF_LOCAL) {
+ sa->flags |= PIM_MSDP_SAF_STALE;
+ }
+ }
+
+ /* re-setup local SA entries */
+ pim_msdp_sa_local_setup();
+
+ for (ALL_LIST_ELEMENTS(msdp->sa_list, sanode, nextnode, sa)) {
+ /* purge stale SA entries */
+ if (sa->flags & PIM_MSDP_SAF_STALE) {
+ /* clear the stale flag; the entry may be kept even
+ * after
+ * "local-deref" */
+ sa->flags &= ~PIM_MSDP_SAF_STALE;
+ /* sa_deref can end up freeing the sa; so don't access
+ * contents after */
+ pim_msdp_sa_deref(sa, PIM_MSDP_SAF_LOCAL);
+ } else {
+ /* if the souce is still active check if we can
+ * influence SPT */
+ pim_msdp_sa_upstream_update(sa, NULL /* xg_up */,
+ "rp-change");
+ }
+ }
}
/* We track the join state of (*, G) entries. If G has sources in the SA-cache
* we need to setup or teardown SPT when the JoinDesired status changes for
* (*, G) */
-void
-pim_msdp_up_join_state_changed(struct pim_upstream *xg_up)
-{
- struct listnode *sanode;
- struct pim_msdp_sa *sa;
-
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP join state changed for %s", xg_up->sg_str);
- }
-
- /* If this is not really an XG entry just move on */
- if ((xg_up->sg.src.s_addr != INADDR_ANY) ||
- (xg_up->sg.grp.s_addr == INADDR_ANY)) {
- return;
- }
-
- /* XXX: Need to maintain SAs per-group to avoid all this unnecessary
- * walking */
- for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
- if (sa->sg.grp.s_addr != xg_up->sg.grp.s_addr) {
- continue;
- }
- pim_msdp_sa_upstream_update(sa, xg_up, "up-jp-change");
- }
-}
-
-static void
-pim_msdp_up_xg_del(struct prefix_sg *sg)
-{
- struct listnode *sanode;
- struct pim_msdp_sa *sa;
-
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP %s del", pim_str_sg_dump(sg));
- }
-
- /* If this is not really an XG entry just move on */
- if ((sg->src.s_addr != INADDR_ANY) ||
- (sg->grp.s_addr == INADDR_ANY)) {
- return;
- }
-
- /* XXX: Need to maintain SAs per-group to avoid all this unnecessary
- * walking */
- for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
- if (sa->sg.grp.s_addr != sg->grp.s_addr) {
- continue;
- }
- pim_msdp_sa_upstream_update(sa, NULL /* xg */, "up-jp-change");
- }
-}
-
-void
-pim_msdp_up_del(struct prefix_sg *sg)
-{
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP up %s del", pim_str_sg_dump(sg));
- }
- if (sg->src.s_addr == INADDR_ANY) {
- pim_msdp_up_xg_del(sg);
- } else {
- pim_msdp_sa_local_del_on_up_del(sg);
- }
+void pim_msdp_up_join_state_changed(struct pim_upstream *xg_up)
+{
+ struct listnode *sanode;
+ struct pim_msdp_sa *sa;
+
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP join state changed for %s", xg_up->sg_str);
+ }
+
+ /* If this is not really an XG entry just move on */
+ if ((xg_up->sg.src.s_addr != INADDR_ANY)
+ || (xg_up->sg.grp.s_addr == INADDR_ANY)) {
+ return;
+ }
+
+ /* XXX: Need to maintain SAs per-group to avoid all this unnecessary
+ * walking */
+ for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
+ if (sa->sg.grp.s_addr != xg_up->sg.grp.s_addr) {
+ continue;
+ }
+ pim_msdp_sa_upstream_update(sa, xg_up, "up-jp-change");
+ }
+}
+
+static void pim_msdp_up_xg_del(struct prefix_sg *sg)
+{
+ struct listnode *sanode;
+ struct pim_msdp_sa *sa;
+
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP %s del", pim_str_sg_dump(sg));
+ }
+
+ /* If this is not really an XG entry just move on */
+ if ((sg->src.s_addr != INADDR_ANY) || (sg->grp.s_addr == INADDR_ANY)) {
+ return;
+ }
+
+ /* XXX: Need to maintain SAs per-group to avoid all this unnecessary
+ * walking */
+ for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
+ if (sa->sg.grp.s_addr != sg->grp.s_addr) {
+ continue;
+ }
+ pim_msdp_sa_upstream_update(sa, NULL /* xg */, "up-jp-change");
+ }
+}
+
+void pim_msdp_up_del(struct prefix_sg *sg)
+{
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP up %s del", pim_str_sg_dump(sg));
+ }
+ if (sg->src.s_addr == INADDR_ANY) {
+ pim_msdp_up_xg_del(sg);
+ } else {
+ pim_msdp_sa_local_del_on_up_del(sg);
+ }
}
/* sa hash and peer list helpers */
-static unsigned int
-pim_msdp_sa_hash_key_make(void *p)
+static unsigned int pim_msdp_sa_hash_key_make(void *p)
{
- struct pim_msdp_sa *sa = p;
+ struct pim_msdp_sa *sa = p;
- return (jhash_2words(sa->sg.src.s_addr, sa->sg.grp.s_addr, 0));
+ return (jhash_2words(sa->sg.src.s_addr, sa->sg.grp.s_addr, 0));
}
-static int
-pim_msdp_sa_hash_eq(const void *p1, const void *p2)
+static int pim_msdp_sa_hash_eq(const void *p1, const void *p2)
{
- const struct pim_msdp_sa *sa1 = p1;
- const struct pim_msdp_sa *sa2 = p2;
+ const struct pim_msdp_sa *sa1 = p1;
+ const struct pim_msdp_sa *sa2 = p2;
- return ((sa1->sg.src.s_addr == sa2->sg.src.s_addr) &&
- (sa1->sg.grp.s_addr == sa2->sg.grp.s_addr));
+ return ((sa1->sg.src.s_addr == sa2->sg.src.s_addr)
+ && (sa1->sg.grp.s_addr == sa2->sg.grp.s_addr));
}
-static int
-pim_msdp_sa_comp(const void *p1, const void *p2)
+static int pim_msdp_sa_comp(const void *p1, const void *p2)
{
- const struct pim_msdp_sa *sa1 = p1;
- const struct pim_msdp_sa *sa2 = p2;
+ const struct pim_msdp_sa *sa1 = p1;
+ const struct pim_msdp_sa *sa2 = p2;
- if (ntohl(sa1->sg.grp.s_addr) < ntohl(sa2->sg.grp.s_addr))
- return -1;
+ if (ntohl(sa1->sg.grp.s_addr) < ntohl(sa2->sg.grp.s_addr))
+ return -1;
- if (ntohl(sa1->sg.grp.s_addr) > ntohl(sa2->sg.grp.s_addr))
- return 1;
+ if (ntohl(sa1->sg.grp.s_addr) > ntohl(sa2->sg.grp.s_addr))
+ return 1;
- if (ntohl(sa1->sg.src.s_addr) < ntohl(sa2->sg.src.s_addr))
- return -1;
+ if (ntohl(sa1->sg.src.s_addr) < ntohl(sa2->sg.src.s_addr))
+ return -1;
- if (ntohl(sa1->sg.src.s_addr) > ntohl(sa2->sg.src.s_addr))
- return 1;
+ if (ntohl(sa1->sg.src.s_addr) > ntohl(sa2->sg.src.s_addr))
+ return 1;
- return 0;
+ return 0;
}
/* RFC-3618:Sec-10.1.3 - Peer-RPF forwarding */
/* XXX: this can use a bit of refining and extensions */
-bool
-pim_msdp_peer_rpf_check(struct pim_msdp_peer *mp, struct in_addr rp)
+bool pim_msdp_peer_rpf_check(struct pim_msdp_peer *mp, struct in_addr rp)
{
- if (mp->peer.s_addr == rp.s_addr) {
- return true;
- }
+ if (mp->peer.s_addr == rp.s_addr) {
+ return true;
+ }
- return false;
+ return false;
}
-
+
/************************ Peer session management **************************/
-char *
-pim_msdp_state_dump(enum pim_msdp_peer_state state, char *buf, int buf_size)
-{
- switch (state) {
- case PIM_MSDP_DISABLED:
- snprintf(buf, buf_size, "%s", "disabled");
- break;
- case PIM_MSDP_INACTIVE:
- snprintf(buf, buf_size, "%s", "inactive");
- break;
- case PIM_MSDP_LISTEN:
- snprintf(buf, buf_size, "%s", "listen");
- break;
- case PIM_MSDP_CONNECTING:
- snprintf(buf, buf_size, "%s", "connecting");
- break;
- case PIM_MSDP_ESTABLISHED:
- snprintf(buf, buf_size, "%s", "established");
- break;
- default:
- snprintf(buf, buf_size, "unk-%d", state);
- }
- return buf;
-}
-
-char *
-pim_msdp_peer_key_dump(struct pim_msdp_peer *mp, char *buf, int buf_size, bool long_format)
-{
- char peer_str[INET_ADDRSTRLEN];
- char local_str[INET_ADDRSTRLEN];
-
- pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
- if (long_format) {
- pim_inet4_dump("<local?>", mp->local, local_str, sizeof(local_str));
- snprintf(buf, buf_size, "MSDP peer %s local %s mg %s",
- peer_str, local_str, mp->mesh_group_name);
- } else {
- snprintf(buf, buf_size, "MSDP peer %s", peer_str);
- }
-
- return buf;
-}
-
-static void
-pim_msdp_peer_state_chg_log(struct pim_msdp_peer *mp)
-{
- char state_str[PIM_MSDP_STATE_STRLEN];
-
- pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
- zlog_debug("MSDP peer %s state chg to %s", mp->key_str, state_str);
+char *pim_msdp_state_dump(enum pim_msdp_peer_state state, char *buf,
+ int buf_size)
+{
+ switch (state) {
+ case PIM_MSDP_DISABLED:
+ snprintf(buf, buf_size, "%s", "disabled");
+ break;
+ case PIM_MSDP_INACTIVE:
+ snprintf(buf, buf_size, "%s", "inactive");
+ break;
+ case PIM_MSDP_LISTEN:
+ snprintf(buf, buf_size, "%s", "listen");
+ break;
+ case PIM_MSDP_CONNECTING:
+ snprintf(buf, buf_size, "%s", "connecting");
+ break;
+ case PIM_MSDP_ESTABLISHED:
+ snprintf(buf, buf_size, "%s", "established");
+ break;
+ default:
+ snprintf(buf, buf_size, "unk-%d", state);
+ }
+ return buf;
+}
+
+char *pim_msdp_peer_key_dump(struct pim_msdp_peer *mp, char *buf, int buf_size,
+ bool long_format)
+{
+ char peer_str[INET_ADDRSTRLEN];
+ char local_str[INET_ADDRSTRLEN];
+
+ pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
+ if (long_format) {
+ pim_inet4_dump("<local?>", mp->local, local_str,
+ sizeof(local_str));
+ snprintf(buf, buf_size, "MSDP peer %s local %s mg %s", peer_str,
+ local_str, mp->mesh_group_name);
+ } else {
+ snprintf(buf, buf_size, "MSDP peer %s", peer_str);
+ }
+
+ return buf;
+}
+
+static void pim_msdp_peer_state_chg_log(struct pim_msdp_peer *mp)
+{
+ char state_str[PIM_MSDP_STATE_STRLEN];
+
+ pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
+ zlog_debug("MSDP peer %s state chg to %s", mp->key_str, state_str);
}
/* MSDP Connection State Machine actions (defined in RFC-3618:Sec-11.2) */
/* 11.2.A2: active peer - start connect retry timer; when the timer fires
* a tcp connection will be made */
-static void
-pim_msdp_peer_connect(struct pim_msdp_peer *mp)
+static void pim_msdp_peer_connect(struct pim_msdp_peer *mp)
{
- mp->state = PIM_MSDP_CONNECTING;
- if (PIM_DEBUG_MSDP_EVENTS) {
- pim_msdp_peer_state_chg_log(mp);
- }
+ mp->state = PIM_MSDP_CONNECTING;
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ pim_msdp_peer_state_chg_log(mp);
+ }
- pim_msdp_peer_cr_timer_setup(mp, true /* start */);
+ pim_msdp_peer_cr_timer_setup(mp, true /* start */);
}
/* 11.2.A3: passive peer - just listen for connections */
-static void
-pim_msdp_peer_listen(struct pim_msdp_peer *mp)
+static void pim_msdp_peer_listen(struct pim_msdp_peer *mp)
{
- mp->state = PIM_MSDP_LISTEN;
- if (PIM_DEBUG_MSDP_EVENTS) {
- pim_msdp_peer_state_chg_log(mp);
- }
+ mp->state = PIM_MSDP_LISTEN;
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ pim_msdp_peer_state_chg_log(mp);
+ }
- /* this is interntionally asymmetric i.e. we set up listen-socket when the
- * first listening peer is configured; but don't bother tearing it down when
- * all the peers go down */
- pim_msdp_sock_listen();
+ /* this is interntionally asymmetric i.e. we set up listen-socket when
+ * the
+ * first listening peer is configured; but don't bother tearing it down
+ * when
+ * all the peers go down */
+ pim_msdp_sock_listen();
}
/* 11.2.A4 and 11.2.A5: transition active or passive peer to
* established state */
-void
-pim_msdp_peer_established(struct pim_msdp_peer *mp)
+void pim_msdp_peer_established(struct pim_msdp_peer *mp)
{
- if (mp->state != PIM_MSDP_ESTABLISHED) {
- ++mp->est_flaps;
- }
+ if (mp->state != PIM_MSDP_ESTABLISHED) {
+ ++mp->est_flaps;
+ }
- mp->state = PIM_MSDP_ESTABLISHED;
- mp->uptime = pim_time_monotonic_sec();
+ mp->state = PIM_MSDP_ESTABLISHED;
+ mp->uptime = pim_time_monotonic_sec();
- if (PIM_DEBUG_MSDP_EVENTS) {
- pim_msdp_peer_state_chg_log(mp);
- }
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ pim_msdp_peer_state_chg_log(mp);
+ }
- /* stop retry timer on active peers */
- pim_msdp_peer_cr_timer_setup(mp, false /* start */);
+ /* stop retry timer on active peers */
+ pim_msdp_peer_cr_timer_setup(mp, false /* start */);
- /* send KA; start KA and hold timers */
- pim_msdp_pkt_ka_tx(mp);
- pim_msdp_peer_ka_timer_setup(mp, true /* start */);
- pim_msdp_peer_hold_timer_setup(mp, true /* start */);
+ /* send KA; start KA and hold timers */
+ pim_msdp_pkt_ka_tx(mp);
+ pim_msdp_peer_ka_timer_setup(mp, true /* start */);
+ pim_msdp_peer_hold_timer_setup(mp, true /* start */);
- pim_msdp_pkt_sa_tx_to_one_peer(mp);
+ pim_msdp_pkt_sa_tx_to_one_peer(mp);
- PIM_MSDP_PEER_WRITE_ON(mp);
- PIM_MSDP_PEER_READ_ON(mp);
+ PIM_MSDP_PEER_WRITE_ON(mp);
+ PIM_MSDP_PEER_READ_ON(mp);
}
/* 11.2.A6, 11.2.A7 and 11.2.A8: shutdown the peer tcp connection */
-void
-pim_msdp_peer_stop_tcp_conn(struct pim_msdp_peer *mp, bool chg_state)
-{
- if (chg_state) {
- if (mp->state == PIM_MSDP_ESTABLISHED) {
- ++mp->est_flaps;
- }
- mp->state = PIM_MSDP_INACTIVE;
- if (PIM_DEBUG_MSDP_EVENTS) {
- pim_msdp_peer_state_chg_log(mp);
- }
- }
-
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP peer %s pim_msdp_peer_stop_tcp_conn", mp->key_str);
- }
- /* stop read and write threads */
- PIM_MSDP_PEER_READ_OFF(mp);
- PIM_MSDP_PEER_WRITE_OFF(mp);
-
- /* reset buffers */
- mp->packet_size = 0;
- if (mp->ibuf)
- stream_reset(mp->ibuf);
- if (mp->obuf)
- stream_fifo_clean(mp->obuf);
-
- /* stop all peer timers */
- pim_msdp_peer_ka_timer_setup(mp, false /* start */);
- pim_msdp_peer_cr_timer_setup(mp, false /* start */);
- pim_msdp_peer_hold_timer_setup(mp, false /* start */);
-
- /* close connection */
- if (mp->fd >= 0) {
- close(mp->fd);
- mp->fd = -1;
- }
+void pim_msdp_peer_stop_tcp_conn(struct pim_msdp_peer *mp, bool chg_state)
+{
+ if (chg_state) {
+ if (mp->state == PIM_MSDP_ESTABLISHED) {
+ ++mp->est_flaps;
+ }
+ mp->state = PIM_MSDP_INACTIVE;
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ pim_msdp_peer_state_chg_log(mp);
+ }
+ }
+
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s pim_msdp_peer_stop_tcp_conn",
+ mp->key_str);
+ }
+ /* stop read and write threads */
+ PIM_MSDP_PEER_READ_OFF(mp);
+ PIM_MSDP_PEER_WRITE_OFF(mp);
+
+ /* reset buffers */
+ mp->packet_size = 0;
+ if (mp->ibuf)
+ stream_reset(mp->ibuf);
+ if (mp->obuf)
+ stream_fifo_clean(mp->obuf);
+
+ /* stop all peer timers */
+ pim_msdp_peer_ka_timer_setup(mp, false /* start */);
+ pim_msdp_peer_cr_timer_setup(mp, false /* start */);
+ pim_msdp_peer_hold_timer_setup(mp, false /* start */);
+
+ /* close connection */
+ if (mp->fd >= 0) {
+ close(mp->fd);
+ mp->fd = -1;
+ }
}
/* RFC-3618:Sec-5.6 - stop the peer tcp connection and startover */
-void
-pim_msdp_peer_reset_tcp_conn(struct pim_msdp_peer *mp, const char *rc_str)
+void pim_msdp_peer_reset_tcp_conn(struct pim_msdp_peer *mp, const char *rc_str)
{
- if (PIM_DEBUG_EVENTS) {
- zlog_debug("MSDP peer %s tcp reset %s", mp->key_str, rc_str);
- snprintf(mp->last_reset, sizeof(mp->last_reset), "%s", rc_str);
- }
+ if (PIM_DEBUG_EVENTS) {
+ zlog_debug("MSDP peer %s tcp reset %s", mp->key_str, rc_str);
+ snprintf(mp->last_reset, sizeof(mp->last_reset), "%s", rc_str);
+ }
- /* close the connection and transition to listening or connecting */
- pim_msdp_peer_stop_tcp_conn(mp, true /* chg_state */);
- if (PIM_MSDP_PEER_IS_LISTENER(mp)) {
- pim_msdp_peer_listen(mp);
- } else {
- pim_msdp_peer_connect(mp);
- }
+ /* close the connection and transition to listening or connecting */
+ pim_msdp_peer_stop_tcp_conn(mp, true /* chg_state */);
+ if (PIM_MSDP_PEER_IS_LISTENER(mp)) {
+ pim_msdp_peer_listen(mp);
+ } else {
+ pim_msdp_peer_connect(mp);
+ }
}
-static void
-pim_msdp_peer_timer_expiry_log(struct pim_msdp_peer *mp, const char *timer_str)
+static void pim_msdp_peer_timer_expiry_log(struct pim_msdp_peer *mp,
+ const char *timer_str)
{
- zlog_debug("MSDP peer %s %s timer expired", mp->key_str, timer_str);
+ zlog_debug("MSDP peer %s %s timer expired", mp->key_str, timer_str);
}
/* RFC-3618:Sec-5.4 - peer hold timer */
-static int
-pim_msdp_peer_hold_timer_cb(struct thread *t)
+static int pim_msdp_peer_hold_timer_cb(struct thread *t)
{
- struct pim_msdp_peer *mp;
+ struct pim_msdp_peer *mp;
- mp = THREAD_ARG(t);
+ mp = THREAD_ARG(t);
- if (PIM_DEBUG_MSDP_EVENTS) {
- pim_msdp_peer_timer_expiry_log(mp, "hold");
- }
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ pim_msdp_peer_timer_expiry_log(mp, "hold");
+ }
- if (mp->state != PIM_MSDP_ESTABLISHED) {
- return 0;
- }
+ if (mp->state != PIM_MSDP_ESTABLISHED) {
+ return 0;
+ }
- if (PIM_DEBUG_MSDP_EVENTS) {
- pim_msdp_peer_state_chg_log(mp);
- }
- pim_msdp_peer_reset_tcp_conn(mp, "ht-expired");
- return 0;
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ pim_msdp_peer_state_chg_log(mp);
+ }
+ pim_msdp_peer_reset_tcp_conn(mp, "ht-expired");
+ return 0;
}
-static void
-pim_msdp_peer_hold_timer_setup(struct pim_msdp_peer *mp, bool start)
+static void pim_msdp_peer_hold_timer_setup(struct pim_msdp_peer *mp, bool start)
{
- THREAD_OFF(mp->hold_timer);
- if (start) {
- thread_add_timer(msdp->master, pim_msdp_peer_hold_timer_cb, mp,
- PIM_MSDP_PEER_HOLD_TIME, &mp->hold_timer);
- }
+ THREAD_OFF(mp->hold_timer);
+ if (start) {
+ thread_add_timer(msdp->master, pim_msdp_peer_hold_timer_cb, mp,
+ PIM_MSDP_PEER_HOLD_TIME, &mp->hold_timer);
+ }
}
/* RFC-3618:Sec-5.5 - peer keepalive timer */
-static int
-pim_msdp_peer_ka_timer_cb(struct thread *t)
+static int pim_msdp_peer_ka_timer_cb(struct thread *t)
{
- struct pim_msdp_peer *mp;
+ struct pim_msdp_peer *mp;
- mp = THREAD_ARG(t);
+ mp = THREAD_ARG(t);
- if (PIM_DEBUG_MSDP_EVENTS) {
- pim_msdp_peer_timer_expiry_log(mp, "ka");
- }
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ pim_msdp_peer_timer_expiry_log(mp, "ka");
+ }
- pim_msdp_pkt_ka_tx(mp);
- pim_msdp_peer_ka_timer_setup(mp, true /* start */);
- return 0;
+ pim_msdp_pkt_ka_tx(mp);
+ pim_msdp_peer_ka_timer_setup(mp, true /* start */);
+ return 0;
}
-static void
-pim_msdp_peer_ka_timer_setup(struct pim_msdp_peer *mp, bool start)
+static void pim_msdp_peer_ka_timer_setup(struct pim_msdp_peer *mp, bool start)
{
- THREAD_OFF(mp->ka_timer);
- if (start) {
- thread_add_timer(msdp->master, pim_msdp_peer_ka_timer_cb, mp,
- PIM_MSDP_PEER_KA_TIME, &mp->ka_timer);
- }
+ THREAD_OFF(mp->ka_timer);
+ if (start) {
+ thread_add_timer(msdp->master, pim_msdp_peer_ka_timer_cb, mp,
+ PIM_MSDP_PEER_KA_TIME, &mp->ka_timer);
+ }
}
-static void
-pim_msdp_peer_active_connect(struct pim_msdp_peer *mp)
+static void pim_msdp_peer_active_connect(struct pim_msdp_peer *mp)
{
- int rc;
- ++mp->conn_attempts;
- rc = pim_msdp_sock_connect(mp);
+ int rc;
+ ++mp->conn_attempts;
+ rc = pim_msdp_sock_connect(mp);
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP peer %s pim_msdp_peer_active_connect: %d", mp->key_str, rc);
- }
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s pim_msdp_peer_active_connect: %d",
+ mp->key_str, rc);
+ }
- switch (rc) {
- case connect_error:
- case -1:
- /* connect failed restart the connect-retry timer */
- pim_msdp_peer_cr_timer_setup(mp, true /* start */);
- break;
+ switch (rc) {
+ case connect_error:
+ case -1:
+ /* connect failed restart the connect-retry timer */
+ pim_msdp_peer_cr_timer_setup(mp, true /* start */);
+ break;
- case connect_success:
- /* connect was sucessful move to established */
- pim_msdp_peer_established(mp);
- break;
+ case connect_success:
+ /* connect was sucessful move to established */
+ pim_msdp_peer_established(mp);
+ break;
- case connect_in_progress:
- /* for NB content we need to wait till sock is readable or
- * writeable */
- PIM_MSDP_PEER_WRITE_ON(mp);
- PIM_MSDP_PEER_READ_ON(mp);
- /* also restart connect-retry timer to reset the socket if connect is
- * not sucessful */
- pim_msdp_peer_cr_timer_setup(mp, true /* start */);
- break;
- }
+ case connect_in_progress:
+ /* for NB content we need to wait till sock is readable or
+ * writeable */
+ PIM_MSDP_PEER_WRITE_ON(mp);
+ PIM_MSDP_PEER_READ_ON(mp);
+ /* also restart connect-retry timer to reset the socket if
+ * connect is
+ * not sucessful */
+ pim_msdp_peer_cr_timer_setup(mp, true /* start */);
+ break;
+ }
}
/* RFC-3618:Sec-5.6 - connection retry on active peer */
-static int
-pim_msdp_peer_cr_timer_cb(struct thread *t)
+static int pim_msdp_peer_cr_timer_cb(struct thread *t)
{
- struct pim_msdp_peer *mp;
+ struct pim_msdp_peer *mp;
- mp = THREAD_ARG(t);
+ mp = THREAD_ARG(t);
- if (PIM_DEBUG_MSDP_EVENTS) {
- pim_msdp_peer_timer_expiry_log(mp, "connect-retry");
- }
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ pim_msdp_peer_timer_expiry_log(mp, "connect-retry");
+ }
- if (mp->state != PIM_MSDP_CONNECTING || PIM_MSDP_PEER_IS_LISTENER(mp)) {
- return 0;
- }
+ if (mp->state != PIM_MSDP_CONNECTING || PIM_MSDP_PEER_IS_LISTENER(mp)) {
+ return 0;
+ }
- pim_msdp_peer_active_connect(mp);
- return 0;
+ pim_msdp_peer_active_connect(mp);
+ return 0;
}
-static void
-pim_msdp_peer_cr_timer_setup(struct pim_msdp_peer *mp, bool start)
+static void pim_msdp_peer_cr_timer_setup(struct pim_msdp_peer *mp, bool start)
{
- THREAD_OFF(mp->cr_timer);
- if (start) {
- thread_add_timer(msdp->master, pim_msdp_peer_cr_timer_cb, mp,
- PIM_MSDP_PEER_CONNECT_RETRY_TIME, &mp->cr_timer);
- }
+ THREAD_OFF(mp->cr_timer);
+ if (start) {
+ thread_add_timer(msdp->master, pim_msdp_peer_cr_timer_cb, mp,
+ PIM_MSDP_PEER_CONNECT_RETRY_TIME,
+ &mp->cr_timer);
+ }
}
/* if a valid packet is rxed from the peer we can restart hold timer */
-void
-pim_msdp_peer_pkt_rxed(struct pim_msdp_peer *mp)
+void pim_msdp_peer_pkt_rxed(struct pim_msdp_peer *mp)
{
- if (mp->state == PIM_MSDP_ESTABLISHED) {
- pim_msdp_peer_hold_timer_setup(mp, true /* start */);
- }
+ if (mp->state == PIM_MSDP_ESTABLISHED) {
+ pim_msdp_peer_hold_timer_setup(mp, true /* start */);
+ }
}
/* if a valid packet is txed to the peer we can restart ka timer and avoid
* unnecessary ka noise in the network */
-void
-pim_msdp_peer_pkt_txed(struct pim_msdp_peer *mp)
+void pim_msdp_peer_pkt_txed(struct pim_msdp_peer *mp)
{
- if (mp->state == PIM_MSDP_ESTABLISHED) {
- pim_msdp_peer_ka_timer_setup(mp, true /* start */);
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP ka timer restart on pkt tx to %s", mp->key_str);
- }
- }
+ if (mp->state == PIM_MSDP_ESTABLISHED) {
+ pim_msdp_peer_ka_timer_setup(mp, true /* start */);
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP ka timer restart on pkt tx to %s",
+ mp->key_str);
+ }
+ }
}
static void pim_msdp_addr2su(union sockunion *su, struct in_addr addr)
{
- sockunion_init(su);
- su->sin.sin_addr = addr;
- su->sin.sin_family = AF_INET;
+ sockunion_init(su);
+ su->sin.sin_addr = addr;
+ su->sin.sin_family = AF_INET;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
- su->sin.sin_len = sizeof(struct sockaddr_in);
+ su->sin.sin_len = sizeof(struct sockaddr_in);
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
}
/* 11.2.A1: create a new peer and transition state to listen or connecting */
-static enum pim_msdp_err
-pim_msdp_peer_new(struct in_addr peer_addr, struct in_addr local_addr,
- const char *mesh_group_name, struct pim_msdp_peer **mp_p)
-{
- struct pim_msdp_peer *mp;
-
- pim_msdp_enable();
-
- mp = XCALLOC(MTYPE_PIM_MSDP_PEER, sizeof(*mp));
- if (!mp) {
- zlog_err("%s: PIM XCALLOC(%zu) failure",
- __PRETTY_FUNCTION__, sizeof(*mp));
- return PIM_MSDP_ERR_OOM;
- }
-
- mp->peer = peer_addr;
- pim_inet4_dump("<peer?>", mp->peer, mp->key_str, sizeof(mp->key_str));
- pim_msdp_addr2su(&mp->su_peer, mp->peer);
- mp->local = local_addr;
- /* XXX: originator_id setting needs to move to the mesh group */
- msdp->originator_id = local_addr;
- pim_msdp_addr2su(&mp->su_local, mp->local);
- mp->mesh_group_name = XSTRDUP(MTYPE_PIM_MSDP_MG_NAME, mesh_group_name);
- mp->state = PIM_MSDP_INACTIVE;
- mp->fd = -1;
- strcpy(mp->last_reset, "-");
- /* higher IP address is listener */
- if (ntohl(mp->local.s_addr) > ntohl(mp->peer.s_addr)) {
- mp->flags |= PIM_MSDP_PEERF_LISTENER;
- }
-
- /* setup packet buffers */
- mp->ibuf = stream_new(PIM_MSDP_MAX_PACKET_SIZE);
- mp->obuf = stream_fifo_new();
-
- /* insert into misc tables for easy access */
- mp = hash_get(msdp->peer_hash, mp, hash_alloc_intern);
- listnode_add_sort(msdp->peer_list, mp);
-
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP peer %s created", mp->key_str);
-
- pim_msdp_peer_state_chg_log(mp);
- }
-
- /* fireup the connect state machine */
- if (PIM_MSDP_PEER_IS_LISTENER(mp)) {
- pim_msdp_peer_listen(mp);
- } else {
- pim_msdp_peer_connect(mp);
- }
- if (mp_p) {
- *mp_p = mp;
- }
- return PIM_MSDP_ERR_NONE;
-}
-
-struct pim_msdp_peer *
-pim_msdp_peer_find(struct in_addr peer_addr)
-{
- struct pim_msdp_peer lookup;
-
- lookup.peer = peer_addr;
- return hash_lookup(msdp->peer_hash, &lookup);
+static enum pim_msdp_err pim_msdp_peer_new(struct in_addr peer_addr,
+ struct in_addr local_addr,
+ const char *mesh_group_name,
+ struct pim_msdp_peer **mp_p)
+{
+ struct pim_msdp_peer *mp;
+
+ pim_msdp_enable();
+
+ mp = XCALLOC(MTYPE_PIM_MSDP_PEER, sizeof(*mp));
+ if (!mp) {
+ zlog_err("%s: PIM XCALLOC(%zu) failure", __PRETTY_FUNCTION__,
+ sizeof(*mp));
+ return PIM_MSDP_ERR_OOM;
+ }
+
+ mp->peer = peer_addr;
+ pim_inet4_dump("<peer?>", mp->peer, mp->key_str, sizeof(mp->key_str));
+ pim_msdp_addr2su(&mp->su_peer, mp->peer);
+ mp->local = local_addr;
+ /* XXX: originator_id setting needs to move to the mesh group */
+ msdp->originator_id = local_addr;
+ pim_msdp_addr2su(&mp->su_local, mp->local);
+ mp->mesh_group_name = XSTRDUP(MTYPE_PIM_MSDP_MG_NAME, mesh_group_name);
+ mp->state = PIM_MSDP_INACTIVE;
+ mp->fd = -1;
+ strcpy(mp->last_reset, "-");
+ /* higher IP address is listener */
+ if (ntohl(mp->local.s_addr) > ntohl(mp->peer.s_addr)) {
+ mp->flags |= PIM_MSDP_PEERF_LISTENER;
+ }
+
+ /* setup packet buffers */
+ mp->ibuf = stream_new(PIM_MSDP_MAX_PACKET_SIZE);
+ mp->obuf = stream_fifo_new();
+
+ /* insert into misc tables for easy access */
+ mp = hash_get(msdp->peer_hash, mp, hash_alloc_intern);
+ listnode_add_sort(msdp->peer_list, mp);
+
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP peer %s created", mp->key_str);
+
+ pim_msdp_peer_state_chg_log(mp);
+ }
+
+ /* fireup the connect state machine */
+ if (PIM_MSDP_PEER_IS_LISTENER(mp)) {
+ pim_msdp_peer_listen(mp);
+ } else {
+ pim_msdp_peer_connect(mp);
+ }
+ if (mp_p) {
+ *mp_p = mp;
+ }
+ return PIM_MSDP_ERR_NONE;
+}
+
+struct pim_msdp_peer *pim_msdp_peer_find(struct in_addr peer_addr)
+{
+ struct pim_msdp_peer lookup;
+
+ lookup.peer = peer_addr;
+ return hash_lookup(msdp->peer_hash, &lookup);
}
/* add peer configuration if it doesn't already exist */
-enum pim_msdp_err
-pim_msdp_peer_add(struct in_addr peer_addr, struct in_addr local_addr,
- const char *mesh_group_name, struct pim_msdp_peer **mp_p)
+enum pim_msdp_err pim_msdp_peer_add(struct in_addr peer_addr,
+ struct in_addr local_addr,
+ const char *mesh_group_name,
+ struct pim_msdp_peer **mp_p)
{
- struct pim_msdp_peer *mp;
+ struct pim_msdp_peer *mp;
- if (mp_p) {
- *mp_p = NULL;
- }
+ if (mp_p) {
+ *mp_p = NULL;
+ }
- if (peer_addr.s_addr == local_addr.s_addr) {
- /* skip session setup if config is invalid */
- if (PIM_DEBUG_MSDP_EVENTS) {
- char peer_str[INET_ADDRSTRLEN];
+ if (peer_addr.s_addr == local_addr.s_addr) {
+ /* skip session setup if config is invalid */
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ char peer_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<peer?>", peer_addr, peer_str, sizeof(peer_str));
- zlog_debug("%s add skipped as DIP=SIP", peer_str);
- }
- return PIM_MSDP_ERR_SIP_EQ_DIP;
- }
+ pim_inet4_dump("<peer?>", peer_addr, peer_str,
+ sizeof(peer_str));
+ zlog_debug("%s add skipped as DIP=SIP", peer_str);
+ }
+ return PIM_MSDP_ERR_SIP_EQ_DIP;
+ }
- mp = pim_msdp_peer_find(peer_addr);
- if (mp) {
- if (mp_p) {
- *mp_p = mp;
- }
- return PIM_MSDP_ERR_PEER_EXISTS;
- }
+ mp = pim_msdp_peer_find(peer_addr);
+ if (mp) {
+ if (mp_p) {
+ *mp_p = mp;
+ }
+ return PIM_MSDP_ERR_PEER_EXISTS;
+ }
- return pim_msdp_peer_new(peer_addr, local_addr, mesh_group_name, mp_p);
+ return pim_msdp_peer_new(peer_addr, local_addr, mesh_group_name, mp_p);
}
/* release all mem associated with a peer */
-static void
-pim_msdp_peer_free(struct pim_msdp_peer *mp)
+static void pim_msdp_peer_free(struct pim_msdp_peer *mp)
{
- if (mp->ibuf) {
- stream_free(mp->ibuf);
- }
+ if (mp->ibuf) {
+ stream_free(mp->ibuf);
+ }
- if (mp->obuf) {
- stream_fifo_free(mp->obuf);
- }
+ if (mp->obuf) {
+ stream_fifo_free(mp->obuf);
+ }
- if (mp->mesh_group_name) {
- XFREE(MTYPE_PIM_MSDP_MG_NAME, mp->mesh_group_name);
- }
- XFREE(MTYPE_PIM_MSDP_PEER, mp);
+ if (mp->mesh_group_name) {
+ XFREE(MTYPE_PIM_MSDP_MG_NAME, mp->mesh_group_name);
+ }
+ XFREE(MTYPE_PIM_MSDP_PEER, mp);
}
/* delete the peer config */
-static enum pim_msdp_err
-pim_msdp_peer_do_del(struct pim_msdp_peer *mp)
+static enum pim_msdp_err pim_msdp_peer_do_del(struct pim_msdp_peer *mp)
{
- /* stop the tcp connection and shutdown all timers */
- pim_msdp_peer_stop_tcp_conn(mp, true /* chg_state */);
+ /* stop the tcp connection and shutdown all timers */
+ pim_msdp_peer_stop_tcp_conn(mp, true /* chg_state */);
- /* remove the session from various tables */
- listnode_delete(msdp->peer_list, mp);
- hash_release(msdp->peer_hash, mp);
+ /* remove the session from various tables */
+ listnode_delete(msdp->peer_list, mp);
+ hash_release(msdp->peer_hash, mp);
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP peer %s deleted", mp->key_str);
- }
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP peer %s deleted", mp->key_str);
+ }
- /* free up any associated memory */
- pim_msdp_peer_free(mp);
+ /* free up any associated memory */
+ pim_msdp_peer_free(mp);
- return PIM_MSDP_ERR_NONE;
+ return PIM_MSDP_ERR_NONE;
}
-enum pim_msdp_err
-pim_msdp_peer_del(struct in_addr peer_addr)
+enum pim_msdp_err pim_msdp_peer_del(struct in_addr peer_addr)
{
- struct pim_msdp_peer *mp;
+ struct pim_msdp_peer *mp;
- mp = pim_msdp_peer_find(peer_addr);
- if (!mp) {
- return PIM_MSDP_ERR_NO_PEER;
- }
+ mp = pim_msdp_peer_find(peer_addr);
+ if (!mp) {
+ return PIM_MSDP_ERR_NO_PEER;
+ }
- return pim_msdp_peer_do_del(mp);
+ return pim_msdp_peer_do_del(mp);
}
/* peer hash and peer list helpers */
-static unsigned int
-pim_msdp_peer_hash_key_make(void *p)
+static unsigned int pim_msdp_peer_hash_key_make(void *p)
{
- struct pim_msdp_peer *mp = p;
- return (jhash_1word(mp->peer.s_addr, 0));
+ struct pim_msdp_peer *mp = p;
+ return (jhash_1word(mp->peer.s_addr, 0));
}
-static int
-pim_msdp_peer_hash_eq(const void *p1, const void *p2)
+static int pim_msdp_peer_hash_eq(const void *p1, const void *p2)
{
- const struct pim_msdp_peer *mp1 = p1;
- const struct pim_msdp_peer *mp2 = p2;
+ const struct pim_msdp_peer *mp1 = p1;
+ const struct pim_msdp_peer *mp2 = p2;
- return (mp1->peer.s_addr == mp2->peer.s_addr);
+ return (mp1->peer.s_addr == mp2->peer.s_addr);
}
-static int
-pim_msdp_peer_comp(const void *p1, const void *p2)
+static int pim_msdp_peer_comp(const void *p1, const void *p2)
{
- const struct pim_msdp_peer *mp1 = p1;
- const struct pim_msdp_peer *mp2 = p2;
+ const struct pim_msdp_peer *mp1 = p1;
+ const struct pim_msdp_peer *mp2 = p2;
- if (ntohl(mp1->peer.s_addr) < ntohl(mp2->peer.s_addr))
- return -1;
+ if (ntohl(mp1->peer.s_addr) < ntohl(mp2->peer.s_addr))
+ return -1;
- if (ntohl(mp1->peer.s_addr) > ntohl(mp2->peer.s_addr))
- return 1;
+ if (ntohl(mp1->peer.s_addr) > ntohl(mp2->peer.s_addr))
+ return 1;
- return 0;
+ return 0;
}
/************************** Mesh group management **************************/
-static void
-pim_msdp_mg_free(struct pim_msdp_mg *mg)
+static void pim_msdp_mg_free(struct pim_msdp_mg *mg)
{
- /* If the mesh-group has valid member or src_ip don't delete it */
- if (!mg || mg->mbr_cnt || (mg->src_ip.s_addr != INADDR_ANY)) {
- return;
- }
+ /* If the mesh-group has valid member or src_ip don't delete it */
+ if (!mg || mg->mbr_cnt || (mg->src_ip.s_addr != INADDR_ANY)) {
+ return;
+ }
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP mesh-group %s deleted", mg->mesh_group_name);
- }
- if (mg->mesh_group_name)
- XFREE(MTYPE_PIM_MSDP_MG_NAME, mg->mesh_group_name);
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP mesh-group %s deleted", mg->mesh_group_name);
+ }
+ if (mg->mesh_group_name)
+ XFREE(MTYPE_PIM_MSDP_MG_NAME, mg->mesh_group_name);
- if (mg->mbr_list)
- list_free(mg->mbr_list);
+ if (mg->mbr_list)
+ list_free(mg->mbr_list);
- XFREE(MTYPE_PIM_MSDP_MG, mg);
- msdp->mg = NULL;
+ XFREE(MTYPE_PIM_MSDP_MG, mg);
+ msdp->mg = NULL;
}
-static struct pim_msdp_mg *
-pim_msdp_mg_new(const char *mesh_group_name)
+static struct pim_msdp_mg *pim_msdp_mg_new(const char *mesh_group_name)
{
- struct pim_msdp_mg *mg;
+ struct pim_msdp_mg *mg;
- mg = XCALLOC(MTYPE_PIM_MSDP_MG, sizeof(*mg));
- if (!mg) {
- zlog_err("%s: PIM XCALLOC(%zu) failure",
- __PRETTY_FUNCTION__, sizeof(*mg));
- return NULL;
- }
+ mg = XCALLOC(MTYPE_PIM_MSDP_MG, sizeof(*mg));
+ if (!mg) {
+ zlog_err("%s: PIM XCALLOC(%zu) failure", __PRETTY_FUNCTION__,
+ sizeof(*mg));
+ return NULL;
+ }
- mg->mesh_group_name = XSTRDUP(MTYPE_PIM_MSDP_MG_NAME, mesh_group_name);
- mg->mbr_list = list_new();
- mg->mbr_list->del = (void (*)(void *))pim_msdp_mg_mbr_free;
- mg->mbr_list->cmp = (int (*)(void *, void *))pim_msdp_mg_mbr_comp;
+ mg->mesh_group_name = XSTRDUP(MTYPE_PIM_MSDP_MG_NAME, mesh_group_name);
+ mg->mbr_list = list_new();
+ mg->mbr_list->del = (void (*)(void *))pim_msdp_mg_mbr_free;
+ mg->mbr_list->cmp = (int (*)(void *, void *))pim_msdp_mg_mbr_comp;
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP mesh-group %s created", mg->mesh_group_name);
- }
- return mg;
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP mesh-group %s created", mg->mesh_group_name);
+ }
+ return mg;
}
-enum pim_msdp_err
-pim_msdp_mg_del(const char *mesh_group_name)
+enum pim_msdp_err pim_msdp_mg_del(const char *mesh_group_name)
{
- struct pim_msdp_mg *mg = msdp->mg;
- struct pim_msdp_mg_mbr *mbr;
+ struct pim_msdp_mg *mg = msdp->mg;
+ struct pim_msdp_mg_mbr *mbr;
- if (!mg || strcmp(mg->mesh_group_name, mesh_group_name)) {
- return PIM_MSDP_ERR_NO_MG;
- }
+ if (!mg || strcmp(mg->mesh_group_name, mesh_group_name)) {
+ return PIM_MSDP_ERR_NO_MG;
+ }
- /* delete all the mesh-group members */
- while (!list_isempty(mg->mbr_list)) {
- mbr = listnode_head(mg->mbr_list);
- pim_msdp_mg_mbr_do_del(mg, mbr);
- }
+ /* delete all the mesh-group members */
+ while (!list_isempty(mg->mbr_list)) {
+ mbr = listnode_head(mg->mbr_list);
+ pim_msdp_mg_mbr_do_del(mg, mbr);
+ }
- /* clear src ip */
- mg->src_ip.s_addr = INADDR_ANY;
+ /* clear src ip */
+ mg->src_ip.s_addr = INADDR_ANY;
- /* free up the mesh-group */
- pim_msdp_mg_free(mg);
- return PIM_MSDP_ERR_NONE;
+ /* free up the mesh-group */
+ pim_msdp_mg_free(mg);
+ return PIM_MSDP_ERR_NONE;
}
-static enum pim_msdp_err
-pim_msdp_mg_add(const char *mesh_group_name)
+static enum pim_msdp_err pim_msdp_mg_add(const char *mesh_group_name)
{
- if (msdp->mg) {
- if (!strcmp(msdp->mg->mesh_group_name, mesh_group_name)) {
- return PIM_MSDP_ERR_NONE;
- }
- /* currently only one mesh-group can exist at a time */
- return PIM_MSDP_ERR_MAX_MESH_GROUPS;
- }
+ if (msdp->mg) {
+ if (!strcmp(msdp->mg->mesh_group_name, mesh_group_name)) {
+ return PIM_MSDP_ERR_NONE;
+ }
+ /* currently only one mesh-group can exist at a time */
+ return PIM_MSDP_ERR_MAX_MESH_GROUPS;
+ }
- msdp->mg = pim_msdp_mg_new(mesh_group_name);
- if (!msdp->mg) {
- return PIM_MSDP_ERR_OOM;
- }
+ msdp->mg = pim_msdp_mg_new(mesh_group_name);
+ if (!msdp->mg) {
+ return PIM_MSDP_ERR_OOM;
+ }
- return PIM_MSDP_ERR_NONE;
+ return PIM_MSDP_ERR_NONE;
}
-static int
-pim_msdp_mg_mbr_comp(const void *p1, const void *p2)
+static int pim_msdp_mg_mbr_comp(const void *p1, const void *p2)
{
- const struct pim_msdp_mg_mbr *mbr1 = p1;
- const struct pim_msdp_mg_mbr *mbr2 = p2;
+ const struct pim_msdp_mg_mbr *mbr1 = p1;
+ const struct pim_msdp_mg_mbr *mbr2 = p2;
- if (ntohl(mbr1->mbr_ip.s_addr) < ntohl(mbr2->mbr_ip.s_addr))
- return -1;
+ if (ntohl(mbr1->mbr_ip.s_addr) < ntohl(mbr2->mbr_ip.s_addr))
+ return -1;
- if (ntohl(mbr1->mbr_ip.s_addr) > ntohl(mbr2->mbr_ip.s_addr))
- return 1;
+ if (ntohl(mbr1->mbr_ip.s_addr) > ntohl(mbr2->mbr_ip.s_addr))
+ return 1;
- return 0;
+ return 0;
}
-static void
-pim_msdp_mg_mbr_free(struct pim_msdp_mg_mbr *mbr)
+static void pim_msdp_mg_mbr_free(struct pim_msdp_mg_mbr *mbr)
{
- XFREE(MTYPE_PIM_MSDP_MG_MBR, mbr);
+ XFREE(MTYPE_PIM_MSDP_MG_MBR, mbr);
}
-static struct pim_msdp_mg_mbr *
-pim_msdp_mg_mbr_find(struct in_addr mbr_ip)
+static struct pim_msdp_mg_mbr *pim_msdp_mg_mbr_find(struct in_addr mbr_ip)
{
- struct pim_msdp_mg_mbr *mbr;
- struct listnode *mbr_node;
+ struct pim_msdp_mg_mbr *mbr;
+ struct listnode *mbr_node;
- if (!msdp->mg) {
- return NULL;
- }
- /* we can move this to a hash but considering that number of peers in
- * a mesh-group that seems like bit of an overkill */
- for (ALL_LIST_ELEMENTS_RO(msdp->mg->mbr_list, mbr_node, mbr)) {
- if (mbr->mbr_ip.s_addr == mbr_ip.s_addr) {
- return mbr;
- }
- }
- return mbr;
+ if (!msdp->mg) {
+ return NULL;
+ }
+ /* we can move this to a hash but considering that number of peers in
+ * a mesh-group that seems like bit of an overkill */
+ for (ALL_LIST_ELEMENTS_RO(msdp->mg->mbr_list, mbr_node, mbr)) {
+ if (mbr->mbr_ip.s_addr == mbr_ip.s_addr) {
+ return mbr;
+ }
+ }
+ return mbr;
}
-enum pim_msdp_err
-pim_msdp_mg_mbr_add(const char *mesh_group_name, struct in_addr mbr_ip)
+enum pim_msdp_err pim_msdp_mg_mbr_add(const char *mesh_group_name,
+ struct in_addr mbr_ip)
{
- int rc;
- struct pim_msdp_mg_mbr *mbr;
- struct pim_msdp_mg *mg;
+ int rc;
+ struct pim_msdp_mg_mbr *mbr;
+ struct pim_msdp_mg *mg;
- rc = pim_msdp_mg_add(mesh_group_name);
- if (rc != PIM_MSDP_ERR_NONE) {
- return rc;
- }
+ rc = pim_msdp_mg_add(mesh_group_name);
+ if (rc != PIM_MSDP_ERR_NONE) {
+ return rc;
+ }
- mg = msdp->mg;
- mbr = pim_msdp_mg_mbr_find(mbr_ip);
- if (mbr) {
- return PIM_MSDP_ERR_MG_MBR_EXISTS;
- }
+ mg = msdp->mg;
+ mbr = pim_msdp_mg_mbr_find(mbr_ip);
+ if (mbr) {
+ return PIM_MSDP_ERR_MG_MBR_EXISTS;
+ }
- mbr = XCALLOC(MTYPE_PIM_MSDP_MG_MBR, sizeof(*mbr));
- if (!mbr) {
- zlog_err("%s: PIM XCALLOC(%zu) failure",
- __PRETTY_FUNCTION__, sizeof(*mbr));
- /* if there are no references to the mg free it */
- pim_msdp_mg_free(mg);
- return PIM_MSDP_ERR_OOM;
- }
- mbr->mbr_ip = mbr_ip;
- listnode_add_sort(mg->mbr_list, mbr);
+ mbr = XCALLOC(MTYPE_PIM_MSDP_MG_MBR, sizeof(*mbr));
+ if (!mbr) {
+ zlog_err("%s: PIM XCALLOC(%zu) failure", __PRETTY_FUNCTION__,
+ sizeof(*mbr));
+ /* if there are no references to the mg free it */
+ pim_msdp_mg_free(mg);
+ return PIM_MSDP_ERR_OOM;
+ }
+ mbr->mbr_ip = mbr_ip;
+ listnode_add_sort(mg->mbr_list, mbr);
- /* if valid SIP has been configured add peer session */
- if (mg->src_ip.s_addr != INADDR_ANY) {
- pim_msdp_peer_add(mbr_ip, mg->src_ip, mesh_group_name,
- &mbr->mp);
- }
+ /* if valid SIP has been configured add peer session */
+ if (mg->src_ip.s_addr != INADDR_ANY) {
+ pim_msdp_peer_add(mbr_ip, mg->src_ip, mesh_group_name,
+ &mbr->mp);
+ }
- if (PIM_DEBUG_MSDP_EVENTS) {
- char ip_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<mbr?>", mbr->mbr_ip, ip_str, sizeof(ip_str));
- zlog_debug("MSDP mesh-group %s mbr %s created", mg->mesh_group_name, ip_str);
- }
- ++mg->mbr_cnt;
- return PIM_MSDP_ERR_NONE;
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ char ip_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<mbr?>", mbr->mbr_ip, ip_str, sizeof(ip_str));
+ zlog_debug("MSDP mesh-group %s mbr %s created",
+ mg->mesh_group_name, ip_str);
+ }
+ ++mg->mbr_cnt;
+ return PIM_MSDP_ERR_NONE;
}
-static void
-pim_msdp_mg_mbr_do_del(struct pim_msdp_mg *mg, struct pim_msdp_mg_mbr *mbr)
+static void pim_msdp_mg_mbr_do_del(struct pim_msdp_mg *mg,
+ struct pim_msdp_mg_mbr *mbr)
{
- /* Delete active peer session if any */
- if (mbr->mp) {
- pim_msdp_peer_do_del(mbr->mp);
- }
+ /* Delete active peer session if any */
+ if (mbr->mp) {
+ pim_msdp_peer_do_del(mbr->mp);
+ }
- listnode_delete(mg->mbr_list, mbr);
- if (PIM_DEBUG_MSDP_EVENTS) {
- char ip_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<mbr?>", mbr->mbr_ip, ip_str, sizeof(ip_str));
- zlog_debug("MSDP mesh-group %s mbr %s deleted", mg->mesh_group_name, ip_str);
- }
- pim_msdp_mg_mbr_free(mbr);
- if (mg->mbr_cnt) {
- --mg->mbr_cnt;
- }
+ listnode_delete(mg->mbr_list, mbr);
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ char ip_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<mbr?>", mbr->mbr_ip, ip_str, sizeof(ip_str));
+ zlog_debug("MSDP mesh-group %s mbr %s deleted",
+ mg->mesh_group_name, ip_str);
+ }
+ pim_msdp_mg_mbr_free(mbr);
+ if (mg->mbr_cnt) {
+ --mg->mbr_cnt;
+ }
}
-enum pim_msdp_err
-pim_msdp_mg_mbr_del(const char *mesh_group_name, struct in_addr mbr_ip)
-{
- struct pim_msdp_mg_mbr *mbr;
- struct pim_msdp_mg *mg = msdp->mg;
-
- if (!mg || strcmp(mg->mesh_group_name, mesh_group_name)) {
- return PIM_MSDP_ERR_NO_MG;
- }
-
- mbr = pim_msdp_mg_mbr_find(mbr_ip);
- if (!mbr) {
- return PIM_MSDP_ERR_NO_MG_MBR;
- }
-
- pim_msdp_mg_mbr_do_del(mg, mbr);
- /* if there are no references to the mg free it */
- pim_msdp_mg_free(mg);
-
- return PIM_MSDP_ERR_NONE;
-}
-
-static void
-pim_msdp_mg_src_do_del(void)
-{
- struct pim_msdp_mg_mbr *mbr;
- struct listnode *mbr_node;
- struct pim_msdp_mg *mg = msdp->mg;
-
- /* SIP is being removed - tear down all active peer sessions */
- for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbr_node, mbr)) {
- if (mbr->mp) {
- pim_msdp_peer_do_del(mbr->mp);
- mbr->mp = NULL;
- }
- }
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP mesh-group %s src cleared", mg->mesh_group_name);
- }
-}
-
-enum pim_msdp_err
-pim_msdp_mg_src_del(const char *mesh_group_name)
-{
- struct pim_msdp_mg *mg = msdp->mg;
-
- if (!mg || strcmp(mg->mesh_group_name, mesh_group_name)) {
- return PIM_MSDP_ERR_NO_MG;
- }
-
- if (mg->src_ip.s_addr != INADDR_ANY) {
- mg->src_ip.s_addr = INADDR_ANY;
- pim_msdp_mg_src_do_del();
- /* if there are no references to the mg free it */
- pim_msdp_mg_free(mg);
- }
- return PIM_MSDP_ERR_NONE;
-}
-
-enum pim_msdp_err
-pim_msdp_mg_src_add(const char *mesh_group_name, struct in_addr src_ip)
-{
- int rc;
- struct pim_msdp_mg_mbr *mbr;
- struct listnode *mbr_node;
- struct pim_msdp_mg *mg;
-
- if (src_ip.s_addr == INADDR_ANY) {
- pim_msdp_mg_src_del(mesh_group_name);
- return PIM_MSDP_ERR_NONE;
- }
-
- rc = pim_msdp_mg_add(mesh_group_name);
- if (rc != PIM_MSDP_ERR_NONE) {
- return rc;
- }
-
- mg = msdp->mg;
- if (mg->src_ip.s_addr != INADDR_ANY) {
- pim_msdp_mg_src_do_del();
- }
- mg->src_ip = src_ip;
+enum pim_msdp_err pim_msdp_mg_mbr_del(const char *mesh_group_name,
+ struct in_addr mbr_ip)
+{
+ struct pim_msdp_mg_mbr *mbr;
+ struct pim_msdp_mg *mg = msdp->mg;
+
+ if (!mg || strcmp(mg->mesh_group_name, mesh_group_name)) {
+ return PIM_MSDP_ERR_NO_MG;
+ }
+
+ mbr = pim_msdp_mg_mbr_find(mbr_ip);
+ if (!mbr) {
+ return PIM_MSDP_ERR_NO_MG_MBR;
+ }
+
+ pim_msdp_mg_mbr_do_del(mg, mbr);
+ /* if there are no references to the mg free it */
+ pim_msdp_mg_free(mg);
+
+ return PIM_MSDP_ERR_NONE;
+}
+
+static void pim_msdp_mg_src_do_del(void)
+{
+ struct pim_msdp_mg_mbr *mbr;
+ struct listnode *mbr_node;
+ struct pim_msdp_mg *mg = msdp->mg;
+
+ /* SIP is being removed - tear down all active peer sessions */
+ for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbr_node, mbr)) {
+ if (mbr->mp) {
+ pim_msdp_peer_do_del(mbr->mp);
+ mbr->mp = NULL;
+ }
+ }
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_debug("MSDP mesh-group %s src cleared",
+ mg->mesh_group_name);
+ }
+}
+
+enum pim_msdp_err pim_msdp_mg_src_del(const char *mesh_group_name)
+{
+ struct pim_msdp_mg *mg = msdp->mg;
+
+ if (!mg || strcmp(mg->mesh_group_name, mesh_group_name)) {
+ return PIM_MSDP_ERR_NO_MG;
+ }
+
+ if (mg->src_ip.s_addr != INADDR_ANY) {
+ mg->src_ip.s_addr = INADDR_ANY;
+ pim_msdp_mg_src_do_del();
+ /* if there are no references to the mg free it */
+ pim_msdp_mg_free(mg);
+ }
+ return PIM_MSDP_ERR_NONE;
+}
+
+enum pim_msdp_err pim_msdp_mg_src_add(const char *mesh_group_name,
+ struct in_addr src_ip)
+{
+ int rc;
+ struct pim_msdp_mg_mbr *mbr;
+ struct listnode *mbr_node;
+ struct pim_msdp_mg *mg;
+
+ if (src_ip.s_addr == INADDR_ANY) {
+ pim_msdp_mg_src_del(mesh_group_name);
+ return PIM_MSDP_ERR_NONE;
+ }
+
+ rc = pim_msdp_mg_add(mesh_group_name);
+ if (rc != PIM_MSDP_ERR_NONE) {
+ return rc;
+ }
+
+ mg = msdp->mg;
+ if (mg->src_ip.s_addr != INADDR_ANY) {
+ pim_msdp_mg_src_do_del();
+ }
+ mg->src_ip = src_ip;
- for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbr_node, mbr)) {
- pim_msdp_peer_add(mbr->mbr_ip, mg->src_ip, mesh_group_name,
- &mbr->mp);
- }
+ for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbr_node, mbr)) {
+ pim_msdp_peer_add(mbr->mbr_ip, mg->src_ip, mesh_group_name,
+ &mbr->mp);
+ }
- if (PIM_DEBUG_MSDP_EVENTS) {
- char ip_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", mg->src_ip, ip_str, sizeof(ip_str));
- zlog_debug("MSDP mesh-group %s src %s set", mg->mesh_group_name, ip_str);
- }
- return PIM_MSDP_ERR_NONE;
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ char ip_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", mg->src_ip, ip_str, sizeof(ip_str));
+ zlog_debug("MSDP mesh-group %s src %s set", mg->mesh_group_name,
+ ip_str);
+ }
+ return PIM_MSDP_ERR_NONE;
}
/*********************** MSDP feature APIs *********************************/
-int
-pim_msdp_config_write(struct vty *vty)
-{
- struct listnode *mbrnode;
- struct pim_msdp_mg_mbr *mbr;
- struct pim_msdp_mg *mg = msdp->mg;
- char mbr_str[INET_ADDRSTRLEN];
- char src_str[INET_ADDRSTRLEN];
- int count = 0;
-
- if (!mg) {
- return count;
- }
-
- if (mg->src_ip.s_addr != INADDR_ANY) {
- pim_inet4_dump("<src?>", mg->src_ip, src_str, sizeof(src_str));
- vty_out (vty, "ip msdp mesh-group %s source %s\n",
- mg->mesh_group_name, src_str);
- ++count;
- }
-
- for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
- pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str, sizeof(mbr_str));
- vty_out (vty, "ip msdp mesh-group %s member %s\n",
- mg->mesh_group_name, mbr_str);
- ++count;
- }
- return count;
+int pim_msdp_config_write(struct vty *vty)
+{
+ struct listnode *mbrnode;
+ struct pim_msdp_mg_mbr *mbr;
+ struct pim_msdp_mg *mg = msdp->mg;
+ char mbr_str[INET_ADDRSTRLEN];
+ char src_str[INET_ADDRSTRLEN];
+ int count = 0;
+
+ if (!mg) {
+ return count;
+ }
+
+ if (mg->src_ip.s_addr != INADDR_ANY) {
+ pim_inet4_dump("<src?>", mg->src_ip, src_str, sizeof(src_str));
+ vty_out(vty, "ip msdp mesh-group %s source %s\n",
+ mg->mesh_group_name, src_str);
+ ++count;
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
+ pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str, sizeof(mbr_str));
+ vty_out(vty, "ip msdp mesh-group %s member %s\n",
+ mg->mesh_group_name, mbr_str);
+ ++count;
+ }
+ return count;
}
/* Enable feature including active/periodic timers etc. on the first peer
* config. Till then MSDP should just stay quiet. */
-static void
-pim_msdp_enable(void)
+static void pim_msdp_enable(void)
{
- if (msdp->flags & PIM_MSDPF_ENABLE) {
- /* feature is already enabled */
- return;
- }
- msdp->flags |= PIM_MSDPF_ENABLE;
- msdp->work_obuf = stream_new(PIM_MSDP_MAX_PACKET_SIZE);
- pim_msdp_sa_adv_timer_setup(true /* start */);
- /* setup sa cache based on local sources */
- pim_msdp_sa_local_setup();
+ if (msdp->flags & PIM_MSDPF_ENABLE) {
+ /* feature is already enabled */
+ return;
+ }
+ msdp->flags |= PIM_MSDPF_ENABLE;
+ msdp->work_obuf = stream_new(PIM_MSDP_MAX_PACKET_SIZE);
+ pim_msdp_sa_adv_timer_setup(true /* start */);
+ /* setup sa cache based on local sources */
+ pim_msdp_sa_local_setup();
}
/* MSDP init */
-void
-pim_msdp_init(struct thread_master *master)
+void pim_msdp_init(struct thread_master *master)
{
- msdp->master = master;
+ msdp->master = master;
- msdp->peer_hash = hash_create(pim_msdp_peer_hash_key_make,
- pim_msdp_peer_hash_eq, NULL);
- msdp->peer_list = list_new();
- msdp->peer_list->del = (void (*)(void *))pim_msdp_peer_free;
- msdp->peer_list->cmp = (int (*)(void *, void *))pim_msdp_peer_comp;
+ msdp->peer_hash = hash_create(pim_msdp_peer_hash_key_make,
+ pim_msdp_peer_hash_eq, NULL);
+ msdp->peer_list = list_new();
+ msdp->peer_list->del = (void (*)(void *))pim_msdp_peer_free;
+ msdp->peer_list->cmp = (int (*)(void *, void *))pim_msdp_peer_comp;
- msdp->sa_hash = hash_create(pim_msdp_sa_hash_key_make,
- pim_msdp_sa_hash_eq, NULL);
- msdp->sa_list = list_new();
- msdp->sa_list->del = (void (*)(void *))pim_msdp_sa_free;
- msdp->sa_list->cmp = (int (*)(void *, void *))pim_msdp_sa_comp;
+ msdp->sa_hash = hash_create(pim_msdp_sa_hash_key_make,
+ pim_msdp_sa_hash_eq, NULL);
+ msdp->sa_list = list_new();
+ msdp->sa_list->del = (void (*)(void *))pim_msdp_sa_free;
+ msdp->sa_list->cmp = (int (*)(void *, void *))pim_msdp_sa_comp;
}
/* counterpart to MSDP init; XXX: unused currently */
-void
-pim_msdp_exit(void)
+void pim_msdp_exit(void)
{
- /* XXX: stop listener and delete all peer sessions */
+ /* XXX: stop listener and delete all peer sessions */
- if (msdp->peer_hash) {
- hash_free(msdp->peer_hash);
- msdp->peer_hash = NULL;
- }
+ if (msdp->peer_hash) {
+ hash_free(msdp->peer_hash);
+ msdp->peer_hash = NULL;
+ }
- if (msdp->peer_list) {
- list_free(msdp->peer_list);
- msdp->peer_list = NULL;
- }
+ if (msdp->peer_list) {
+ list_free(msdp->peer_list);
+ msdp->peer_list = NULL;
+ }
}
diff --git a/pimd/pim_msdp.h b/pimd/pim_msdp.h
index 308b437a6..66e5457df 100644
--- a/pimd/pim_msdp.h
+++ b/pimd/pim_msdp.h
@@ -20,35 +20,35 @@
#define PIM_MSDP_H
enum pim_msdp_peer_state {
- PIM_MSDP_DISABLED,
- PIM_MSDP_INACTIVE,
- PIM_MSDP_LISTEN,
- PIM_MSDP_CONNECTING,
- PIM_MSDP_ESTABLISHED
+ PIM_MSDP_DISABLED,
+ PIM_MSDP_INACTIVE,
+ PIM_MSDP_LISTEN,
+ PIM_MSDP_CONNECTING,
+ PIM_MSDP_ESTABLISHED
};
/* SA and KA TLVs are processed; rest ignored */
enum pim_msdp_tlv {
- PIM_MSDP_V4_SOURCE_ACTIVE = 1,
- PIM_MSDP_V4_SOURCE_ACTIVE_REQUEST,
- PIM_MSDP_V4_SOURCE_ACTIVE_RESPONSE,
- PIM_MSDP_KEEPALIVE,
- PIM_MSDP_RESERVED,
- PIM_MSDP_TRACEROUTE_PROGRESS,
- PIM_MSDP_TRACEROUTE_REPLY,
+ PIM_MSDP_V4_SOURCE_ACTIVE = 1,
+ PIM_MSDP_V4_SOURCE_ACTIVE_REQUEST,
+ PIM_MSDP_V4_SOURCE_ACTIVE_RESPONSE,
+ PIM_MSDP_KEEPALIVE,
+ PIM_MSDP_RESERVED,
+ PIM_MSDP_TRACEROUTE_PROGRESS,
+ PIM_MSDP_TRACEROUTE_REPLY,
};
/* MSDP error codes */
enum pim_msdp_err {
- PIM_MSDP_ERR_NONE = 0,
- PIM_MSDP_ERR_OOM = -1,
- PIM_MSDP_ERR_PEER_EXISTS = -2,
- PIM_MSDP_ERR_MAX_MESH_GROUPS = -3,
- PIM_MSDP_ERR_NO_PEER = -4,
- PIM_MSDP_ERR_MG_MBR_EXISTS = -5,
- PIM_MSDP_ERR_NO_MG = -6,
- PIM_MSDP_ERR_NO_MG_MBR = -7,
- PIM_MSDP_ERR_SIP_EQ_DIP = -8,
+ PIM_MSDP_ERR_NONE = 0,
+ PIM_MSDP_ERR_OOM = -1,
+ PIM_MSDP_ERR_PEER_EXISTS = -2,
+ PIM_MSDP_ERR_MAX_MESH_GROUPS = -3,
+ PIM_MSDP_ERR_NO_PEER = -4,
+ PIM_MSDP_ERR_MG_MBR_EXISTS = -5,
+ PIM_MSDP_ERR_NO_MG = -6,
+ PIM_MSDP_ERR_NO_MG_MBR = -7,
+ PIM_MSDP_ERR_SIP_EQ_DIP = -8,
};
#define PIM_MSDP_STATE_STRLEN 16
@@ -58,149 +58,155 @@ enum pim_msdp_err {
#define PIM_MSDP_SOCKET_SNDBUF_SIZE 65536
enum pim_msdp_sa_flags {
- PIM_MSDP_SAF_NONE = 0,
- /* There are two cases where we can pickup an active source locally -
- * 1. We are RP and got a source-register from the FHR
- * 2. We are RP and FHR and learnt a new directly connected source on a
- * DR interface */
- PIM_MSDP_SAF_LOCAL = (1 << 0),
- /* We got this in the MSDP SA TLV from a peer (and this passed peer-RPF
- * checks) */
- PIM_MSDP_SAF_PEER = (1 << 1),
- PIM_MSDP_SAF_REF = (PIM_MSDP_SAF_LOCAL | PIM_MSDP_SAF_PEER),
- PIM_MSDP_SAF_STALE = (1 << 2), /* local entries can get kicked out on
- * misc pim events such as RP change */
- PIM_MSDP_SAF_UP_DEL_IN_PROG = (1 << 3)
+ PIM_MSDP_SAF_NONE = 0,
+ /* There are two cases where we can pickup an active source locally -
+ * 1. We are RP and got a source-register from the FHR
+ * 2. We are RP and FHR and learnt a new directly connected source on a
+ * DR interface */
+ PIM_MSDP_SAF_LOCAL = (1 << 0),
+ /* We got this in the MSDP SA TLV from a peer (and this passed peer-RPF
+ * checks) */
+ PIM_MSDP_SAF_PEER = (1 << 1),
+ PIM_MSDP_SAF_REF = (PIM_MSDP_SAF_LOCAL | PIM_MSDP_SAF_PEER),
+ PIM_MSDP_SAF_STALE = (1 << 2), /* local entries can get kicked out on
+ * misc pim events such as RP change */
+ PIM_MSDP_SAF_UP_DEL_IN_PROG = (1 << 3)
};
struct pim_msdp_sa {
- struct prefix_sg sg;
- char sg_str[PIM_SG_LEN];
- struct in_addr rp; /* Last RP address associated with this SA */
- struct in_addr peer; /* last peer from who we heard this SA */
- enum pim_msdp_sa_flags flags;
-
- /* rfc-3618 is missing default value for SA-hold-down-Period. pulled
- * this number from industry-standards */
+ struct prefix_sg sg;
+ char sg_str[PIM_SG_LEN];
+ struct in_addr rp; /* Last RP address associated with this SA */
+ struct in_addr peer; /* last peer from who we heard this SA */
+ enum pim_msdp_sa_flags flags;
+
+/* rfc-3618 is missing default value for SA-hold-down-Period. pulled
+ * this number from industry-standards */
#define PIM_MSDP_SA_HOLD_TIME ((3*60)+30)
- struct thread *sa_state_timer; // 5.6
- int64_t uptime;
+ struct thread *sa_state_timer; // 5.6
+ int64_t uptime;
- struct pim_upstream *up;
+ struct pim_upstream *up;
};
enum pim_msdp_peer_flags {
- PIM_MSDP_PEERF_NONE = 0,
- PIM_MSDP_PEERF_LISTENER = (1 << 0),
+ PIM_MSDP_PEERF_NONE = 0,
+ PIM_MSDP_PEERF_LISTENER = (1 << 0),
#define PIM_MSDP_PEER_IS_LISTENER(mp) (mp->flags & PIM_MSDP_PEERF_LISTENER)
- PIM_MSDP_PEERF_SA_JUST_SENT = (1 << 1)
+ PIM_MSDP_PEERF_SA_JUST_SENT = (1 << 1)
};
struct pim_msdp_peer {
- /* configuration */
- struct in_addr local;
- struct in_addr peer;
- char *mesh_group_name;
- char key_str[INET_ADDRSTRLEN];
-
- /* state */
- enum pim_msdp_peer_state state;
- enum pim_msdp_peer_flags flags;
-
- /* TCP socket info */
- union sockunion su_local;
- union sockunion su_peer;
- int fd;
-
- /* protocol timers */
+ /* configuration */
+ struct in_addr local;
+ struct in_addr peer;
+ char *mesh_group_name;
+ char key_str[INET_ADDRSTRLEN];
+
+ /* state */
+ enum pim_msdp_peer_state state;
+ enum pim_msdp_peer_flags flags;
+
+ /* TCP socket info */
+ union sockunion su_local;
+ union sockunion su_peer;
+ int fd;
+
+/* protocol timers */
#define PIM_MSDP_PEER_HOLD_TIME 75
- struct thread *hold_timer; // 5.4
+ struct thread *hold_timer; // 5.4
+ /* $FRR indent$ */
+/* clang-format off */
#define PIM_MSDP_PEER_KA_TIME 60
- struct thread *ka_timer; // 5.5
+ struct thread *ka_timer; // 5.5
+ /* $FRR indent$ */
+ /* clang-format off */
#define PIM_MSDP_PEER_CONNECT_RETRY_TIME 30
- struct thread *cr_timer; // 5.6
-
- /* packet thread and buffers */
- uint32_t packet_size;
- struct stream *ibuf;
- struct stream_fifo *obuf;
- struct thread *t_read;
- struct thread *t_write;
-
- /* stats */
- uint32_t conn_attempts;
- uint32_t est_flaps;
- uint32_t sa_cnt; /* number of SAs attributed to this peer */
+ struct thread *cr_timer; // 5.6
+
+ /* packet thread and buffers */
+ uint32_t packet_size;
+ struct stream *ibuf;
+ struct stream_fifo *obuf;
+ struct thread *t_read;
+ struct thread *t_write;
+
+ /* stats */
+ uint32_t conn_attempts;
+ uint32_t est_flaps;
+ uint32_t sa_cnt; /* number of SAs attributed to this peer */
+ /* $FRR indent$ */
+ /* clang-format off */
#define PIM_MSDP_PEER_LAST_RESET_STR 20
- char last_reset[PIM_MSDP_PEER_LAST_RESET_STR];
+ char last_reset[PIM_MSDP_PEER_LAST_RESET_STR];
- /* packet stats */
- uint32_t ka_tx_cnt;
- uint32_t sa_tx_cnt;
- uint32_t ka_rx_cnt;
- uint32_t sa_rx_cnt;
- uint32_t unk_rx_cnt;
+ /* packet stats */
+ uint32_t ka_tx_cnt;
+ uint32_t sa_tx_cnt;
+ uint32_t ka_rx_cnt;
+ uint32_t sa_rx_cnt;
+ uint32_t unk_rx_cnt;
- /* timestamps */
- int64_t uptime;
+ /* timestamps */
+ int64_t uptime;
};
struct pim_msdp_mg_mbr {
- struct in_addr mbr_ip;
- struct pim_msdp_peer *mp;
+ struct in_addr mbr_ip;
+ struct pim_msdp_peer *mp;
};
/* PIM MSDP mesh-group */
struct pim_msdp_mg {
- char *mesh_group_name;
- struct in_addr src_ip;
- uint32_t mbr_cnt;
- struct list *mbr_list;
+ char *mesh_group_name;
+ struct in_addr src_ip;
+ uint32_t mbr_cnt;
+ struct list *mbr_list;
};
enum pim_msdp_flags {
- PIM_MSDPF_NONE = 0,
- PIM_MSDPF_ENABLE = (1 << 0),
- PIM_MSDPF_LISTENER = (1 << 1)
+ PIM_MSDPF_NONE = 0,
+ PIM_MSDPF_ENABLE = (1 << 0),
+ PIM_MSDPF_LISTENER = (1 << 1)
};
struct pim_msdp_listener {
- int fd;
- union sockunion su;
- struct thread *thread;
+ int fd;
+ union sockunion su;
+ struct thread *thread;
};
struct pim_msdp {
- enum pim_msdp_flags flags;
- struct thread_master *master;
- struct pim_msdp_listener listener;
- uint32_t rejected_accepts;
+ enum pim_msdp_flags flags;
+ struct thread_master *master;
+ struct pim_msdp_listener listener;
+ uint32_t rejected_accepts;
- /* MSDP peer info */
- struct hash *peer_hash;
- struct list *peer_list;
+ /* MSDP peer info */
+ struct hash *peer_hash;
+ struct list *peer_list;
- /* MSDP active-source info */
+/* MSDP active-source info */
#define PIM_MSDP_SA_ADVERTISMENT_TIME 60
- struct thread *sa_adv_timer; // 5.6
- struct hash *sa_hash;
- struct list *sa_list;
- uint32_t local_cnt;
+ struct thread *sa_adv_timer; // 5.6
+ struct hash *sa_hash;
+ struct list *sa_list;
+ uint32_t local_cnt;
- /* keep a scratch pad for building SA TLVs */
- struct stream *work_obuf;
+ /* keep a scratch pad for building SA TLVs */
+ struct stream *work_obuf;
- struct in_addr originator_id;
+ struct in_addr originator_id;
- /* currently only one mesh-group is supported - so just stash it here */
- struct pim_msdp_mg *mg;
+ /* currently only one mesh-group is supported - so just stash it here */
+ struct pim_msdp_mg *mg;
};
-#define PIM_MSDP_PEER_READ_ON(mp) \
- thread_add_read (msdp->master, pim_msdp_read, mp, mp->fd, &mp->t_read)
+#define PIM_MSDP_PEER_READ_ON(mp) \
+ thread_add_read(msdp->master, pim_msdp_read, mp, mp->fd, &mp->t_read)
-#define PIM_MSDP_PEER_WRITE_ON(mp) \
- thread_add_write (msdp->master, pim_msdp_write, mp, mp->fd, &mp->t_write)
+#define PIM_MSDP_PEER_WRITE_ON(mp) \
+ thread_add_write(msdp->master, pim_msdp_write, mp, mp->fd, &mp->t_write)
#define PIM_MSDP_PEER_READ_OFF(mp) THREAD_READ_OFF(mp->t_read)
#define PIM_MSDP_PEER_WRITE_OFF(mp) THREAD_WRITE_OFF(mp->t_write)
@@ -208,28 +214,36 @@ struct pim_msdp {
extern struct pim_msdp *msdp;
void pim_msdp_init(struct thread_master *master);
void pim_msdp_exit(void);
-enum pim_msdp_err pim_msdp_peer_add(struct in_addr peer, struct in_addr local, const char *mesh_group_name, struct pim_msdp_peer **mp_p);
+enum pim_msdp_err pim_msdp_peer_add(struct in_addr peer, struct in_addr local,
+ const char *mesh_group_name,
+ struct pim_msdp_peer **mp_p);
enum pim_msdp_err pim_msdp_peer_del(struct in_addr peer_addr);
-char *pim_msdp_state_dump(enum pim_msdp_peer_state state, char *buf, int buf_size);
+char *pim_msdp_state_dump(enum pim_msdp_peer_state state, char *buf,
+ int buf_size);
struct pim_msdp_peer *pim_msdp_peer_find(struct in_addr peer_addr);
void pim_msdp_peer_established(struct pim_msdp_peer *mp);
void pim_msdp_peer_pkt_rxed(struct pim_msdp_peer *mp);
void pim_msdp_peer_stop_tcp_conn(struct pim_msdp_peer *mp, bool chg_state);
void pim_msdp_peer_reset_tcp_conn(struct pim_msdp_peer *mp, const char *rc_str);
int pim_msdp_write(struct thread *thread);
-char *pim_msdp_peer_key_dump(struct pim_msdp_peer *mp, char *buf, int buf_size, bool long_format);
+char *pim_msdp_peer_key_dump(struct pim_msdp_peer *mp, char *buf, int buf_size,
+ bool long_format);
int pim_msdp_config_write(struct vty *vty);
void pim_msdp_peer_pkt_txed(struct pim_msdp_peer *mp);
-void pim_msdp_sa_ref(struct pim_msdp_peer *mp, struct prefix_sg *sg, struct in_addr rp);
+void pim_msdp_sa_ref(struct pim_msdp_peer *mp, struct prefix_sg *sg,
+ struct in_addr rp);
void pim_msdp_sa_local_update(struct pim_upstream *up);
void pim_msdp_sa_local_del(struct prefix_sg *sg);
void pim_msdp_i_am_rp_changed(void);
bool pim_msdp_peer_rpf_check(struct pim_msdp_peer *mp, struct in_addr rp);
void pim_msdp_up_join_state_changed(struct pim_upstream *xg_up);
void pim_msdp_up_del(struct prefix_sg *sg);
-enum pim_msdp_err pim_msdp_mg_mbr_add(const char *mesh_group_name, struct in_addr mbr_ip);
-enum pim_msdp_err pim_msdp_mg_mbr_del(const char *mesh_group_name, struct in_addr mbr_ip);
+enum pim_msdp_err pim_msdp_mg_mbr_add(const char *mesh_group_name,
+ struct in_addr mbr_ip);
+enum pim_msdp_err pim_msdp_mg_mbr_del(const char *mesh_group_name,
+ struct in_addr mbr_ip);
enum pim_msdp_err pim_msdp_mg_src_del(const char *mesh_group_name);
-enum pim_msdp_err pim_msdp_mg_src_add(const char *mesh_group_name, struct in_addr src_ip);
+enum pim_msdp_err pim_msdp_mg_src_add(const char *mesh_group_name,
+ struct in_addr src_ip);
enum pim_msdp_err pim_msdp_mg_del(const char *mesh_group_name);
#endif
diff --git a/pimd/pim_msdp_packet.c b/pimd/pim_msdp_packet.c
index 0a8679336..01ce293e3 100644
--- a/pimd/pim_msdp_packet.c
+++ b/pimd/pim_msdp_packet.c
@@ -31,665 +31,661 @@
#include "pim_msdp_packet.h"
#include "pim_msdp_socket.h"
-static char *
-pim_msdp_pkt_type_dump(enum pim_msdp_tlv type, char *buf, int buf_size)
+static char *pim_msdp_pkt_type_dump(enum pim_msdp_tlv type, char *buf,
+ int buf_size)
{
- switch (type) {
- case PIM_MSDP_V4_SOURCE_ACTIVE:
- snprintf(buf, buf_size, "%s", "SA");
- break;
- case PIM_MSDP_V4_SOURCE_ACTIVE_REQUEST:
- snprintf(buf, buf_size, "%s", "SA_REQ");
- break;
- case PIM_MSDP_V4_SOURCE_ACTIVE_RESPONSE:
- snprintf(buf, buf_size, "%s", "SA_RESP");
- break;
- case PIM_MSDP_KEEPALIVE:
- snprintf(buf, buf_size, "%s", "KA");
- break;
- case PIM_MSDP_RESERVED:
- snprintf(buf, buf_size, "%s", "RSVD");
- break;
- case PIM_MSDP_TRACEROUTE_PROGRESS:
- snprintf(buf, buf_size, "%s", "TRACE_PROG");
- break;
- case PIM_MSDP_TRACEROUTE_REPLY:
- snprintf(buf, buf_size, "%s", "TRACE_REPLY");
- break;
- default:
- snprintf(buf, buf_size, "UNK-%d", type);
- }
- return buf;
+ switch (type) {
+ case PIM_MSDP_V4_SOURCE_ACTIVE:
+ snprintf(buf, buf_size, "%s", "SA");
+ break;
+ case PIM_MSDP_V4_SOURCE_ACTIVE_REQUEST:
+ snprintf(buf, buf_size, "%s", "SA_REQ");
+ break;
+ case PIM_MSDP_V4_SOURCE_ACTIVE_RESPONSE:
+ snprintf(buf, buf_size, "%s", "SA_RESP");
+ break;
+ case PIM_MSDP_KEEPALIVE:
+ snprintf(buf, buf_size, "%s", "KA");
+ break;
+ case PIM_MSDP_RESERVED:
+ snprintf(buf, buf_size, "%s", "RSVD");
+ break;
+ case PIM_MSDP_TRACEROUTE_PROGRESS:
+ snprintf(buf, buf_size, "%s", "TRACE_PROG");
+ break;
+ case PIM_MSDP_TRACEROUTE_REPLY:
+ snprintf(buf, buf_size, "%s", "TRACE_REPLY");
+ break;
+ default:
+ snprintf(buf, buf_size, "UNK-%d", type);
+ }
+ return buf;
}
-static void
-pim_msdp_pkt_sa_dump_one(struct stream *s)
+static void pim_msdp_pkt_sa_dump_one(struct stream *s)
{
- struct prefix_sg sg;
+ struct prefix_sg sg;
- /* just throw away the three reserved bytes */
- stream_get3(s);
- /* throw away the prefix length also */
- stream_getc(s);
+ /* just throw away the three reserved bytes */
+ stream_get3(s);
+ /* throw away the prefix length also */
+ stream_getc(s);
- memset(&sg, 0, sizeof (struct prefix_sg));
- sg.grp.s_addr = stream_get_ipv4(s);
- sg.src.s_addr = stream_get_ipv4(s);
+ memset(&sg, 0, sizeof(struct prefix_sg));
+ sg.grp.s_addr = stream_get_ipv4(s);
+ sg.src.s_addr = stream_get_ipv4(s);
- zlog_debug(" sg %s", pim_str_sg_dump(&sg));
+ zlog_debug(" sg %s", pim_str_sg_dump(&sg));
}
-static void
-pim_msdp_pkt_sa_dump(struct stream *s)
+static void pim_msdp_pkt_sa_dump(struct stream *s)
{
- int entry_cnt;
- int i;
- struct in_addr rp; /* Last RP address associated with this SA */
-
- entry_cnt = stream_getc(s);
- rp.s_addr = stream_get_ipv4(s);
-
- if (PIM_DEBUG_MSDP_PACKETS) {
- char rp_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<rp?>", rp, rp_str, sizeof(rp_str));
- zlog_debug(" entry_cnt %d rp %s", entry_cnt, rp_str);
- }
-
- /* dump SAs */
- for (i = 0; i < entry_cnt; ++i) {
- pim_msdp_pkt_sa_dump_one(s);
- }
+ int entry_cnt;
+ int i;
+ struct in_addr rp; /* Last RP address associated with this SA */
+
+ entry_cnt = stream_getc(s);
+ rp.s_addr = stream_get_ipv4(s);
+
+ if (PIM_DEBUG_MSDP_PACKETS) {
+ char rp_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<rp?>", rp, rp_str, sizeof(rp_str));
+ zlog_debug(" entry_cnt %d rp %s", entry_cnt, rp_str);
+ }
+
+ /* dump SAs */
+ for (i = 0; i < entry_cnt; ++i) {
+ pim_msdp_pkt_sa_dump_one(s);
+ }
}
-static void
-pim_msdp_pkt_dump(struct pim_msdp_peer *mp, int type, int len, bool rx,
- struct stream *s)
+static void pim_msdp_pkt_dump(struct pim_msdp_peer *mp, int type, int len,
+ bool rx, struct stream *s)
{
- char type_str[PIM_MSDP_PKT_TYPE_STRLEN];
+ char type_str[PIM_MSDP_PKT_TYPE_STRLEN];
- pim_msdp_pkt_type_dump(type, type_str, sizeof(type_str));
+ pim_msdp_pkt_type_dump(type, type_str, sizeof(type_str));
- zlog_debug("MSDP peer %s pkt %s type %s len %d",
- mp->key_str, rx?"rx":"tx", type_str, len);
+ zlog_debug("MSDP peer %s pkt %s type %s len %d", mp->key_str,
+ rx ? "rx" : "tx", type_str, len);
- if (!s) {
- return;
- }
+ if (!s) {
+ return;
+ }
- switch(type) {
- case PIM_MSDP_V4_SOURCE_ACTIVE:
- pim_msdp_pkt_sa_dump(s);
- break;
- default:;
- }
+ switch (type) {
+ case PIM_MSDP_V4_SOURCE_ACTIVE:
+ pim_msdp_pkt_sa_dump(s);
+ break;
+ default:;
+ }
}
/* Check file descriptor whether connect is established. */
-static void
-pim_msdp_connect_check(struct pim_msdp_peer *mp)
+static void pim_msdp_connect_check(struct pim_msdp_peer *mp)
{
- int status;
- socklen_t slen;
- int ret;
-
- if (mp->state != PIM_MSDP_CONNECTING) {
- /* if we are here it means we are not in a connecting or established state
- * for now treat this as a fatal error */
- pim_msdp_peer_reset_tcp_conn(mp, "invalid-state");
- return;
- }
-
- PIM_MSDP_PEER_READ_OFF(mp);
- PIM_MSDP_PEER_WRITE_OFF(mp);
-
- /* Check file descriptor. */
- slen = sizeof(status);
- ret = getsockopt(mp->fd, SOL_SOCKET, SO_ERROR, (void *)&status, &slen);
-
- /* If getsockopt is fail, this is fatal error. */
- if (ret < 0) {
- zlog_err("can't get sockopt for nonblocking connect");
- pim_msdp_peer_reset_tcp_conn(mp, "connect-failed");
- return;
- }
-
- /* When status is 0 then TCP connection is established. */
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP peer %s pim_connect_check %s", mp->key_str, status?"fail":"success");
- }
- if (status == 0) {
- pim_msdp_peer_established(mp);
- } else {
- pim_msdp_peer_reset_tcp_conn(mp, "connect-failed");
- }
+ int status;
+ socklen_t slen;
+ int ret;
+
+ if (mp->state != PIM_MSDP_CONNECTING) {
+ /* if we are here it means we are not in a connecting or
+ * established state
+ * for now treat this as a fatal error */
+ pim_msdp_peer_reset_tcp_conn(mp, "invalid-state");
+ return;
+ }
+
+ PIM_MSDP_PEER_READ_OFF(mp);
+ PIM_MSDP_PEER_WRITE_OFF(mp);
+
+ /* Check file descriptor. */
+ slen = sizeof(status);
+ ret = getsockopt(mp->fd, SOL_SOCKET, SO_ERROR, (void *)&status, &slen);
+
+ /* If getsockopt is fail, this is fatal error. */
+ if (ret < 0) {
+ zlog_err("can't get sockopt for nonblocking connect");
+ pim_msdp_peer_reset_tcp_conn(mp, "connect-failed");
+ return;
+ }
+
+ /* When status is 0 then TCP connection is established. */
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s pim_connect_check %s", mp->key_str,
+ status ? "fail" : "success");
+ }
+ if (status == 0) {
+ pim_msdp_peer_established(mp);
+ } else {
+ pim_msdp_peer_reset_tcp_conn(mp, "connect-failed");
+ }
}
-static void
-pim_msdp_pkt_delete(struct pim_msdp_peer *mp)
+static void pim_msdp_pkt_delete(struct pim_msdp_peer *mp)
{
- stream_free(stream_fifo_pop(mp->obuf));
+ stream_free(stream_fifo_pop(mp->obuf));
}
-static void
-pim_msdp_pkt_add(struct pim_msdp_peer *mp, struct stream *s)
+static void pim_msdp_pkt_add(struct pim_msdp_peer *mp, struct stream *s)
{
- stream_fifo_push(mp->obuf, s);
+ stream_fifo_push(mp->obuf, s);
}
-static void
-pim_msdp_write_proceed_actions(struct pim_msdp_peer *mp)
+static void pim_msdp_write_proceed_actions(struct pim_msdp_peer *mp)
{
- if (stream_fifo_head(mp->obuf)) {
- PIM_MSDP_PEER_WRITE_ON(mp);
- }
+ if (stream_fifo_head(mp->obuf)) {
+ PIM_MSDP_PEER_WRITE_ON(mp);
+ }
}
-int
-pim_msdp_write(struct thread *thread)
+int pim_msdp_write(struct thread *thread)
{
- struct pim_msdp_peer *mp;
- struct stream *s;
- int num;
- enum pim_msdp_tlv type;
- int len;
- int work_cnt = 0;
- int work_max_cnt = 100;
-
- mp = THREAD_ARG(thread);
- mp->t_write = NULL;
-
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP peer %s pim_msdp_write", mp->key_str);
- }
- if (mp->fd < 0) {
- return -1;
- }
-
- /* check if TCP connection is established */
- if (mp->state != PIM_MSDP_ESTABLISHED) {
- pim_msdp_connect_check(mp);
- return 0;
- }
-
- s = stream_fifo_head(mp->obuf);
- if (!s) {
- pim_msdp_write_proceed_actions(mp);
- return 0;
- }
-
- sockopt_cork(mp->fd, 1);
-
- /* Nonblocking write until TCP output buffer is full */
- do
- {
- int writenum;
-
- /* Number of bytes to be sent */
- writenum = stream_get_endp(s) - stream_get_getp(s);
-
- /* Call write() system call */
- num = write(mp->fd, STREAM_PNT(s), writenum);
- if (num < 0) {
- /* write failed either retry needed or error */
- if (ERRNO_IO_RETRY(errno)) {
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP peer %s pim_msdp_write io retry", mp->key_str);
- }
- break;
- }
-
- pim_msdp_peer_reset_tcp_conn(mp, "pkt-tx-failed");
- return 0;
- }
-
- if (num != writenum) {
- /* Partial write */
- stream_forward_getp(s, num);
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP peer %s pim_msdp_partial_write", mp->key_str);
- }
- break;
- }
-
- /* Retrieve msdp packet type. */
- stream_set_getp(s,0);
- type = stream_getc(s);
- len = stream_getw(s);
- switch (type)
- {
- case PIM_MSDP_KEEPALIVE:
- mp->ka_tx_cnt++;
- break;
- case PIM_MSDP_V4_SOURCE_ACTIVE:
- mp->sa_tx_cnt++;
- break;
- default:;
- }
- if (PIM_DEBUG_MSDP_PACKETS) {
- pim_msdp_pkt_dump(mp, type, len, false /*rx*/, s);
- }
-
- /* packet sent delete it. */
- pim_msdp_pkt_delete(mp);
-
- ++work_cnt;
- /* may need to pause if we have done too much work in this
- * loop */
- if (work_cnt >= work_max_cnt) {
- break;
- }
- } while ((s = stream_fifo_head(mp->obuf)) != NULL);
- pim_msdp_write_proceed_actions(mp);
-
- sockopt_cork(mp->fd, 0);
-
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP peer %s pim_msdp_write wrote %d packets", mp->key_str, work_cnt);
- }
-
- return 0;
+ struct pim_msdp_peer *mp;
+ struct stream *s;
+ int num;
+ enum pim_msdp_tlv type;
+ int len;
+ int work_cnt = 0;
+ int work_max_cnt = 100;
+
+ mp = THREAD_ARG(thread);
+ mp->t_write = NULL;
+
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s pim_msdp_write", mp->key_str);
+ }
+ if (mp->fd < 0) {
+ return -1;
+ }
+
+ /* check if TCP connection is established */
+ if (mp->state != PIM_MSDP_ESTABLISHED) {
+ pim_msdp_connect_check(mp);
+ return 0;
+ }
+
+ s = stream_fifo_head(mp->obuf);
+ if (!s) {
+ pim_msdp_write_proceed_actions(mp);
+ return 0;
+ }
+
+ sockopt_cork(mp->fd, 1);
+
+ /* Nonblocking write until TCP output buffer is full */
+ do {
+ int writenum;
+
+ /* Number of bytes to be sent */
+ writenum = stream_get_endp(s) - stream_get_getp(s);
+
+ /* Call write() system call */
+ num = write(mp->fd, STREAM_PNT(s), writenum);
+ if (num < 0) {
+ /* write failed either retry needed or error */
+ if (ERRNO_IO_RETRY(errno)) {
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug(
+ "MSDP peer %s pim_msdp_write io retry",
+ mp->key_str);
+ }
+ break;
+ }
+
+ pim_msdp_peer_reset_tcp_conn(mp, "pkt-tx-failed");
+ return 0;
+ }
+
+ if (num != writenum) {
+ /* Partial write */
+ stream_forward_getp(s, num);
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug(
+ "MSDP peer %s pim_msdp_partial_write",
+ mp->key_str);
+ }
+ break;
+ }
+
+ /* Retrieve msdp packet type. */
+ stream_set_getp(s, 0);
+ type = stream_getc(s);
+ len = stream_getw(s);
+ switch (type) {
+ case PIM_MSDP_KEEPALIVE:
+ mp->ka_tx_cnt++;
+ break;
+ case PIM_MSDP_V4_SOURCE_ACTIVE:
+ mp->sa_tx_cnt++;
+ break;
+ default:;
+ }
+ if (PIM_DEBUG_MSDP_PACKETS) {
+ pim_msdp_pkt_dump(mp, type, len, false /*rx*/, s);
+ }
+
+ /* packet sent delete it. */
+ pim_msdp_pkt_delete(mp);
+
+ ++work_cnt;
+ /* may need to pause if we have done too much work in this
+ * loop */
+ if (work_cnt >= work_max_cnt) {
+ break;
+ }
+ } while ((s = stream_fifo_head(mp->obuf)) != NULL);
+ pim_msdp_write_proceed_actions(mp);
+
+ sockopt_cork(mp->fd, 0);
+
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s pim_msdp_write wrote %d packets",
+ mp->key_str, work_cnt);
+ }
+
+ return 0;
}
-static void
-pim_msdp_pkt_send(struct pim_msdp_peer *mp, struct stream *s)
+static void pim_msdp_pkt_send(struct pim_msdp_peer *mp, struct stream *s)
{
- /* Add packet to the end of list. */
- pim_msdp_pkt_add(mp, s);
+ /* Add packet to the end of list. */
+ pim_msdp_pkt_add(mp, s);
- PIM_MSDP_PEER_WRITE_ON(mp);
+ PIM_MSDP_PEER_WRITE_ON(mp);
}
-void
-pim_msdp_pkt_ka_tx(struct pim_msdp_peer *mp)
+void pim_msdp_pkt_ka_tx(struct pim_msdp_peer *mp)
{
- struct stream *s;
+ struct stream *s;
- if (mp->state != PIM_MSDP_ESTABLISHED) {
- /* don't tx anything unless a session is established */
- return;
- }
- s = stream_new(PIM_MSDP_KA_TLV_MAX_SIZE);
- stream_putc(s, PIM_MSDP_KEEPALIVE);
- stream_putw(s, PIM_MSDP_KA_TLV_MAX_SIZE);
+ if (mp->state != PIM_MSDP_ESTABLISHED) {
+ /* don't tx anything unless a session is established */
+ return;
+ }
+ s = stream_new(PIM_MSDP_KA_TLV_MAX_SIZE);
+ stream_putc(s, PIM_MSDP_KEEPALIVE);
+ stream_putw(s, PIM_MSDP_KA_TLV_MAX_SIZE);
- pim_msdp_pkt_send(mp, s);
+ pim_msdp_pkt_send(mp, s);
}
-static void
-pim_msdp_pkt_sa_push_to_one_peer(struct pim_msdp_peer *mp)
+static void pim_msdp_pkt_sa_push_to_one_peer(struct pim_msdp_peer *mp)
{
- struct stream *s;
-
- if (mp->state != PIM_MSDP_ESTABLISHED) {
- /* don't tx anything unless a session is established */
- return;
- }
- s = stream_dup(msdp->work_obuf);
- if (s) {
- pim_msdp_pkt_send(mp, s);
- mp->flags |= PIM_MSDP_PEERF_SA_JUST_SENT;
- }
+ struct stream *s;
+
+ if (mp->state != PIM_MSDP_ESTABLISHED) {
+ /* don't tx anything unless a session is established */
+ return;
+ }
+ s = stream_dup(msdp->work_obuf);
+ if (s) {
+ pim_msdp_pkt_send(mp, s);
+ mp->flags |= PIM_MSDP_PEERF_SA_JUST_SENT;
+ }
}
/* push the stream into the obuf fifo of all the peers */
-static void
-pim_msdp_pkt_sa_push(struct pim_msdp_peer *mp)
+static void pim_msdp_pkt_sa_push(struct pim_msdp_peer *mp)
{
- struct listnode *mpnode;
-
- if (mp) {
- pim_msdp_pkt_sa_push_to_one_peer(mp);
- } else {
- for (ALL_LIST_ELEMENTS_RO(msdp->peer_list, mpnode, mp)) {
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP peer %s pim_msdp_pkt_sa_push", mp->key_str);
- }
- pim_msdp_pkt_sa_push_to_one_peer(mp);
- }
- }
+ struct listnode *mpnode;
+
+ if (mp) {
+ pim_msdp_pkt_sa_push_to_one_peer(mp);
+ } else {
+ for (ALL_LIST_ELEMENTS_RO(msdp->peer_list, mpnode, mp)) {
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s pim_msdp_pkt_sa_push",
+ mp->key_str);
+ }
+ pim_msdp_pkt_sa_push_to_one_peer(mp);
+ }
+ }
}
-static int
-pim_msdp_pkt_sa_fill_hdr(int local_cnt)
+static int pim_msdp_pkt_sa_fill_hdr(int local_cnt)
{
- int curr_tlv_ecnt;
-
- stream_reset(msdp->work_obuf);
- curr_tlv_ecnt = local_cnt>PIM_MSDP_SA_MAX_ENTRY_CNT?PIM_MSDP_SA_MAX_ENTRY_CNT:local_cnt;
- local_cnt -= curr_tlv_ecnt;
- stream_putc(msdp->work_obuf, PIM_MSDP_V4_SOURCE_ACTIVE);
- stream_putw(msdp->work_obuf, PIM_MSDP_SA_ENTRY_CNT2SIZE(curr_tlv_ecnt));
- stream_putc(msdp->work_obuf, curr_tlv_ecnt);
- stream_put_ipv4(msdp->work_obuf, msdp->originator_id.s_addr);
-
- return local_cnt;
+ int curr_tlv_ecnt;
+
+ stream_reset(msdp->work_obuf);
+ curr_tlv_ecnt = local_cnt > PIM_MSDP_SA_MAX_ENTRY_CNT
+ ? PIM_MSDP_SA_MAX_ENTRY_CNT
+ : local_cnt;
+ local_cnt -= curr_tlv_ecnt;
+ stream_putc(msdp->work_obuf, PIM_MSDP_V4_SOURCE_ACTIVE);
+ stream_putw(msdp->work_obuf, PIM_MSDP_SA_ENTRY_CNT2SIZE(curr_tlv_ecnt));
+ stream_putc(msdp->work_obuf, curr_tlv_ecnt);
+ stream_put_ipv4(msdp->work_obuf, msdp->originator_id.s_addr);
+
+ return local_cnt;
}
-static void
-pim_msdp_pkt_sa_fill_one(struct pim_msdp_sa *sa)
+static void pim_msdp_pkt_sa_fill_one(struct pim_msdp_sa *sa)
{
- stream_put3(msdp->work_obuf, 0 /* reserved */);
- stream_putc(msdp->work_obuf, 32 /* sprefix len */);
- stream_put_ipv4(msdp->work_obuf, sa->sg.grp.s_addr);
- stream_put_ipv4(msdp->work_obuf, sa->sg.src.s_addr);
+ stream_put3(msdp->work_obuf, 0 /* reserved */);
+ stream_putc(msdp->work_obuf, 32 /* sprefix len */);
+ stream_put_ipv4(msdp->work_obuf, sa->sg.grp.s_addr);
+ stream_put_ipv4(msdp->work_obuf, sa->sg.src.s_addr);
}
-static void
-pim_msdp_pkt_sa_gen(struct pim_msdp_peer *mp)
+static void pim_msdp_pkt_sa_gen(struct pim_msdp_peer *mp)
{
- struct listnode *sanode;
- struct pim_msdp_sa *sa;
- int sa_count;
- int local_cnt = msdp->local_cnt;
-
- sa_count = 0;
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug(" sa gen %d", local_cnt);
- }
-
- local_cnt = pim_msdp_pkt_sa_fill_hdr(local_cnt);
-
- for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
- if (!(sa->flags & PIM_MSDP_SAF_LOCAL)) {
- /* current implementation of MSDP is for anycast i.e. full mesh. so
- * no re-forwarding of SAs that we learnt from other peers */
- continue;
- }
- /* add sa into scratch pad */
- pim_msdp_pkt_sa_fill_one(sa);
- ++sa_count;
- if (sa_count >= PIM_MSDP_SA_MAX_ENTRY_CNT) {
- pim_msdp_pkt_sa_push(mp);
- /* reset headers */
- sa_count = 0;
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug(" sa gen for remainder %d", local_cnt);
- }
- local_cnt = pim_msdp_pkt_sa_fill_hdr(local_cnt);
- }
- }
-
- if (sa_count) {
- pim_msdp_pkt_sa_push(mp);
- }
- return;
+ struct listnode *sanode;
+ struct pim_msdp_sa *sa;
+ int sa_count;
+ int local_cnt = msdp->local_cnt;
+
+ sa_count = 0;
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug(" sa gen %d", local_cnt);
+ }
+
+ local_cnt = pim_msdp_pkt_sa_fill_hdr(local_cnt);
+
+ for (ALL_LIST_ELEMENTS_RO(msdp->sa_list, sanode, sa)) {
+ if (!(sa->flags & PIM_MSDP_SAF_LOCAL)) {
+ /* current implementation of MSDP is for anycast i.e.
+ * full mesh. so
+ * no re-forwarding of SAs that we learnt from other
+ * peers */
+ continue;
+ }
+ /* add sa into scratch pad */
+ pim_msdp_pkt_sa_fill_one(sa);
+ ++sa_count;
+ if (sa_count >= PIM_MSDP_SA_MAX_ENTRY_CNT) {
+ pim_msdp_pkt_sa_push(mp);
+ /* reset headers */
+ sa_count = 0;
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug(" sa gen for remainder %d",
+ local_cnt);
+ }
+ local_cnt = pim_msdp_pkt_sa_fill_hdr(local_cnt);
+ }
+ }
+
+ if (sa_count) {
+ pim_msdp_pkt_sa_push(mp);
+ }
+ return;
}
-static void
-pim_msdp_pkt_sa_tx_done(void)
+static void pim_msdp_pkt_sa_tx_done(void)
{
- struct listnode *mpnode;
- struct pim_msdp_peer *mp;
-
- /* if SA were sent to the peers we restart ka timer and avoid
- * unnecessary ka noise */
- for (ALL_LIST_ELEMENTS_RO(msdp->peer_list, mpnode, mp)) {
- if (mp->flags & PIM_MSDP_PEERF_SA_JUST_SENT) {
- mp->flags &= ~PIM_MSDP_PEERF_SA_JUST_SENT;
- pim_msdp_peer_pkt_txed(mp);
- }
- }
+ struct listnode *mpnode;
+ struct pim_msdp_peer *mp;
+
+ /* if SA were sent to the peers we restart ka timer and avoid
+ * unnecessary ka noise */
+ for (ALL_LIST_ELEMENTS_RO(msdp->peer_list, mpnode, mp)) {
+ if (mp->flags & PIM_MSDP_PEERF_SA_JUST_SENT) {
+ mp->flags &= ~PIM_MSDP_PEERF_SA_JUST_SENT;
+ pim_msdp_peer_pkt_txed(mp);
+ }
+ }
}
-void
-pim_msdp_pkt_sa_tx(void)
+void pim_msdp_pkt_sa_tx(void)
{
- pim_msdp_pkt_sa_gen(NULL /* mp */);
- pim_msdp_pkt_sa_tx_done();
+ pim_msdp_pkt_sa_gen(NULL /* mp */);
+ pim_msdp_pkt_sa_tx_done();
}
-void
-pim_msdp_pkt_sa_tx_one(struct pim_msdp_sa *sa)
+void pim_msdp_pkt_sa_tx_one(struct pim_msdp_sa *sa)
{
- pim_msdp_pkt_sa_fill_hdr(1 /* cnt */);
- pim_msdp_pkt_sa_fill_one(sa);
- pim_msdp_pkt_sa_push(NULL);
- pim_msdp_pkt_sa_tx_done();
+ pim_msdp_pkt_sa_fill_hdr(1 /* cnt */);
+ pim_msdp_pkt_sa_fill_one(sa);
+ pim_msdp_pkt_sa_push(NULL);
+ pim_msdp_pkt_sa_tx_done();
}
/* when a connection is first established we push all SAs immediately */
-void
-pim_msdp_pkt_sa_tx_to_one_peer(struct pim_msdp_peer *mp)
+void pim_msdp_pkt_sa_tx_to_one_peer(struct pim_msdp_peer *mp)
{
- pim_msdp_pkt_sa_gen(mp);
- pim_msdp_pkt_sa_tx_done();
+ pim_msdp_pkt_sa_gen(mp);
+ pim_msdp_pkt_sa_tx_done();
}
-static void
-pim_msdp_pkt_rxed_with_fatal_error(struct pim_msdp_peer *mp)
+static void pim_msdp_pkt_rxed_with_fatal_error(struct pim_msdp_peer *mp)
{
- pim_msdp_peer_reset_tcp_conn(mp, "invalid-pkt-rx");
+ pim_msdp_peer_reset_tcp_conn(mp, "invalid-pkt-rx");
}
-static void
-pim_msdp_pkt_ka_rx(struct pim_msdp_peer *mp, int len)
+static void pim_msdp_pkt_ka_rx(struct pim_msdp_peer *mp, int len)
{
- mp->ka_rx_cnt++;
- if (len != PIM_MSDP_KA_TLV_MAX_SIZE) {
- pim_msdp_pkt_rxed_with_fatal_error(mp);
- return;
- }
- pim_msdp_peer_pkt_rxed(mp);
+ mp->ka_rx_cnt++;
+ if (len != PIM_MSDP_KA_TLV_MAX_SIZE) {
+ pim_msdp_pkt_rxed_with_fatal_error(mp);
+ return;
+ }
+ pim_msdp_peer_pkt_rxed(mp);
}
-static void
-pim_msdp_pkt_sa_rx_one(struct pim_msdp_peer *mp, struct in_addr rp)
+static void pim_msdp_pkt_sa_rx_one(struct pim_msdp_peer *mp, struct in_addr rp)
{
- int prefix_len;
- struct prefix_sg sg;
-
- /* just throw away the three reserved bytes */
- stream_get3(mp->ibuf);
- prefix_len = stream_getc(mp->ibuf);
-
- memset(&sg, 0, sizeof (struct prefix_sg));
- sg.grp.s_addr = stream_get_ipv4(mp->ibuf);
- sg.src.s_addr = stream_get_ipv4(mp->ibuf);
-
- if (prefix_len != 32) {
- /* ignore SA update if the prefix length is not 32 */
- zlog_err("rxed sa update with invalid prefix length %d", prefix_len);
- return;
- }
- if (PIM_DEBUG_MSDP_PACKETS) {
- zlog_debug(" sg %s", pim_str_sg_dump(&sg));
- }
- pim_msdp_sa_ref(mp, &sg, rp);
+ int prefix_len;
+ struct prefix_sg sg;
+
+ /* just throw away the three reserved bytes */
+ stream_get3(mp->ibuf);
+ prefix_len = stream_getc(mp->ibuf);
+
+ memset(&sg, 0, sizeof(struct prefix_sg));
+ sg.grp.s_addr = stream_get_ipv4(mp->ibuf);
+ sg.src.s_addr = stream_get_ipv4(mp->ibuf);
+
+ if (prefix_len != 32) {
+ /* ignore SA update if the prefix length is not 32 */
+ zlog_err("rxed sa update with invalid prefix length %d",
+ prefix_len);
+ return;
+ }
+ if (PIM_DEBUG_MSDP_PACKETS) {
+ zlog_debug(" sg %s", pim_str_sg_dump(&sg));
+ }
+ pim_msdp_sa_ref(mp, &sg, rp);
}
-static void
-pim_msdp_pkt_sa_rx(struct pim_msdp_peer *mp, int len)
+static void pim_msdp_pkt_sa_rx(struct pim_msdp_peer *mp, int len)
{
- int entry_cnt;
- int i;
- struct in_addr rp; /* Last RP address associated with this SA */
-
- mp->sa_rx_cnt++;
-
- if (len < PIM_MSDP_SA_TLV_MIN_SIZE) {
- pim_msdp_pkt_rxed_with_fatal_error(mp);
- return;
- }
-
- entry_cnt = stream_getc(mp->ibuf);
- /* some vendors include the actual multicast data in the tlv (at the end).
- * we will ignore such data. in the future we may consider pushing it down
- * the RPT */
- if (len < PIM_MSDP_SA_ENTRY_CNT2SIZE(entry_cnt)) {
- pim_msdp_pkt_rxed_with_fatal_error(mp);
- return;
- }
- rp.s_addr = stream_get_ipv4(mp->ibuf);
-
- if (PIM_DEBUG_MSDP_PACKETS) {
- char rp_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<rp?>", rp, rp_str, sizeof(rp_str));
- zlog_debug(" entry_cnt %d rp %s", entry_cnt, rp_str);
- }
-
- if (!pim_msdp_peer_rpf_check(mp, rp)) {
- /* if peer-RPF check fails don't process the packet any further */
- if (PIM_DEBUG_MSDP_PACKETS) {
- zlog_debug(" peer RPF check failed");
- }
- return;
- }
-
- pim_msdp_peer_pkt_rxed(mp);
-
- /* update SA cache */
- for (i = 0; i < entry_cnt; ++i) {
- pim_msdp_pkt_sa_rx_one(mp, rp);
- }
+ int entry_cnt;
+ int i;
+ struct in_addr rp; /* Last RP address associated with this SA */
+
+ mp->sa_rx_cnt++;
+
+ if (len < PIM_MSDP_SA_TLV_MIN_SIZE) {
+ pim_msdp_pkt_rxed_with_fatal_error(mp);
+ return;
+ }
+
+ entry_cnt = stream_getc(mp->ibuf);
+ /* some vendors include the actual multicast data in the tlv (at the
+ * end).
+ * we will ignore such data. in the future we may consider pushing it
+ * down
+ * the RPT */
+ if (len < PIM_MSDP_SA_ENTRY_CNT2SIZE(entry_cnt)) {
+ pim_msdp_pkt_rxed_with_fatal_error(mp);
+ return;
+ }
+ rp.s_addr = stream_get_ipv4(mp->ibuf);
+
+ if (PIM_DEBUG_MSDP_PACKETS) {
+ char rp_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<rp?>", rp, rp_str, sizeof(rp_str));
+ zlog_debug(" entry_cnt %d rp %s", entry_cnt, rp_str);
+ }
+
+ if (!pim_msdp_peer_rpf_check(mp, rp)) {
+ /* if peer-RPF check fails don't process the packet any further
+ */
+ if (PIM_DEBUG_MSDP_PACKETS) {
+ zlog_debug(" peer RPF check failed");
+ }
+ return;
+ }
+
+ pim_msdp_peer_pkt_rxed(mp);
+
+ /* update SA cache */
+ for (i = 0; i < entry_cnt; ++i) {
+ pim_msdp_pkt_sa_rx_one(mp, rp);
+ }
}
-static void
-pim_msdp_pkt_rx(struct pim_msdp_peer *mp)
+static void pim_msdp_pkt_rx(struct pim_msdp_peer *mp)
{
- enum pim_msdp_tlv type;
- int len;
-
- /* re-read type and len */
- type = stream_getc_from(mp->ibuf, 0);
- len = stream_getw_from(mp->ibuf, 1);
- if (len < PIM_MSDP_HEADER_SIZE) {
- pim_msdp_pkt_rxed_with_fatal_error(mp);
- return;
- }
-
- if (len > PIM_MSDP_SA_TLV_MAX_SIZE) {
- /* if tlv size if greater than max just ignore the tlv */
- return;
- }
-
- if (PIM_DEBUG_MSDP_PACKETS) {
- pim_msdp_pkt_dump(mp, type, len, true /*rx*/, NULL /*s*/);
- }
-
- switch(type) {
- case PIM_MSDP_KEEPALIVE:
- pim_msdp_pkt_ka_rx(mp, len);
- break;
- case PIM_MSDP_V4_SOURCE_ACTIVE:
- mp->sa_rx_cnt++;
- pim_msdp_pkt_sa_rx(mp, len);
- break;
- default:
- mp->unk_rx_cnt++;
- }
+ enum pim_msdp_tlv type;
+ int len;
+
+ /* re-read type and len */
+ type = stream_getc_from(mp->ibuf, 0);
+ len = stream_getw_from(mp->ibuf, 1);
+ if (len < PIM_MSDP_HEADER_SIZE) {
+ pim_msdp_pkt_rxed_with_fatal_error(mp);
+ return;
+ }
+
+ if (len > PIM_MSDP_SA_TLV_MAX_SIZE) {
+ /* if tlv size if greater than max just ignore the tlv */
+ return;
+ }
+
+ if (PIM_DEBUG_MSDP_PACKETS) {
+ pim_msdp_pkt_dump(mp, type, len, true /*rx*/, NULL /*s*/);
+ }
+
+ switch (type) {
+ case PIM_MSDP_KEEPALIVE:
+ pim_msdp_pkt_ka_rx(mp, len);
+ break;
+ case PIM_MSDP_V4_SOURCE_ACTIVE:
+ mp->sa_rx_cnt++;
+ pim_msdp_pkt_sa_rx(mp, len);
+ break;
+ default:
+ mp->unk_rx_cnt++;
+ }
}
/* pim msdp read utility function. */
-static int
-pim_msdp_read_packet(struct pim_msdp_peer *mp)
+static int pim_msdp_read_packet(struct pim_msdp_peer *mp)
{
- int nbytes;
- int readsize;
- int old_endp;
- int new_endp;
-
- old_endp = stream_get_endp(mp->ibuf);
- readsize = mp->packet_size - old_endp;
- if (!readsize) {
- return 0;
- }
-
- /* Read packet from fd */
- nbytes = stream_read_try(mp->ibuf, mp->fd, readsize);
- new_endp = stream_get_endp(mp->ibuf);
- if (nbytes < 0) {
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP peer %s read failed %d", mp->key_str, nbytes);
- }
- if (nbytes == -2) {
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP peer %s pim_msdp_read io retry old_end: %d new_end: %d", mp->key_str, old_endp, new_endp);
- }
- /* transient error retry */
- return -1;
- }
- pim_msdp_pkt_rxed_with_fatal_error(mp);
- return -1;
- }
-
- if (!nbytes) {
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP peer %s read failed %d", mp->key_str, nbytes);
- }
- pim_msdp_peer_reset_tcp_conn(mp, "peer-down");
- return -1;
- }
-
- /* We read partial packet. */
- if (stream_get_endp(mp->ibuf) != mp->packet_size) {
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP peer %s read partial len %d old_endp %d new_endp %d", mp->key_str, mp->packet_size, old_endp, new_endp);
- }
- return -1;
- }
-
- return 0;
+ int nbytes;
+ int readsize;
+ int old_endp;
+ int new_endp;
+
+ old_endp = stream_get_endp(mp->ibuf);
+ readsize = mp->packet_size - old_endp;
+ if (!readsize) {
+ return 0;
+ }
+
+ /* Read packet from fd */
+ nbytes = stream_read_try(mp->ibuf, mp->fd, readsize);
+ new_endp = stream_get_endp(mp->ibuf);
+ if (nbytes < 0) {
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s read failed %d", mp->key_str,
+ nbytes);
+ }
+ if (nbytes == -2) {
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug(
+ "MSDP peer %s pim_msdp_read io retry old_end: %d new_end: %d",
+ mp->key_str, old_endp, new_endp);
+ }
+ /* transient error retry */
+ return -1;
+ }
+ pim_msdp_pkt_rxed_with_fatal_error(mp);
+ return -1;
+ }
+
+ if (!nbytes) {
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s read failed %d", mp->key_str,
+ nbytes);
+ }
+ pim_msdp_peer_reset_tcp_conn(mp, "peer-down");
+ return -1;
+ }
+
+ /* We read partial packet. */
+ if (stream_get_endp(mp->ibuf) != mp->packet_size) {
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug(
+ "MSDP peer %s read partial len %d old_endp %d new_endp %d",
+ mp->key_str, mp->packet_size, old_endp,
+ new_endp);
+ }
+ return -1;
+ }
+
+ return 0;
}
-int
-pim_msdp_read(struct thread *thread)
+int pim_msdp_read(struct thread *thread)
{
- struct pim_msdp_peer *mp;
- int rc;
- uint32_t len;
-
- mp = THREAD_ARG(thread);
- mp->t_read = NULL;
-
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP peer %s pim_msdp_read", mp->key_str);
- }
-
- if (mp->fd < 0) {
- return -1;
- }
-
- /* check if TCP connection is established */
- if (mp->state != PIM_MSDP_ESTABLISHED) {
- pim_msdp_connect_check(mp);
- return 0;
- }
-
- PIM_MSDP_PEER_READ_ON(mp);
-
- if (!mp->packet_size) {
- mp->packet_size = PIM_MSDP_HEADER_SIZE;
- }
-
- if (stream_get_endp(mp->ibuf) < PIM_MSDP_HEADER_SIZE) {
- /* start by reading the TLV header */
- rc = pim_msdp_read_packet(mp);
- if (rc < 0) {
- goto pim_msdp_read_end;
- }
-
- /* Find TLV type and len */
- stream_getc(mp->ibuf);
- len = stream_getw(mp->ibuf);
- if (len < PIM_MSDP_HEADER_SIZE) {
- pim_msdp_pkt_rxed_with_fatal_error(mp);
- goto pim_msdp_read_end;
- }
- /* read complete TLV */
- mp->packet_size = len;
- }
-
- rc = pim_msdp_read_packet(mp);
- if (rc < 0) {
- goto pim_msdp_read_end;
- }
-
- pim_msdp_pkt_rx(mp);
-
- /* reset input buffers and get ready for the next packet */
- mp->packet_size = 0;
- stream_reset(mp->ibuf);
+ struct pim_msdp_peer *mp;
+ int rc;
+ uint32_t len;
+
+ mp = THREAD_ARG(thread);
+ mp->t_read = NULL;
+
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s pim_msdp_read", mp->key_str);
+ }
+
+ if (mp->fd < 0) {
+ return -1;
+ }
+
+ /* check if TCP connection is established */
+ if (mp->state != PIM_MSDP_ESTABLISHED) {
+ pim_msdp_connect_check(mp);
+ return 0;
+ }
+
+ PIM_MSDP_PEER_READ_ON(mp);
+
+ if (!mp->packet_size) {
+ mp->packet_size = PIM_MSDP_HEADER_SIZE;
+ }
+
+ if (stream_get_endp(mp->ibuf) < PIM_MSDP_HEADER_SIZE) {
+ /* start by reading the TLV header */
+ rc = pim_msdp_read_packet(mp);
+ if (rc < 0) {
+ goto pim_msdp_read_end;
+ }
+
+ /* Find TLV type and len */
+ stream_getc(mp->ibuf);
+ len = stream_getw(mp->ibuf);
+ if (len < PIM_MSDP_HEADER_SIZE) {
+ pim_msdp_pkt_rxed_with_fatal_error(mp);
+ goto pim_msdp_read_end;
+ }
+ /* read complete TLV */
+ mp->packet_size = len;
+ }
+
+ rc = pim_msdp_read_packet(mp);
+ if (rc < 0) {
+ goto pim_msdp_read_end;
+ }
+
+ pim_msdp_pkt_rx(mp);
+
+ /* reset input buffers and get ready for the next packet */
+ mp->packet_size = 0;
+ stream_reset(mp->ibuf);
pim_msdp_read_end:
- return 0;
+ return 0;
}
diff --git a/pimd/pim_msdp_packet.h b/pimd/pim_msdp_packet.h
index aa42bbfe4..986fa3b32 100644
--- a/pimd/pim_msdp_packet.h
+++ b/pimd/pim_msdp_packet.h
@@ -50,8 +50,8 @@
#define PIM_MSDP_SA_X_SIZE 8
#define PIM_MSDP_SA_ONE_ENTRY_SIZE 12
#define PIM_MSDP_SA_Y_SIZE(entry_cnt) (PIM_MSDP_SA_ONE_ENTRY_SIZE * entry_cnt)
-#define PIM_MSDP_SA_ENTRY_CNT2SIZE(entry_cnt) (PIM_MSDP_SA_X_SIZE +\
- PIM_MSDP_SA_Y_SIZE(entry_cnt))
+#define PIM_MSDP_SA_ENTRY_CNT2SIZE(entry_cnt) \
+ (PIM_MSDP_SA_X_SIZE + PIM_MSDP_SA_Y_SIZE(entry_cnt))
/* SA TLV has to have atleast only one entry in it so x=8 + y=12 */
#define PIM_MSDP_SA_TLV_MIN_SIZE PIM_MSDP_SA_ENTRY_CNT2SIZE(1)
/* XXX: theoretically we can fix a max of 255 but that may result in packet
diff --git a/pimd/pim_msdp_socket.c b/pimd/pim_msdp_socket.c
index 9662f054e..0ce097101 100644
--- a/pimd/pim_msdp_socket.c
+++ b/pimd/pim_msdp_socket.c
@@ -31,199 +31,207 @@
#include "pim_msdp_socket.h"
/* increase socket send buffer size */
-static void
-pim_msdp_update_sock_send_buffer_size (int fd)
+static void pim_msdp_update_sock_send_buffer_size(int fd)
{
- int size = PIM_MSDP_SOCKET_SNDBUF_SIZE;
- int optval;
- socklen_t optlen = sizeof(optval);
-
- if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &optval, &optlen) < 0) {
- zlog_err("getsockopt of SO_SNDBUF failed %s\n", safe_strerror(errno));
- return;
- }
-
- if (optval < size) {
- if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) < 0) {
- zlog_err("Couldn't increase send buffer: %s\n", safe_strerror(errno));
- }
- }
+ int size = PIM_MSDP_SOCKET_SNDBUF_SIZE;
+ int optval;
+ socklen_t optlen = sizeof(optval);
+
+ if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &optval, &optlen) < 0) {
+ zlog_err("getsockopt of SO_SNDBUF failed %s\n",
+ safe_strerror(errno));
+ return;
+ }
+
+ if (optval < size) {
+ if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size))
+ < 0) {
+ zlog_err("Couldn't increase send buffer: %s\n",
+ safe_strerror(errno));
+ }
+ }
}
/* passive peer socket accept */
-static int
-pim_msdp_sock_accept(struct thread *thread)
+static int pim_msdp_sock_accept(struct thread *thread)
{
- union sockunion su;
- struct pim_msdp_listener *listener = THREAD_ARG(thread);
- int accept_sock;
- int msdp_sock;
- struct pim_msdp_peer *mp;
- char buf[SU_ADDRSTRLEN];
-
- sockunion_init(&su);
-
- /* re-register accept thread */
- accept_sock = THREAD_FD(thread);
- if (accept_sock < 0) {
- zlog_err ("accept_sock is negative value %d", accept_sock);
- return -1;
- }
- listener->thread = NULL;
- thread_add_read(master, pim_msdp_sock_accept, listener, accept_sock,
- &listener->thread);
-
- /* accept client connection. */
- msdp_sock = sockunion_accept(accept_sock, &su);
- if (msdp_sock < 0) {
- zlog_err ("pim_msdp_sock_accept failed (%s)", safe_strerror (errno));
- return -1;
- }
-
- /* see if have peer config for this */
- mp = pim_msdp_peer_find(su.sin.sin_addr);
- if (!mp || !PIM_MSDP_PEER_IS_LISTENER(mp)) {
- ++msdp->rejected_accepts;
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_err("msdp peer connection refused from %s",
- sockunion2str(&su, buf, SU_ADDRSTRLEN));
- }
- close(msdp_sock);
- return -1;
- }
-
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP peer %s accept success%s", mp->key_str, mp->fd>=0?"(dup)":"");
- }
-
- /* if we have an existing connection we need to kill that one
- * with this one */
- if (mp->fd >= 0) {
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_err("msdp peer new connection from %s stop old connection",
- sockunion2str(&su, buf, SU_ADDRSTRLEN));
- }
- pim_msdp_peer_stop_tcp_conn(mp, true /* chg_state */);
- }
- mp->fd = msdp_sock;
- set_nonblocking(mp->fd);
- pim_msdp_update_sock_send_buffer_size(mp->fd);
- pim_msdp_peer_established(mp);
- return 0;
+ union sockunion su;
+ struct pim_msdp_listener *listener = THREAD_ARG(thread);
+ int accept_sock;
+ int msdp_sock;
+ struct pim_msdp_peer *mp;
+ char buf[SU_ADDRSTRLEN];
+
+ sockunion_init(&su);
+
+ /* re-register accept thread */
+ accept_sock = THREAD_FD(thread);
+ if (accept_sock < 0) {
+ zlog_err("accept_sock is negative value %d", accept_sock);
+ return -1;
+ }
+ listener->thread = NULL;
+ thread_add_read(master, pim_msdp_sock_accept, listener, accept_sock,
+ &listener->thread);
+
+ /* accept client connection. */
+ msdp_sock = sockunion_accept(accept_sock, &su);
+ if (msdp_sock < 0) {
+ zlog_err("pim_msdp_sock_accept failed (%s)",
+ safe_strerror(errno));
+ return -1;
+ }
+
+ /* see if have peer config for this */
+ mp = pim_msdp_peer_find(su.sin.sin_addr);
+ if (!mp || !PIM_MSDP_PEER_IS_LISTENER(mp)) {
+ ++msdp->rejected_accepts;
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_err("msdp peer connection refused from %s",
+ sockunion2str(&su, buf, SU_ADDRSTRLEN));
+ }
+ close(msdp_sock);
+ return -1;
+ }
+
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s accept success%s", mp->key_str,
+ mp->fd >= 0 ? "(dup)" : "");
+ }
+
+ /* if we have an existing connection we need to kill that one
+ * with this one */
+ if (mp->fd >= 0) {
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_err(
+ "msdp peer new connection from %s stop old connection",
+ sockunion2str(&su, buf, SU_ADDRSTRLEN));
+ }
+ pim_msdp_peer_stop_tcp_conn(mp, true /* chg_state */);
+ }
+ mp->fd = msdp_sock;
+ set_nonblocking(mp->fd);
+ pim_msdp_update_sock_send_buffer_size(mp->fd);
+ pim_msdp_peer_established(mp);
+ return 0;
}
/* global listener for the MSDP well know TCP port */
-int
-pim_msdp_sock_listen(void)
+int pim_msdp_sock_listen(void)
{
- int sock;
- int socklen;
- struct sockaddr_in sin;
- int rc;
- struct pim_msdp_listener *listener = &msdp->listener;
-
- if (msdp->flags & PIM_MSDPF_LISTENER) {
- /* listener already setup */
- return 0;
- }
-
- sock = socket(AF_INET, SOCK_STREAM, 0);
- if (sock < 0) {
- zlog_err ("socket: %s", safe_strerror (errno));
- return sock;
- }
-
- memset(&sin, 0, sizeof(struct sockaddr_in));
- sin.sin_family = AF_INET;
- sin.sin_port = htons(PIM_MSDP_TCP_PORT);
- socklen = sizeof(struct sockaddr_in);
+ int sock;
+ int socklen;
+ struct sockaddr_in sin;
+ int rc;
+ struct pim_msdp_listener *listener = &msdp->listener;
+
+ if (msdp->flags & PIM_MSDPF_LISTENER) {
+ /* listener already setup */
+ return 0;
+ }
+
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (sock < 0) {
+ zlog_err("socket: %s", safe_strerror(errno));
+ return sock;
+ }
+
+ memset(&sin, 0, sizeof(struct sockaddr_in));
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(PIM_MSDP_TCP_PORT);
+ socklen = sizeof(struct sockaddr_in);
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
- sin.sin_len = socklen;
+ sin.sin_len = socklen;
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
- sockopt_reuseaddr(sock);
- sockopt_reuseport(sock);
-
- if (pimd_privs.change(ZPRIVS_RAISE)) {
- zlog_err ("pim_msdp_socket: could not raise privs, %s",
- safe_strerror (errno));
- }
-
- /* bind to well known TCP port */
- rc = bind(sock, (struct sockaddr *)&sin, socklen);
-
- if (pimd_privs.change(ZPRIVS_LOWER)) {
- zlog_err ("pim_msdp_socket: could not lower privs, %s",
- safe_strerror (errno));
- }
-
- if (rc < 0) {
- zlog_err ("pim_msdp_socket bind to port %d: %s", ntohs(sin.sin_port), safe_strerror (errno));
- close(sock);
- return rc;
- }
-
- rc = listen(sock, 3 /* backlog */);
- if (rc < 0) {
- zlog_err ("pim_msdp_socket listen: %s", safe_strerror (errno));
- close(sock);
- return rc;
- }
-
- /* add accept thread */
- listener->fd = sock;
- memcpy(&listener->su, &sin, socklen);
- listener->thread = NULL;
- thread_add_read(msdp->master, pim_msdp_sock_accept, listener, sock,
- &listener->thread);
-
- msdp->flags |= PIM_MSDPF_LISTENER;
- return 0;
+ sockopt_reuseaddr(sock);
+ sockopt_reuseport(sock);
+
+ if (pimd_privs.change(ZPRIVS_RAISE)) {
+ zlog_err("pim_msdp_socket: could not raise privs, %s",
+ safe_strerror(errno));
+ }
+
+ /* bind to well known TCP port */
+ rc = bind(sock, (struct sockaddr *)&sin, socklen);
+
+ if (pimd_privs.change(ZPRIVS_LOWER)) {
+ zlog_err("pim_msdp_socket: could not lower privs, %s",
+ safe_strerror(errno));
+ }
+
+ if (rc < 0) {
+ zlog_err("pim_msdp_socket bind to port %d: %s",
+ ntohs(sin.sin_port), safe_strerror(errno));
+ close(sock);
+ return rc;
+ }
+
+ rc = listen(sock, 3 /* backlog */);
+ if (rc < 0) {
+ zlog_err("pim_msdp_socket listen: %s", safe_strerror(errno));
+ close(sock);
+ return rc;
+ }
+
+ /* add accept thread */
+ listener->fd = sock;
+ memcpy(&listener->su, &sin, socklen);
+ listener->thread = NULL;
+ thread_add_read(msdp->master, pim_msdp_sock_accept, listener, sock,
+ &listener->thread);
+
+ msdp->flags |= PIM_MSDPF_LISTENER;
+ return 0;
}
/* active peer socket setup */
-int
-pim_msdp_sock_connect(struct pim_msdp_peer *mp)
+int pim_msdp_sock_connect(struct pim_msdp_peer *mp)
{
- int rc;
-
- if (PIM_DEBUG_MSDP_INTERNAL) {
- zlog_debug("MSDP peer %s attempt connect%s", mp->key_str, mp->fd<0?"":"(dup)");
- }
-
- /* if we have an existing connection we need to kill that one
- * with this one */
- if (mp->fd >= 0) {
- if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_err("msdp duplicate connect to %s nuke old connection", mp->key_str);
- }
- pim_msdp_peer_stop_tcp_conn(mp, false /* chg_state */);
- }
-
- /* Make socket for the peer. */
- mp->fd = sockunion_socket(&mp->su_peer);
- if (mp->fd < 0) {
- zlog_err ("pim_msdp_socket socket failure: %s", safe_strerror (errno));
- return -1;
- }
-
- set_nonblocking(mp->fd);
-
- /* Set socket send buffer size */
- pim_msdp_update_sock_send_buffer_size(mp->fd);
- sockopt_reuseaddr(mp->fd);
- sockopt_reuseport(mp->fd);
-
- /* source bind */
- rc = sockunion_bind(mp->fd, &mp->su_local, 0, &mp->su_local);
- if (rc < 0) {
- zlog_err ("pim_msdp_socket connect bind failure: %s", safe_strerror (errno));
- close(mp->fd);
- mp->fd = -1;
- return rc;
- }
-
- /* Connect to the remote mp. */
- return (sockunion_connect(mp->fd, &mp->su_peer, htons(PIM_MSDP_TCP_PORT), 0));
+ int rc;
+
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ zlog_debug("MSDP peer %s attempt connect%s", mp->key_str,
+ mp->fd < 0 ? "" : "(dup)");
+ }
+
+ /* if we have an existing connection we need to kill that one
+ * with this one */
+ if (mp->fd >= 0) {
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ zlog_err(
+ "msdp duplicate connect to %s nuke old connection",
+ mp->key_str);
+ }
+ pim_msdp_peer_stop_tcp_conn(mp, false /* chg_state */);
+ }
+
+ /* Make socket for the peer. */
+ mp->fd = sockunion_socket(&mp->su_peer);
+ if (mp->fd < 0) {
+ zlog_err("pim_msdp_socket socket failure: %s",
+ safe_strerror(errno));
+ return -1;
+ }
+
+ set_nonblocking(mp->fd);
+
+ /* Set socket send buffer size */
+ pim_msdp_update_sock_send_buffer_size(mp->fd);
+ sockopt_reuseaddr(mp->fd);
+ sockopt_reuseport(mp->fd);
+
+ /* source bind */
+ rc = sockunion_bind(mp->fd, &mp->su_local, 0, &mp->su_local);
+ if (rc < 0) {
+ zlog_err("pim_msdp_socket connect bind failure: %s",
+ safe_strerror(errno));
+ close(mp->fd);
+ mp->fd = -1;
+ return rc;
+ }
+
+ /* Connect to the remote mp. */
+ return (sockunion_connect(mp->fd, &mp->su_peer,
+ htons(PIM_MSDP_TCP_PORT), 0));
}
-
diff --git a/pimd/pim_msg.c b/pimd/pim_msg.c
index e077a8516..04f1f4846 100644
--- a/pimd/pim_msg.c
+++ b/pimd/pim_msg.c
@@ -37,197 +37,202 @@
#include "pim_register.h"
#include "pim_jp_agg.h"
-void pim_msg_build_header(uint8_t *pim_msg, size_t pim_msg_size, uint8_t pim_msg_type)
+void pim_msg_build_header(uint8_t *pim_msg, size_t pim_msg_size,
+ uint8_t pim_msg_type)
{
- struct pim_msg_header *header = (struct pim_msg_header *)pim_msg;
-
- /*
- * Write header
- */
- header->ver = PIM_PROTO_VERSION;
- header->type = pim_msg_type;
- header->reserved = 0;
-
-
- header->checksum = 0;
- /*
- * The checksum for Registers is done only on the first 8 bytes of the packet,
- * including the PIM header and the next 4 bytes, excluding the data packet portion
- */
- if (pim_msg_type == PIM_MSG_TYPE_REGISTER)
- header->checksum = in_cksum (pim_msg, PIM_MSG_REGISTER_LEN);
- else
- header->checksum = in_cksum (pim_msg, pim_msg_size);
+ struct pim_msg_header *header = (struct pim_msg_header *)pim_msg;
+
+ /*
+ * Write header
+ */
+ header->ver = PIM_PROTO_VERSION;
+ header->type = pim_msg_type;
+ header->reserved = 0;
+
+
+ header->checksum = 0;
+ /*
+ * The checksum for Registers is done only on the first 8 bytes of the
+ * packet,
+ * including the PIM header and the next 4 bytes, excluding the data
+ * packet portion
+ */
+ if (pim_msg_type == PIM_MSG_TYPE_REGISTER)
+ header->checksum = in_cksum(pim_msg, PIM_MSG_REGISTER_LEN);
+ else
+ header->checksum = in_cksum(pim_msg, pim_msg_size);
}
uint8_t *pim_msg_addr_encode_ipv4_ucast(uint8_t *buf, struct in_addr addr)
{
- buf[0] = PIM_MSG_ADDRESS_FAMILY_IPV4; /* addr family */
- buf[1] = '\0'; /* native encoding */
- memcpy(buf+2, &addr, sizeof(struct in_addr));
+ buf[0] = PIM_MSG_ADDRESS_FAMILY_IPV4; /* addr family */
+ buf[1] = '\0'; /* native encoding */
+ memcpy(buf + 2, &addr, sizeof(struct in_addr));
- return buf + PIM_ENCODED_IPV4_UCAST_SIZE;
+ return buf + PIM_ENCODED_IPV4_UCAST_SIZE;
}
uint8_t *pim_msg_addr_encode_ipv4_group(uint8_t *buf, struct in_addr addr)
{
- buf[0] = PIM_MSG_ADDRESS_FAMILY_IPV4; /* addr family */
- buf[1] = '\0'; /* native encoding */
- buf[2] = '\0'; /* reserved */
- buf[3] = 32; /* mask len */
- memcpy(buf+4, &addr, sizeof(struct in_addr));
+ buf[0] = PIM_MSG_ADDRESS_FAMILY_IPV4; /* addr family */
+ buf[1] = '\0'; /* native encoding */
+ buf[2] = '\0'; /* reserved */
+ buf[3] = 32; /* mask len */
+ memcpy(buf + 4, &addr, sizeof(struct in_addr));
- return buf + PIM_ENCODED_IPV4_GROUP_SIZE;
+ return buf + PIM_ENCODED_IPV4_GROUP_SIZE;
}
-uint8_t *
-pim_msg_addr_encode_ipv4_source(uint8_t *buf,
- struct in_addr addr, uint8_t bits)
+uint8_t *pim_msg_addr_encode_ipv4_source(uint8_t *buf, struct in_addr addr,
+ uint8_t bits)
{
- buf[0] = PIM_MSG_ADDRESS_FAMILY_IPV4; /* addr family */
- buf[1] = '\0'; /* native encoding */
- buf[2] = bits;
- buf[3] = 32; /* mask len */
- memcpy(buf+4, &addr, sizeof(struct in_addr));
+ buf[0] = PIM_MSG_ADDRESS_FAMILY_IPV4; /* addr family */
+ buf[1] = '\0'; /* native encoding */
+ buf[2] = bits;
+ buf[3] = 32; /* mask len */
+ memcpy(buf + 4, &addr, sizeof(struct in_addr));
- return buf + PIM_ENCODED_IPV4_SOURCE_SIZE;
+ return buf + PIM_ENCODED_IPV4_SOURCE_SIZE;
}
/*
* For the given 'struct pim_jp_sources' list
* determine the size_t it would take up.
*/
-size_t
-pim_msg_get_jp_group_size (struct list *sources)
+size_t pim_msg_get_jp_group_size(struct list *sources)
{
- struct pim_jp_sources *js;
- size_t size = 0;
-
- size += sizeof (struct pim_encoded_group_ipv4);
- size += 4; // Joined sources (2) + Pruned Sources (2)
-
- size += sizeof (struct pim_encoded_source_ipv4) * sources->count;
-
- js = listgetdata(listhead(sources));
- if (js && js->up->sg.src.s_addr == INADDR_ANY)
- {
- struct pim_upstream *child, *up;
- struct listnode *up_node;
-
- up = js->up;
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug ("%s: Considering (%s) children for (S,G,rpt) prune",
- __PRETTY_FUNCTION__, up->sg_str);
-
- for (ALL_LIST_ELEMENTS_RO (up->sources, up_node, child))
- {
- if (child->sptbit == PIM_UPSTREAM_SPTBIT_TRUE)
- {
- if (!pim_rpf_is_same(&up->rpf, &child->rpf))
- {
- size += sizeof (struct pim_encoded_source_ipv4);
- PIM_UPSTREAM_FLAG_SET_SEND_SG_RPT_PRUNE(child->flags);
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug ("%s: SPT Bit and RPF'(%s) != RPF'(S,G): Add Prune (%s,rpt) to compound message",
- __PRETTY_FUNCTION__, up->sg_str, child->sg_str);
- }
- else
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug ("%s: SPT Bit and RPF'(%s) == RPF'(S,G): Not adding Prune for (%s,rpt)",
- __PRETTY_FUNCTION__, up->sg_str, child->sg_str);
- }
- else if (pim_upstream_is_sg_rpt (child))
- {
- if (pim_upstream_empty_inherited_olist (child))
- {
- size += sizeof (struct pim_encoded_source_ipv4);
- PIM_UPSTREAM_FLAG_SET_SEND_SG_RPT_PRUNE(child->flags);
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug ("%s: inherited_olist(%s,rpt) is NULL, Add Prune to compound message",
- __PRETTY_FUNCTION__, child->sg_str);
- }
- else if (!pim_rpf_is_same (&up->rpf, &child->rpf))
- {
- size += sizeof (struct pim_encoded_source_ipv4);
- PIM_UPSTREAM_FLAG_SET_SEND_SG_RPT_PRUNE(child->flags);
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug ("%s: RPF'(%s) != RPF'(%s,rpt), Add Prune to compound message",
- __PRETTY_FUNCTION__, up->sg_str, child->sg_str);
- }
- else
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug ("%s: RPF'(%s) == RPF'(%s,rpt), Do not add Prune to compound message",
- __PRETTY_FUNCTION__, up->sg_str, child->sg_str);
- }
- else
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug ("%s: SPT bit is not set for (%s)",
- __PRETTY_FUNCTION__, child->sg_str);
- }
- }
- return size;
+ struct pim_jp_sources *js;
+ size_t size = 0;
+
+ size += sizeof(struct pim_encoded_group_ipv4);
+ size += 4; // Joined sources (2) + Pruned Sources (2)
+
+ size += sizeof(struct pim_encoded_source_ipv4) * sources->count;
+
+ js = listgetdata(listhead(sources));
+ if (js && js->up->sg.src.s_addr == INADDR_ANY) {
+ struct pim_upstream *child, *up;
+ struct listnode *up_node;
+
+ up = js->up;
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "%s: Considering (%s) children for (S,G,rpt) prune",
+ __PRETTY_FUNCTION__, up->sg_str);
+
+ for (ALL_LIST_ELEMENTS_RO(up->sources, up_node, child)) {
+ if (child->sptbit == PIM_UPSTREAM_SPTBIT_TRUE) {
+ if (!pim_rpf_is_same(&up->rpf, &child->rpf)) {
+ size += sizeof(
+ struct pim_encoded_source_ipv4);
+ PIM_UPSTREAM_FLAG_SET_SEND_SG_RPT_PRUNE(
+ child->flags);
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "%s: SPT Bit and RPF'(%s) != RPF'(S,G): Add Prune (%s,rpt) to compound message",
+ __PRETTY_FUNCTION__,
+ up->sg_str,
+ child->sg_str);
+ } else if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "%s: SPT Bit and RPF'(%s) == RPF'(S,G): Not adding Prune for (%s,rpt)",
+ __PRETTY_FUNCTION__, up->sg_str,
+ child->sg_str);
+ } else if (pim_upstream_is_sg_rpt(child)) {
+ if (pim_upstream_empty_inherited_olist(child)) {
+ size += sizeof(
+ struct pim_encoded_source_ipv4);
+ PIM_UPSTREAM_FLAG_SET_SEND_SG_RPT_PRUNE(
+ child->flags);
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "%s: inherited_olist(%s,rpt) is NULL, Add Prune to compound message",
+ __PRETTY_FUNCTION__,
+ child->sg_str);
+ } else if (!pim_rpf_is_same(&up->rpf,
+ &child->rpf)) {
+ size += sizeof(
+ struct pim_encoded_source_ipv4);
+ PIM_UPSTREAM_FLAG_SET_SEND_SG_RPT_PRUNE(
+ child->flags);
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "%s: RPF'(%s) != RPF'(%s,rpt), Add Prune to compound message",
+ __PRETTY_FUNCTION__,
+ up->sg_str,
+ child->sg_str);
+ } else if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "%s: RPF'(%s) == RPF'(%s,rpt), Do not add Prune to compound message",
+ __PRETTY_FUNCTION__, up->sg_str,
+ child->sg_str);
+ } else if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug("%s: SPT bit is not set for (%s)",
+ __PRETTY_FUNCTION__, child->sg_str);
+ }
+ }
+ return size;
}
-size_t
-pim_msg_build_jp_groups (struct pim_jp_groups *grp, struct pim_jp_agg_group *sgs, size_t size)
+size_t pim_msg_build_jp_groups(struct pim_jp_groups *grp,
+ struct pim_jp_agg_group *sgs, size_t size)
{
- struct listnode *node, *nnode;
- struct pim_jp_sources *source;
- struct pim_upstream *up = NULL;
- struct in_addr stosend;
- uint8_t bits;
- uint8_t tgroups = 0;
-
- memset (grp, 0, size);
- pim_msg_addr_encode_ipv4_group ((uint8_t *)&grp->g, sgs->group);
-
- for (ALL_LIST_ELEMENTS(sgs->sources, node, nnode, source))
- {
- /* number of joined/pruned sources */
- if (source->is_join)
- grp->joins++;
- else
- grp->prunes++;
-
- if (source->up->sg.src.s_addr == INADDR_ANY)
- {
- struct pim_rpf *rpf = pim_rp_g (source->up->sg.grp);
- bits = PIM_ENCODE_SPARSE_BIT | PIM_ENCODE_WC_BIT | PIM_ENCODE_RPT_BIT;
- stosend = rpf->rpf_addr.u.prefix4;
- /* Only Send SGRpt in case of *,G Join */
- if (source->is_join)
- up = source->up;
- }
- else
- {
- bits = PIM_ENCODE_SPARSE_BIT;
- stosend = source->up->sg.src;
- }
-
- pim_msg_addr_encode_ipv4_source ((uint8_t *)&grp->s[tgroups], stosend, bits);
- tgroups++;
- }
-
- if (up)
- {
- struct pim_upstream *child;
-
- for (ALL_LIST_ELEMENTS(up->sources, node, nnode, child))
- {
- if (PIM_UPSTREAM_FLAG_TEST_SEND_SG_RPT_PRUNE(child->flags))
- {
- pim_msg_addr_encode_ipv4_source ((uint8_t *)&grp->s[tgroups],
- child->sg.src,
- PIM_ENCODE_SPARSE_BIT | PIM_ENCODE_RPT_BIT);
- tgroups++;
- PIM_UPSTREAM_FLAG_UNSET_SEND_SG_RPT_PRUNE(child->flags);
- grp->prunes++;
- }
- }
- }
-
- grp->joins = htons(grp->joins);
- grp->prunes = htons(grp->prunes);
-
- return size;
+ struct listnode *node, *nnode;
+ struct pim_jp_sources *source;
+ struct pim_upstream *up = NULL;
+ struct in_addr stosend;
+ uint8_t bits;
+ uint8_t tgroups = 0;
+
+ memset(grp, 0, size);
+ pim_msg_addr_encode_ipv4_group((uint8_t *)&grp->g, sgs->group);
+
+ for (ALL_LIST_ELEMENTS(sgs->sources, node, nnode, source)) {
+ /* number of joined/pruned sources */
+ if (source->is_join)
+ grp->joins++;
+ else
+ grp->prunes++;
+
+ if (source->up->sg.src.s_addr == INADDR_ANY) {
+ struct pim_rpf *rpf = pim_rp_g(source->up->sg.grp);
+ bits = PIM_ENCODE_SPARSE_BIT | PIM_ENCODE_WC_BIT
+ | PIM_ENCODE_RPT_BIT;
+ stosend = rpf->rpf_addr.u.prefix4;
+ /* Only Send SGRpt in case of *,G Join */
+ if (source->is_join)
+ up = source->up;
+ } else {
+ bits = PIM_ENCODE_SPARSE_BIT;
+ stosend = source->up->sg.src;
+ }
+
+ pim_msg_addr_encode_ipv4_source((uint8_t *)&grp->s[tgroups],
+ stosend, bits);
+ tgroups++;
+ }
+
+ if (up) {
+ struct pim_upstream *child;
+
+ for (ALL_LIST_ELEMENTS(up->sources, node, nnode, child)) {
+ if (PIM_UPSTREAM_FLAG_TEST_SEND_SG_RPT_PRUNE(
+ child->flags)) {
+ pim_msg_addr_encode_ipv4_source(
+ (uint8_t *)&grp->s[tgroups],
+ child->sg.src,
+ PIM_ENCODE_SPARSE_BIT
+ | PIM_ENCODE_RPT_BIT);
+ tgroups++;
+ PIM_UPSTREAM_FLAG_UNSET_SEND_SG_RPT_PRUNE(
+ child->flags);
+ grp->prunes++;
+ }
+ }
+ }
+
+ grp->joins = htons(grp->joins);
+ grp->prunes = htons(grp->prunes);
+
+ return size;
}
diff --git a/pimd/pim_msg.h b/pimd/pim_msg.h
index 38ffaf6a7..ad9b5d9c0 100644
--- a/pimd/pim_msg.h
+++ b/pimd/pim_msg.h
@@ -24,7 +24,7 @@
#include "pim_jp_agg.h"
/*
- Number Description
+ Number Description
---------- ------------------
0 Reserved
1 IP (IP version 4)
@@ -34,70 +34,72 @@
http://www.iana.org/assignments/address-family-numbers
*/
enum pim_msg_address_family {
- PIM_MSG_ADDRESS_FAMILY_RESERVED,
- PIM_MSG_ADDRESS_FAMILY_IPV4,
- PIM_MSG_ADDRESS_FAMILY_IPV6,
+ PIM_MSG_ADDRESS_FAMILY_RESERVED,
+ PIM_MSG_ADDRESS_FAMILY_IPV4,
+ PIM_MSG_ADDRESS_FAMILY_IPV6,
};
/*
* Network Order pim_msg_hdr
*/
struct pim_msg_header {
- uint8_t type:4;
- uint8_t ver:4;
- uint8_t reserved;
- uint16_t checksum;
-} __attribute__ ((packed));
+ uint8_t type : 4;
+ uint8_t ver : 4;
+ uint8_t reserved;
+ uint16_t checksum;
+} __attribute__((packed));
struct pim_encoded_ipv4_unicast {
- uint8_t family;
- uint8_t reserved;
- struct in_addr addr;
-} __attribute__ ((packed));
+ uint8_t family;
+ uint8_t reserved;
+ struct in_addr addr;
+} __attribute__((packed));
struct pim_encoded_group_ipv4 {
- uint8_t ne;
- uint8_t family;
- uint8_t reserved;
- uint8_t mask;
- struct in_addr addr;
-} __attribute__ ((packed));
+ uint8_t ne;
+ uint8_t family;
+ uint8_t reserved;
+ uint8_t mask;
+ struct in_addr addr;
+} __attribute__((packed));
struct pim_encoded_source_ipv4 {
- uint8_t ne;
- uint8_t family;
- uint8_t bits;
- uint8_t mask;
- struct in_addr addr;
-} __attribute__ ((packed));
+ uint8_t ne;
+ uint8_t family;
+ uint8_t bits;
+ uint8_t mask;
+ struct in_addr addr;
+} __attribute__((packed));
struct pim_jp_groups {
- struct pim_encoded_group_ipv4 g;
- uint16_t joins;
- uint16_t prunes;
- struct pim_encoded_source_ipv4 s[1];
-} __attribute__ ((packed));
+ struct pim_encoded_group_ipv4 g;
+ uint16_t joins;
+ uint16_t prunes;
+ struct pim_encoded_source_ipv4 s[1];
+} __attribute__((packed));
struct pim_jp {
- struct pim_msg_header header;
- struct pim_encoded_ipv4_unicast addr;
- uint8_t reserved;
- uint8_t num_groups;
- uint16_t holdtime;
- struct pim_jp_groups groups[1];
-} __attribute__ ((packed));
+ struct pim_msg_header header;
+ struct pim_encoded_ipv4_unicast addr;
+ uint8_t reserved;
+ uint8_t num_groups;
+ uint16_t holdtime;
+ struct pim_jp_groups groups[1];
+} __attribute__((packed));
-void pim_msg_build_header(uint8_t *pim_msg, size_t pim_msg_size, uint8_t pim_msg_type);
+void pim_msg_build_header(uint8_t *pim_msg, size_t pim_msg_size,
+ uint8_t pim_msg_type);
uint8_t *pim_msg_addr_encode_ipv4_ucast(uint8_t *buf, struct in_addr addr);
uint8_t *pim_msg_addr_encode_ipv4_group(uint8_t *buf, struct in_addr addr);
#define PIM_ENCODE_SPARSE_BIT 0x04
#define PIM_ENCODE_WC_BIT 0x02
#define PIM_ENCODE_RPT_BIT 0x01
-uint8_t *pim_msg_addr_encode_ipv4_source(uint8_t *buf,
- struct in_addr addr, uint8_t bits);
+uint8_t *pim_msg_addr_encode_ipv4_source(uint8_t *buf, struct in_addr addr,
+ uint8_t bits);
-size_t pim_msg_get_jp_group_size (struct list *sources);
-size_t pim_msg_build_jp_groups (struct pim_jp_groups *grp, struct pim_jp_agg_group *sgs, size_t size);
+size_t pim_msg_get_jp_group_size(struct list *sources);
+size_t pim_msg_build_jp_groups(struct pim_jp_groups *grp,
+ struct pim_jp_agg_group *sgs, size_t size);
#endif /* PIM_MSG_H */
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;
}
diff --git a/pimd/pim_neighbor.h b/pimd/pim_neighbor.h
index eaaefd8fe..a4f2e10c8 100644
--- a/pimd/pim_neighbor.h
+++ b/pimd/pim_neighbor.h
@@ -29,54 +29,46 @@
#include "pim_tlv.h"
struct pim_neighbor {
- int64_t creation; /* timestamp of creation */
- struct in_addr source_addr;
- pim_hello_options hello_options;
- uint16_t holdtime;
- uint16_t propagation_delay_msec;
- uint16_t override_interval_msec;
- uint32_t dr_priority;
- uint32_t generation_id;
- struct list *prefix_list; /* list of struct prefix */
- struct thread *t_expire_timer;
- struct interface *interface;
+ int64_t creation; /* timestamp of creation */
+ struct in_addr source_addr;
+ pim_hello_options hello_options;
+ uint16_t holdtime;
+ uint16_t propagation_delay_msec;
+ uint16_t override_interval_msec;
+ uint32_t dr_priority;
+ uint32_t generation_id;
+ struct list *prefix_list; /* list of struct prefix */
+ struct thread *t_expire_timer;
+ struct interface *interface;
- struct thread *jp_timer;
- struct list *upstream_jp_agg;
- struct bfd_info *bfd_info;
+ struct thread *jp_timer;
+ struct list *upstream_jp_agg;
+ struct bfd_info *bfd_info;
};
void pim_neighbor_timer_reset(struct pim_neighbor *neigh, uint16_t holdtime);
void pim_neighbor_free(struct pim_neighbor *neigh);
struct pim_neighbor *pim_neighbor_find(struct interface *ifp,
struct in_addr source_addr);
-struct pim_neighbor *pim_neighbor_find_by_secondary (struct interface *ifp,
- struct prefix *src);
-struct pim_neighbor *pim_neighbor_find_if (struct interface *ifp);
+struct pim_neighbor *pim_neighbor_find_by_secondary(struct interface *ifp,
+ struct prefix *src);
+struct pim_neighbor *pim_neighbor_find_if(struct interface *ifp);
#define PIM_NEIGHBOR_SEND_DELAY 0
#define PIM_NEIGHBOR_SEND_NOW 1
-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);
-void pim_neighbor_delete(struct interface *ifp,
- struct pim_neighbor *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);
+void pim_neighbor_delete(struct interface *ifp, struct pim_neighbor *neigh,
const char *delete_message);
-void pim_neighbor_delete_all(struct interface *ifp,
- const char *delete_message);
+void pim_neighbor_delete_all(struct interface *ifp, const char *delete_message);
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 prefix *pim_neighbor_find_secondary(struct pim_neighbor *neigh,
struct prefix *addr);
int pim_if_dr_election(struct interface *ifp);
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c
index 4aa6ecd5f..f8bf2ac77 100644
--- a/pimd/pim_nht.c
+++ b/pimd/pim_nht.c
@@ -44,258 +44,247 @@
* pim_sendmsg_zebra_rnh -- Format and send a nexthop register/Unregister
* command to Zebra.
*/
-void
-pim_sendmsg_zebra_rnh (struct zclient *zclient, struct pim_nexthop_cache *pnc,
- int command)
+void pim_sendmsg_zebra_rnh(struct zclient *zclient,
+ struct pim_nexthop_cache *pnc, int command)
{
- struct stream *s;
- struct prefix *p;
- int ret;
-
- /* Check socket. */
- if (!zclient || zclient->sock < 0)
- return;
-
- p = &(pnc->rpf.rpf_addr);
- s = zclient->obuf;
- stream_reset (s);
- zclient_create_header (s, command, VRF_DEFAULT);
- /* get update for all routes for a prefix */
- stream_putc (s, 0);
-
- stream_putw (s, PREFIX_FAMILY (p));
- stream_putc (s, p->prefixlen);
- switch (PREFIX_FAMILY (p))
- {
- case AF_INET:
- stream_put_in_addr (s, &p->u.prefix4);
- break;
- case AF_INET6:
- stream_put (s, &(p->u.prefix6), 16);
- break;
- default:
- break;
- }
- stream_putw_at (s, 0, stream_get_endp (s));
-
- ret = zclient_send_message (zclient);
- if (ret < 0)
- zlog_warn ("sendmsg_nexthop: zclient_send_message() failed");
-
-
- if (PIM_DEBUG_TRACE)
- {
- char buf[PREFIX2STR_BUFFER];
- prefix2str (p, buf, sizeof (buf));
- zlog_debug ("%s: NHT %sregistered addr %s with Zebra ret:%d ",
- __PRETTY_FUNCTION__,
- (command == ZEBRA_NEXTHOP_REGISTER) ? " " : "de", buf, ret);
- }
-
- return;
+ struct stream *s;
+ struct prefix *p;
+ int ret;
+
+ /* Check socket. */
+ if (!zclient || zclient->sock < 0)
+ return;
+
+ p = &(pnc->rpf.rpf_addr);
+ s = zclient->obuf;
+ stream_reset(s);
+ zclient_create_header(s, command, VRF_DEFAULT);
+ /* get update for all routes for a prefix */
+ stream_putc(s, 0);
+
+ stream_putw(s, PREFIX_FAMILY(p));
+ stream_putc(s, p->prefixlen);
+ switch (PREFIX_FAMILY(p)) {
+ case AF_INET:
+ stream_put_in_addr(s, &p->u.prefix4);
+ break;
+ case AF_INET6:
+ stream_put(s, &(p->u.prefix6), 16);
+ break;
+ default:
+ break;
+ }
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ ret = zclient_send_message(zclient);
+ if (ret < 0)
+ zlog_warn("sendmsg_nexthop: zclient_send_message() failed");
+
+
+ if (PIM_DEBUG_TRACE) {
+ char buf[PREFIX2STR_BUFFER];
+ prefix2str(p, buf, sizeof(buf));
+ zlog_debug("%s: NHT %sregistered addr %s with Zebra ret:%d ",
+ __PRETTY_FUNCTION__,
+ (command == ZEBRA_NEXTHOP_REGISTER) ? " " : "de",
+ buf, ret);
+ }
+
+ return;
}
-struct pim_nexthop_cache *
-pim_nexthop_cache_find (struct pim_rpf *rpf)
+struct pim_nexthop_cache *pim_nexthop_cache_find(struct pim_rpf *rpf)
{
- struct pim_nexthop_cache *pnc = NULL;
- struct pim_nexthop_cache lookup;
+ struct pim_nexthop_cache *pnc = NULL;
+ struct pim_nexthop_cache lookup;
- lookup.rpf.rpf_addr.family = rpf->rpf_addr.family;
- lookup.rpf.rpf_addr.prefixlen = rpf->rpf_addr.prefixlen;
- lookup.rpf.rpf_addr.u.prefix4.s_addr = rpf->rpf_addr.u.prefix4.s_addr;
+ lookup.rpf.rpf_addr.family = rpf->rpf_addr.family;
+ lookup.rpf.rpf_addr.prefixlen = rpf->rpf_addr.prefixlen;
+ lookup.rpf.rpf_addr.u.prefix4.s_addr = rpf->rpf_addr.u.prefix4.s_addr;
- pnc = hash_lookup (pimg->rpf_hash, &lookup);
-
- return pnc;
+ pnc = hash_lookup(pimg->rpf_hash, &lookup);
+ return pnc;
}
-struct pim_nexthop_cache *
-pim_nexthop_cache_add (struct pim_rpf *rpf_addr)
+struct pim_nexthop_cache *pim_nexthop_cache_add(struct pim_rpf *rpf_addr)
{
- struct pim_nexthop_cache *pnc;
-
- pnc = XCALLOC (MTYPE_PIM_NEXTHOP_CACHE, sizeof (struct pim_nexthop_cache));
- if (!pnc)
- {
- zlog_err ("%s: NHT PIM XCALLOC failure ", __PRETTY_FUNCTION__);
- return NULL;
- }
- pnc->rpf.rpf_addr.family = rpf_addr->rpf_addr.family;
- pnc->rpf.rpf_addr.prefixlen = rpf_addr->rpf_addr.prefixlen;
- pnc->rpf.rpf_addr.u.prefix4.s_addr = rpf_addr->rpf_addr.u.prefix4.s_addr;
-
- pnc = hash_get (pimg->rpf_hash, pnc, hash_alloc_intern);
-
- pnc->rp_list = list_new ();
- pnc->rp_list->cmp = pim_rp_list_cmp;
-
- pnc->upstream_list = list_new ();
- pnc->upstream_list->cmp = pim_upstream_compare;
-
- if (PIM_DEBUG_ZEBRA)
- {
- char rpf_str[PREFIX_STRLEN];
- pim_addr_dump ("<nht?>", &rpf_addr->rpf_addr, rpf_str,
- sizeof (rpf_str));
- zlog_debug ("%s: NHT hash node, RP and UP lists allocated for %s ",
- __PRETTY_FUNCTION__, rpf_str);
- }
-
- return pnc;
+ struct pim_nexthop_cache *pnc;
+
+ pnc = XCALLOC(MTYPE_PIM_NEXTHOP_CACHE,
+ sizeof(struct pim_nexthop_cache));
+ if (!pnc) {
+ zlog_err("%s: NHT PIM XCALLOC failure ", __PRETTY_FUNCTION__);
+ return NULL;
+ }
+ pnc->rpf.rpf_addr.family = rpf_addr->rpf_addr.family;
+ pnc->rpf.rpf_addr.prefixlen = rpf_addr->rpf_addr.prefixlen;
+ pnc->rpf.rpf_addr.u.prefix4.s_addr =
+ rpf_addr->rpf_addr.u.prefix4.s_addr;
+
+ pnc = hash_get(pimg->rpf_hash, pnc, hash_alloc_intern);
+
+ pnc->rp_list = list_new();
+ pnc->rp_list->cmp = pim_rp_list_cmp;
+
+ pnc->upstream_list = list_new();
+ pnc->upstream_list->cmp = pim_upstream_compare;
+
+ if (PIM_DEBUG_ZEBRA) {
+ char rpf_str[PREFIX_STRLEN];
+ pim_addr_dump("<nht?>", &rpf_addr->rpf_addr, rpf_str,
+ sizeof(rpf_str));
+ zlog_debug(
+ "%s: NHT hash node, RP and UP lists allocated for %s ",
+ __PRETTY_FUNCTION__, rpf_str);
+ }
+
+ return pnc;
}
/* This API is used to Register an address with Zebra
ret 1 means nexthop cache is found.
*/
-int
-pim_find_or_track_nexthop (struct prefix *addr, struct pim_upstream *up,
- struct rp_info *rp,
- struct pim_nexthop_cache *out_pnc)
+int pim_find_or_track_nexthop(struct prefix *addr, struct pim_upstream *up,
+ struct rp_info *rp,
+ struct pim_nexthop_cache *out_pnc)
{
- struct pim_nexthop_cache *pnc = NULL;
- struct pim_rpf rpf;
- struct listnode *ch_node = NULL;
- struct zclient *zclient = NULL;
-
- zclient = pim_zebra_zclient_get ();
- memset (&rpf, 0, sizeof (struct pim_rpf));
- rpf.rpf_addr.family = addr->family;
- rpf.rpf_addr.prefixlen = addr->prefixlen;
- rpf.rpf_addr.u.prefix4 = addr->u.prefix4;
-
- pnc = pim_nexthop_cache_find (&rpf);
- if (!pnc)
- {
- pnc = pim_nexthop_cache_add (&rpf);
- if (pnc)
- pim_sendmsg_zebra_rnh (zclient, pnc, ZEBRA_NEXTHOP_REGISTER);
- else
- {
- char rpf_str[PREFIX_STRLEN];
- pim_addr_dump ("<nht-pnc?>", addr, rpf_str, sizeof (rpf_str));
- zlog_warn ("%s: pnc node allocation failed. addr %s ",
- __PRETTY_FUNCTION__, rpf_str);
- return -1;
- }
- }
-
- if (rp != NULL)
- {
- ch_node = listnode_lookup (pnc->rp_list, rp);
- if (ch_node == NULL)
- {
- if (PIM_DEBUG_ZEBRA)
- {
- char rp_str[PREFIX_STRLEN];
- pim_addr_dump ("<rp?>", &rp->rp.rpf_addr, rp_str,
- sizeof (rp_str));
- zlog_debug ("%s: Add RP %s node to pnc cached list",
- __PRETTY_FUNCTION__, rp_str);
- }
- listnode_add_sort (pnc->rp_list, rp);
- }
- }
-
- if (up != NULL)
- {
- ch_node = listnode_lookup (pnc->upstream_list, up);
- if (ch_node == NULL)
- {
- if (PIM_DEBUG_ZEBRA)
- {
- char buf[PREFIX2STR_BUFFER];
- prefix2str (addr, buf, sizeof (buf));
- zlog_debug ("%s: Add upstream %s node to pnc cached list, rpf %s",
- __PRETTY_FUNCTION__, up->sg_str, buf);
- }
- listnode_add_sort (pnc->upstream_list, up);
- }
- }
-
- if (pnc && CHECK_FLAG (pnc->flags, PIM_NEXTHOP_VALID))
- {
- memcpy (out_pnc, pnc, sizeof (struct pim_nexthop_cache));
- return 1;
- }
-
- return 0;
+ struct pim_nexthop_cache *pnc = NULL;
+ struct pim_rpf rpf;
+ struct listnode *ch_node = NULL;
+ struct zclient *zclient = NULL;
+
+ zclient = pim_zebra_zclient_get();
+ memset(&rpf, 0, sizeof(struct pim_rpf));
+ rpf.rpf_addr.family = addr->family;
+ rpf.rpf_addr.prefixlen = addr->prefixlen;
+ rpf.rpf_addr.u.prefix4 = addr->u.prefix4;
+
+ pnc = pim_nexthop_cache_find(&rpf);
+ if (!pnc) {
+ pnc = pim_nexthop_cache_add(&rpf);
+ if (pnc)
+ pim_sendmsg_zebra_rnh(zclient, pnc,
+ ZEBRA_NEXTHOP_REGISTER);
+ else {
+ char rpf_str[PREFIX_STRLEN];
+ pim_addr_dump("<nht-pnc?>", addr, rpf_str,
+ sizeof(rpf_str));
+ zlog_warn("%s: pnc node allocation failed. addr %s ",
+ __PRETTY_FUNCTION__, rpf_str);
+ return -1;
+ }
+ }
+
+ if (rp != NULL) {
+ ch_node = listnode_lookup(pnc->rp_list, rp);
+ if (ch_node == NULL) {
+ if (PIM_DEBUG_ZEBRA) {
+ char rp_str[PREFIX_STRLEN];
+ pim_addr_dump("<rp?>", &rp->rp.rpf_addr, rp_str,
+ sizeof(rp_str));
+ zlog_debug(
+ "%s: Add RP %s node to pnc cached list",
+ __PRETTY_FUNCTION__, rp_str);
+ }
+ listnode_add_sort(pnc->rp_list, rp);
+ }
+ }
+
+ if (up != NULL) {
+ ch_node = listnode_lookup(pnc->upstream_list, up);
+ if (ch_node == NULL) {
+ if (PIM_DEBUG_ZEBRA) {
+ char buf[PREFIX2STR_BUFFER];
+ prefix2str(addr, buf, sizeof(buf));
+ zlog_debug(
+ "%s: Add upstream %s node to pnc cached list, rpf %s",
+ __PRETTY_FUNCTION__, up->sg_str, buf);
+ }
+ listnode_add_sort(pnc->upstream_list, up);
+ }
+ }
+
+ if (pnc && CHECK_FLAG(pnc->flags, PIM_NEXTHOP_VALID)) {
+ memcpy(out_pnc, pnc, sizeof(struct pim_nexthop_cache));
+ return 1;
+ }
+
+ return 0;
}
-void
-pim_delete_tracked_nexthop (struct prefix *addr, struct pim_upstream *up,
- struct rp_info *rp)
+void pim_delete_tracked_nexthop(struct prefix *addr, struct pim_upstream *up,
+ struct rp_info *rp)
{
- struct pim_nexthop_cache *pnc = NULL;
- struct pim_nexthop_cache lookup;
- struct zclient *zclient = NULL;
-
- zclient = pim_zebra_zclient_get ();
-
- /* Remove from RPF hash if it is the last entry */
- lookup.rpf.rpf_addr = *addr;
- pnc = hash_lookup (pimg->rpf_hash, &lookup);
- if (pnc)
- {
- if (rp)
- listnode_delete (pnc->rp_list, rp);
- if (up)
- listnode_delete (pnc->upstream_list, up);
-
- if (PIM_DEBUG_ZEBRA)
- zlog_debug ("%s: NHT rp_list count:%d upstream_list count:%d ",
- __PRETTY_FUNCTION__, pnc->rp_list->count,
- pnc->upstream_list->count);
-
- if (pnc->rp_list->count == 0 && pnc->upstream_list->count == 0)
- {
- pim_sendmsg_zebra_rnh (zclient, pnc, ZEBRA_NEXTHOP_UNREGISTER);
-
- list_delete (pnc->rp_list);
- list_delete (pnc->upstream_list);
-
- hash_release (pimg->rpf_hash, pnc);
- if (pnc->nexthop)
- nexthops_free (pnc->nexthop);
- XFREE (MTYPE_PIM_NEXTHOP_CACHE, pnc);
- }
- }
+ struct pim_nexthop_cache *pnc = NULL;
+ struct pim_nexthop_cache lookup;
+ struct zclient *zclient = NULL;
+
+ zclient = pim_zebra_zclient_get();
+
+ /* Remove from RPF hash if it is the last entry */
+ lookup.rpf.rpf_addr = *addr;
+ pnc = hash_lookup(pimg->rpf_hash, &lookup);
+ if (pnc) {
+ if (rp)
+ listnode_delete(pnc->rp_list, rp);
+ if (up)
+ listnode_delete(pnc->upstream_list, up);
+
+ if (PIM_DEBUG_ZEBRA)
+ zlog_debug(
+ "%s: NHT rp_list count:%d upstream_list count:%d ",
+ __PRETTY_FUNCTION__, pnc->rp_list->count,
+ pnc->upstream_list->count);
+
+ if (pnc->rp_list->count == 0
+ && pnc->upstream_list->count == 0) {
+ pim_sendmsg_zebra_rnh(zclient, pnc,
+ ZEBRA_NEXTHOP_UNREGISTER);
+
+ list_delete(pnc->rp_list);
+ list_delete(pnc->upstream_list);
+
+ hash_release(pimg->rpf_hash, pnc);
+ if (pnc->nexthop)
+ nexthops_free(pnc->nexthop);
+ XFREE(MTYPE_PIM_NEXTHOP_CACHE, pnc);
+ }
+ }
}
/* Update RP nexthop info based on Nexthop update received from Zebra.*/
-int
-pim_update_rp_nh (struct pim_nexthop_cache *pnc)
+int pim_update_rp_nh(struct pim_nexthop_cache *pnc)
{
- struct listnode *node = NULL;
- struct rp_info *rp_info = NULL;
- int ret = 0;
-
- /*Traverse RP list and update each RP Nexthop info */
- for (ALL_LIST_ELEMENTS_RO (pnc->rp_list, node, rp_info))
- {
- if (rp_info->rp.rpf_addr.u.prefix4.s_addr == INADDR_NONE)
- continue;
-
- //Compute PIM RPF using cached nexthop
- ret = pim_ecmp_nexthop_search (pnc, &rp_info->rp.source_nexthop,
- &rp_info->rp.rpf_addr, &rp_info->group, 1);
-
- if (PIM_DEBUG_TRACE)
- {
- char rp_str[PREFIX_STRLEN];
- pim_addr_dump ("<rp?>", &rp_info->rp.rpf_addr, rp_str,
- sizeof (rp_str));
- zlog_debug ("%s: NHT update, nexthop for RP %s is interface %s ",
- __PRETTY_FUNCTION__, rp_str,
- rp_info->rp.source_nexthop.interface->name);
- }
- }
-
- if (ret)
- return 0;
-
- return 1;
+ struct listnode *node = NULL;
+ struct rp_info *rp_info = NULL;
+ int ret = 0;
+
+ /*Traverse RP list and update each RP Nexthop info */
+ for (ALL_LIST_ELEMENTS_RO(pnc->rp_list, node, rp_info)) {
+ if (rp_info->rp.rpf_addr.u.prefix4.s_addr == INADDR_NONE)
+ continue;
+
+ // Compute PIM RPF using cached nexthop
+ ret = pim_ecmp_nexthop_search(pnc, &rp_info->rp.source_nexthop,
+ &rp_info->rp.rpf_addr,
+ &rp_info->group, 1);
+
+ if (PIM_DEBUG_TRACE) {
+ char rp_str[PREFIX_STRLEN];
+ pim_addr_dump("<rp?>", &rp_info->rp.rpf_addr, rp_str,
+ sizeof(rp_str));
+ zlog_debug(
+ "%s: NHT update, nexthop for RP %s is interface %s ",
+ __PRETTY_FUNCTION__, rp_str,
+ rp_info->rp.source_nexthop.interface->name);
+ }
+ }
+
+ if (ret)
+ return 0;
+
+ return 1;
}
/* This API is used to traverse nexthop cache of RPF addr
@@ -303,771 +292,779 @@ pim_update_rp_nh (struct pim_nexthop_cache *pnc)
unresolved state and due to event like pim neighbor
UP event if it can be resolved.
*/
-void
-pim_resolve_upstream_nh (struct prefix *nht_p)
+void pim_resolve_upstream_nh(struct prefix *nht_p)
{
- struct nexthop *nh_node = NULL;
- struct pim_nexthop_cache pnc;
- struct pim_neighbor *nbr = NULL;
-
- memset (&pnc, 0, sizeof (struct pim_nexthop_cache));
- if ((pim_find_or_track_nexthop (nht_p, NULL, NULL, &pnc)) == 1)
- {
- for (nh_node = pnc.nexthop; nh_node; nh_node = nh_node->next)
- {
- if (nh_node->gate.ipv4.s_addr == 0)
- {
- struct interface *ifp1 = if_lookup_by_index(nh_node->ifindex,
- VRF_DEFAULT);
- nbr = pim_neighbor_find_if (ifp1);
- if (nbr)
- {
- nh_node->gate.ipv4 = nbr->source_addr;
- if (PIM_DEBUG_TRACE)
- {
- char str[PREFIX_STRLEN];
- char str1[INET_ADDRSTRLEN];
- pim_inet4_dump ("<nht_nbr?>", nbr->source_addr, str1,
- sizeof (str1));
- pim_addr_dump ("<nht_addr?>", nht_p, str, sizeof (str));
- zlog_debug ("%s: addr %s new nexthop addr %s interface %s",
- __PRETTY_FUNCTION__, str, str1, ifp1->name);
- }
- }
- }
- }
- }
+ struct nexthop *nh_node = NULL;
+ struct pim_nexthop_cache pnc;
+ struct pim_neighbor *nbr = NULL;
+
+ memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
+ if ((pim_find_or_track_nexthop(nht_p, NULL, NULL, &pnc)) == 1) {
+ for (nh_node = pnc.nexthop; nh_node; nh_node = nh_node->next) {
+ if (nh_node->gate.ipv4.s_addr == 0) {
+ struct interface *ifp1 = if_lookup_by_index(
+ nh_node->ifindex, VRF_DEFAULT);
+ nbr = pim_neighbor_find_if(ifp1);
+ if (nbr) {
+ nh_node->gate.ipv4 = nbr->source_addr;
+ if (PIM_DEBUG_TRACE) {
+ char str[PREFIX_STRLEN];
+ char str1[INET_ADDRSTRLEN];
+ pim_inet4_dump("<nht_nbr?>",
+ nbr->source_addr,
+ str1,
+ sizeof(str1));
+ pim_addr_dump("<nht_addr?>",
+ nht_p, str,
+ sizeof(str));
+ zlog_debug(
+ "%s: addr %s new nexthop addr %s interface %s",
+ __PRETTY_FUNCTION__,
+ str, str1, ifp1->name);
+ }
+ }
+ }
+ }
+ }
}
/* Update Upstream nexthop info based on Nexthop update received from Zebra.*/
-static int
-pim_update_upstream_nh (struct pim_nexthop_cache *pnc)
+static int pim_update_upstream_nh(struct pim_nexthop_cache *pnc)
{
- struct listnode *up_node;
- struct listnode *ifnode;
- struct listnode *up_nextnode;
- struct listnode *node;
- struct pim_upstream *up = NULL;
- struct interface *ifp = NULL;
- int vif_index = 0;
-
- for (ALL_LIST_ELEMENTS (pnc->upstream_list, up_node, up_nextnode, up))
- {
- enum pim_rpf_result rpf_result;
- struct pim_rpf old;
-
- old.source_nexthop.interface = up->rpf.source_nexthop.interface;
- rpf_result = pim_rpf_update (up, &old, 0);
- if (rpf_result == PIM_RPF_FAILURE)
- continue;
-
- /* update kernel multicast forwarding cache (MFC) */
- if (up->channel_oil)
- {
- ifindex_t ifindex = up->rpf.source_nexthop.interface->ifindex;
- vif_index = pim_if_find_vifindex_by_ifindex (ifindex);
- /* Pass Current selected NH vif index to mroute download */
- if (vif_index)
- pim_scan_individual_oil (up->channel_oil, vif_index);
- else
- {
- if (PIM_DEBUG_ZEBRA)
- zlog_debug ("%s: NHT upstream %s channel_oil IIF %s vif_index is not valid",
- __PRETTY_FUNCTION__, up->sg_str,
- up->rpf.source_nexthop.interface->name);
- }
- }
-
- if (rpf_result == PIM_RPF_CHANGED)
- {
- struct pim_neighbor *nbr;
-
- nbr = pim_neighbor_find (old.source_nexthop.interface,
- old.rpf_addr.u.prefix4);
- if (nbr)
- pim_jp_agg_remove_group (nbr->upstream_jp_agg, up);
-
- /*
- * We have detected a case where we might need to rescan
- * the inherited o_list so do it.
- */
- if (up->channel_oil && up->channel_oil->oil_inherited_rescan)
- {
- pim_upstream_inherited_olist_decide (up);
- up->channel_oil->oil_inherited_rescan = 0;
- }
-
- if (up->join_state == PIM_UPSTREAM_JOINED)
- {
- /*
- * If we come up real fast we can be here
- * where the mroute has not been installed
- * so install it.
- */
- if (up->channel_oil && !up->channel_oil->installed)
- pim_mroute_add (up->channel_oil, __PRETTY_FUNCTION__);
-
- /*
- RFC 4601: 4.5.7. Sending (S,G) Join/Prune Messages
-
- Transitions from Joined State
-
- RPF'(S,G) changes not due to an Assert
-
- The upstream (S,G) state machine remains in Joined
- state. Send Join(S,G) to the new upstream neighbor, which is
- the new value of RPF'(S,G). Send Prune(S,G) to the old
- upstream neighbor, which is the old value of RPF'(S,G). Set
- the Join Timer (JT) to expire after t_periodic seconds.
- */
- pim_jp_agg_switch_interface (&old, &up->rpf, up);
-
- pim_upstream_join_timer_restart (up, &old);
- } /* up->join_state == PIM_UPSTREAM_JOINED */
-
- /* FIXME can join_desired actually be changed by pim_rpf_update()
- returning PIM_RPF_CHANGED ? */
- pim_upstream_update_join_desired (up);
-
- } /* PIM_RPF_CHANGED */
-
- if (PIM_DEBUG_TRACE)
- {
- zlog_debug ("%s: NHT upstream %s old ifp %s new ifp %s",
- __PRETTY_FUNCTION__, up->sg_str,
- old.source_nexthop.interface->name,
- up->rpf.source_nexthop.interface->name);
- }
- } /* for (pnc->upstream_list) */
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp))
- if (ifp->info)
- {
- struct pim_interface *pim_ifp = ifp->info;
- struct pim_iface_upstream_switch *us;
-
- for (ALL_LIST_ELEMENTS_RO (pim_ifp->upstream_switch_list, node, us))
- {
- struct pim_rpf rpf;
- rpf.source_nexthop.interface = ifp;
- rpf.rpf_addr.u.prefix4 = us->address;
- pim_joinprune_send (&rpf, us->us);
- pim_jp_agg_clear_group (us->us);
- }
- }
-
- return 0;
+ struct listnode *up_node;
+ struct listnode *ifnode;
+ struct listnode *up_nextnode;
+ struct listnode *node;
+ struct pim_upstream *up = NULL;
+ struct interface *ifp = NULL;
+ int vif_index = 0;
+
+ for (ALL_LIST_ELEMENTS(pnc->upstream_list, up_node, up_nextnode, up)) {
+ enum pim_rpf_result rpf_result;
+ struct pim_rpf old;
+
+ old.source_nexthop.interface = up->rpf.source_nexthop.interface;
+ rpf_result = pim_rpf_update(up, &old, 0);
+ if (rpf_result == PIM_RPF_FAILURE)
+ continue;
+
+ /* update kernel multicast forwarding cache (MFC) */
+ if (up->channel_oil) {
+ ifindex_t ifindex =
+ up->rpf.source_nexthop.interface->ifindex;
+ vif_index = pim_if_find_vifindex_by_ifindex(ifindex);
+ /* Pass Current selected NH vif index to mroute download
+ */
+ if (vif_index)
+ pim_scan_individual_oil(up->channel_oil,
+ vif_index);
+ else {
+ if (PIM_DEBUG_ZEBRA)
+ zlog_debug(
+ "%s: NHT upstream %s channel_oil IIF %s vif_index is not valid",
+ __PRETTY_FUNCTION__, up->sg_str,
+ up->rpf.source_nexthop
+ .interface->name);
+ }
+ }
+
+ if (rpf_result == PIM_RPF_CHANGED) {
+ struct pim_neighbor *nbr;
+
+ nbr = pim_neighbor_find(old.source_nexthop.interface,
+ old.rpf_addr.u.prefix4);
+ if (nbr)
+ pim_jp_agg_remove_group(nbr->upstream_jp_agg,
+ up);
+
+ /*
+ * We have detected a case where we might need to rescan
+ * the inherited o_list so do it.
+ */
+ if (up->channel_oil
+ && up->channel_oil->oil_inherited_rescan) {
+ pim_upstream_inherited_olist_decide(up);
+ up->channel_oil->oil_inherited_rescan = 0;
+ }
+
+ if (up->join_state == PIM_UPSTREAM_JOINED) {
+ /*
+ * If we come up real fast we can be here
+ * where the mroute has not been installed
+ * so install it.
+ */
+ if (up->channel_oil
+ && !up->channel_oil->installed)
+ pim_mroute_add(up->channel_oil,
+ __PRETTY_FUNCTION__);
+
+ /*
+ RFC 4601: 4.5.7. Sending (S,G) Join/Prune
+ Messages
+
+ Transitions from Joined State
+
+ RPF'(S,G) changes not due to an Assert
+
+ The upstream (S,G) state machine remains in
+ Joined
+ state. Send Join(S,G) to the new upstream
+ neighbor, which is
+ the new value of RPF'(S,G). Send Prune(S,G)
+ to the old
+ upstream neighbor, which is the old value of
+ RPF'(S,G). Set
+ the Join Timer (JT) to expire after
+ t_periodic seconds.
+ */
+ pim_jp_agg_switch_interface(&old, &up->rpf, up);
+
+ pim_upstream_join_timer_restart(up, &old);
+ } /* up->join_state == PIM_UPSTREAM_JOINED */
+
+ /* FIXME can join_desired actually be changed by
+ pim_rpf_update()
+ returning PIM_RPF_CHANGED ? */
+ pim_upstream_update_join_desired(up);
+
+ } /* PIM_RPF_CHANGED */
+
+ if (PIM_DEBUG_TRACE) {
+ zlog_debug("%s: NHT upstream %s old ifp %s new ifp %s",
+ __PRETTY_FUNCTION__, up->sg_str,
+ old.source_nexthop.interface->name,
+ up->rpf.source_nexthop.interface->name);
+ }
+ } /* for (pnc->upstream_list) */
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), ifnode, ifp))
+ if (ifp->info) {
+ struct pim_interface *pim_ifp = ifp->info;
+ struct pim_iface_upstream_switch *us;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->upstream_switch_list,
+ node, us)) {
+ struct pim_rpf rpf;
+ rpf.source_nexthop.interface = ifp;
+ rpf.rpf_addr.u.prefix4 = us->address;
+ pim_joinprune_send(&rpf, us->us);
+ pim_jp_agg_clear_group(us->us);
+ }
+ }
+
+ return 0;
}
-uint32_t
-pim_compute_ecmp_hash (struct prefix * src, struct prefix * grp)
+uint32_t pim_compute_ecmp_hash(struct prefix *src, struct prefix *grp)
{
- uint32_t hash_val;
- uint32_t s = 0, g = 0;
-
- if ((!src))
- return 0;
-
- switch (src->family)
- {
- case AF_INET:
- {
- s = src->u.prefix4.s_addr;
- s = s == 0 ? 1 : s;
- if (grp)
- g = grp->u.prefix4.s_addr;
- }
- break;
- default:
- break;
- }
-
- hash_val = jhash_2words (g, s, 101);
- if (PIM_DEBUG_PIM_TRACE_DETAIL)
- {
- char buf[PREFIX2STR_BUFFER];
- char bufg[PREFIX2STR_BUFFER];
- prefix2str (src, buf, sizeof (buf));
- if (grp)
- prefix2str (grp, bufg, sizeof (bufg));
- zlog_debug ("%s: addr %s %s hash_val %u", __PRETTY_FUNCTION__, buf,
- grp ? bufg : "", hash_val);
-
- }
- return hash_val;
+ uint32_t hash_val;
+ uint32_t s = 0, g = 0;
+
+ if ((!src))
+ return 0;
+
+ switch (src->family) {
+ case AF_INET: {
+ s = src->u.prefix4.s_addr;
+ s = s == 0 ? 1 : s;
+ if (grp)
+ g = grp->u.prefix4.s_addr;
+ } break;
+ default:
+ break;
+ }
+
+ hash_val = jhash_2words(g, s, 101);
+ if (PIM_DEBUG_PIM_TRACE_DETAIL) {
+ char buf[PREFIX2STR_BUFFER];
+ char bufg[PREFIX2STR_BUFFER];
+ prefix2str(src, buf, sizeof(buf));
+ if (grp)
+ prefix2str(grp, bufg, sizeof(bufg));
+ zlog_debug("%s: addr %s %s hash_val %u", __PRETTY_FUNCTION__,
+ buf, grp ? bufg : "", hash_val);
+ }
+ return hash_val;
}
-int
-pim_ecmp_nexthop_search (struct pim_nexthop_cache *pnc,
- struct pim_nexthop *nexthop, struct prefix *src,
- struct prefix *grp, int neighbor_needed)
+int pim_ecmp_nexthop_search(struct pim_nexthop_cache *pnc,
+ struct pim_nexthop *nexthop, struct prefix *src,
+ struct prefix *grp, int neighbor_needed)
{
- struct pim_neighbor *nbr = NULL;
- struct nexthop *nh_node = NULL;
- ifindex_t first_ifindex;
- struct interface *ifp = NULL;
- uint32_t hash_val = 0, mod_val = 0;
- uint8_t nh_iter = 0, found = 0;
-
- if (!pnc || !pnc->nexthop_num || !nexthop)
- return -1;
-
- //Current Nexthop is VALID, check to stay on the current path.
- if (nexthop->interface && nexthop->interface->info &&
- nexthop->mrib_nexthop_addr.u.prefix4.s_addr !=
- PIM_NET_INADDR_ANY)
- {
- /* User configured knob to explicitly switch
- to new path is disabled or current path
- metric is less than nexthop update.
- */
-
- if (qpim_ecmp_rebalance_enable == 0)
- {
- uint8_t curr_route_valid = 0;
- //Check if current nexthop is present in new updated Nexthop list.
- //If the current nexthop is not valid, candidate to choose new Nexthop.
- for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next)
- curr_route_valid = (nexthop->interface->ifindex == nh_node->ifindex);
-
- if (curr_route_valid &&
- !pim_if_connected_to_source (nexthop->interface,
- src->u.prefix4))
- {
- nbr = pim_neighbor_find (nexthop->interface,
- nexthop->mrib_nexthop_addr.u.prefix4);
- if (!nbr && !if_is_loopback (nexthop->interface))
- {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: current nexthop does not have nbr ",
- __PRETTY_FUNCTION__);
- }
- else
- {
- if (PIM_DEBUG_TRACE)
- {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump ("<addr?>", src->u.prefix4, src_str,
- sizeof (src_str));
- char grp_str[INET_ADDRSTRLEN];
- pim_inet4_dump ("<addr?>", grp->u.prefix4, grp_str,
- sizeof (grp_str));
- zlog_debug ("%s: (%s, %s) current nexthop %s is valid, skipping new path selection",
- __PRETTY_FUNCTION__, src_str, grp_str,
- nexthop->interface->name);
- }
- return 0;
- }
- }
- }
- }
- if (qpim_ecmp_enable)
- {
- //PIM ECMP flag is enable then choose ECMP path.
- hash_val = pim_compute_ecmp_hash (src, grp);
- mod_val = hash_val % pnc->nexthop_num;
- if (PIM_DEBUG_PIM_TRACE_DETAIL)
- zlog_debug ("%s: hash_val %u mod_val %u ",
- __PRETTY_FUNCTION__, hash_val, mod_val);
- }
-
- for (nh_node = pnc->nexthop; nh_node && (found == 0);
- nh_node = nh_node->next)
- {
- first_ifindex = nh_node->ifindex;
- ifp = if_lookup_by_index(first_ifindex, VRF_DEFAULT);
- if (!ifp)
- {
- if (PIM_DEBUG_ZEBRA)
- {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump ("<addr?>", src->u.prefix4, addr_str,
- sizeof (addr_str));
- zlog_debug ("%s %s: could not find interface for ifindex %d (address %s)",
- __FILE__, __PRETTY_FUNCTION__, first_ifindex, addr_str);
- }
- if (nh_iter == mod_val)
- mod_val++; //Select nexthpath
- nh_iter++;
- continue;
- }
- if (!ifp->info)
- {
- if (PIM_DEBUG_ZEBRA)
- {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump ("<addr?>", src->u.prefix4, addr_str,
- sizeof (addr_str));
- zlog_debug ("%s: multicast not enabled on input interface %s (ifindex=%d, RPF for source %s)",
- __PRETTY_FUNCTION__, ifp->name, first_ifindex, addr_str);
- }
- if (nh_iter == mod_val)
- mod_val++; //Select nexthpath
- nh_iter++;
- continue;
- }
-
- if (neighbor_needed
- && !pim_if_connected_to_source (ifp, src->u.prefix4))
- {
- nbr = pim_neighbor_find (ifp, nh_node->gate.ipv4);
- if (PIM_DEBUG_PIM_TRACE_DETAIL)
- zlog_debug ("ifp name: %s, pim nbr: %p", ifp->name, nbr);
- if (!nbr && !if_is_loopback (ifp))
- {
- if (PIM_DEBUG_ZEBRA)
- zlog_debug ("%s: pim nbr not found on input interface %s",
- __PRETTY_FUNCTION__, ifp->name);
- if (nh_iter == mod_val)
- mod_val++; //Select nexthpath
- nh_iter++;
- continue;
- }
- }
-
- if (nh_iter == mod_val)
- {
- nexthop->interface = ifp;
- nexthop->mrib_nexthop_addr.family = AF_INET;
- nexthop->mrib_nexthop_addr.prefixlen = IPV4_MAX_BITLEN;
- nexthop->mrib_nexthop_addr.u.prefix4 = nh_node->gate.ipv4;
- nexthop->mrib_metric_preference = pnc->distance;
- nexthop->mrib_route_metric = pnc->metric;
- nexthop->last_lookup = src->u.prefix4;
- nexthop->last_lookup_time = pim_time_monotonic_usec ();
- nexthop->nbr = nbr;
- found = 1;
- if (PIM_DEBUG_ZEBRA)
- {
- char buf[INET_ADDRSTRLEN];
- char buf2[INET_ADDRSTRLEN];
- char buf3[INET_ADDRSTRLEN];
- pim_inet4_dump ("<src?>", src->u.prefix4, buf2, sizeof (buf2));
- pim_inet4_dump ("<grp?>", grp->u.prefix4, buf3, sizeof (buf3));
- pim_inet4_dump ("<rpf?>",
- nexthop->mrib_nexthop_addr.u.prefix4, buf,
- sizeof (buf));
- zlog_debug ("%s: (%s, %s) selected nhop interface %s addr %s mod_val %u iter %d ecmp %d",
- __PRETTY_FUNCTION__, buf2, buf3, ifp->name,
- buf, mod_val, nh_iter, qpim_ecmp_enable);
- }
- }
- nh_iter++;
- }
-
- if (found)
- return 0;
- else
- return -1;
+ struct pim_neighbor *nbr = NULL;
+ struct nexthop *nh_node = NULL;
+ ifindex_t first_ifindex;
+ struct interface *ifp = NULL;
+ uint32_t hash_val = 0, mod_val = 0;
+ uint8_t nh_iter = 0, found = 0;
+
+ if (!pnc || !pnc->nexthop_num || !nexthop)
+ return -1;
+
+ // Current Nexthop is VALID, check to stay on the current path.
+ if (nexthop->interface && nexthop->interface->info
+ && nexthop->mrib_nexthop_addr.u.prefix4.s_addr
+ != PIM_NET_INADDR_ANY) {
+ /* User configured knob to explicitly switch
+ to new path is disabled or current path
+ metric is less than nexthop update.
+ */
+
+ if (qpim_ecmp_rebalance_enable == 0) {
+ uint8_t curr_route_valid = 0;
+ // Check if current nexthop is present in new updated
+ // Nexthop list.
+ // If the current nexthop is not valid, candidate to
+ // choose new Nexthop.
+ for (nh_node = pnc->nexthop; nh_node;
+ nh_node = nh_node->next)
+ curr_route_valid = (nexthop->interface->ifindex
+ == nh_node->ifindex);
+
+ if (curr_route_valid
+ && !pim_if_connected_to_source(nexthop->interface,
+ src->u.prefix4)) {
+ nbr = pim_neighbor_find(
+ nexthop->interface,
+ nexthop->mrib_nexthop_addr.u.prefix4);
+ if (!nbr
+ && !if_is_loopback(nexthop->interface)) {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug(
+ "%s: current nexthop does not have nbr ",
+ __PRETTY_FUNCTION__);
+ } else {
+ if (PIM_DEBUG_TRACE) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>",
+ src->u.prefix4,
+ src_str,
+ sizeof(src_str));
+ char grp_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>",
+ grp->u.prefix4,
+ grp_str,
+ sizeof(grp_str));
+ zlog_debug(
+ "%s: (%s, %s) current nexthop %s is valid, skipping new path selection",
+ __PRETTY_FUNCTION__,
+ src_str, grp_str,
+ nexthop->interface->name);
+ }
+ return 0;
+ }
+ }
+ }
+ }
+ if (qpim_ecmp_enable) {
+ // PIM ECMP flag is enable then choose ECMP path.
+ hash_val = pim_compute_ecmp_hash(src, grp);
+ mod_val = hash_val % pnc->nexthop_num;
+ if (PIM_DEBUG_PIM_TRACE_DETAIL)
+ zlog_debug("%s: hash_val %u mod_val %u ",
+ __PRETTY_FUNCTION__, hash_val, mod_val);
+ }
+
+ for (nh_node = pnc->nexthop; nh_node && (found == 0);
+ nh_node = nh_node->next) {
+ first_ifindex = nh_node->ifindex;
+ ifp = if_lookup_by_index(first_ifindex, VRF_DEFAULT);
+ if (!ifp) {
+ if (PIM_DEBUG_ZEBRA) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", src->u.prefix4,
+ addr_str, sizeof(addr_str));
+ zlog_debug(
+ "%s %s: could not find interface for ifindex %d (address %s)",
+ __FILE__, __PRETTY_FUNCTION__,
+ first_ifindex, addr_str);
+ }
+ if (nh_iter == mod_val)
+ mod_val++; // Select nexthpath
+ nh_iter++;
+ continue;
+ }
+ if (!ifp->info) {
+ if (PIM_DEBUG_ZEBRA) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", src->u.prefix4,
+ addr_str, sizeof(addr_str));
+ zlog_debug(
+ "%s: multicast not enabled on input interface %s (ifindex=%d, RPF for source %s)",
+ __PRETTY_FUNCTION__, ifp->name,
+ first_ifindex, addr_str);
+ }
+ if (nh_iter == mod_val)
+ mod_val++; // Select nexthpath
+ nh_iter++;
+ continue;
+ }
+
+ if (neighbor_needed
+ && !pim_if_connected_to_source(ifp, src->u.prefix4)) {
+ nbr = pim_neighbor_find(ifp, nh_node->gate.ipv4);
+ if (PIM_DEBUG_PIM_TRACE_DETAIL)
+ zlog_debug("ifp name: %s, pim nbr: %p",
+ ifp->name, nbr);
+ if (!nbr && !if_is_loopback(ifp)) {
+ if (PIM_DEBUG_ZEBRA)
+ zlog_debug(
+ "%s: pim nbr not found on input interface %s",
+ __PRETTY_FUNCTION__, ifp->name);
+ if (nh_iter == mod_val)
+ mod_val++; // Select nexthpath
+ nh_iter++;
+ continue;
+ }
+ }
+
+ if (nh_iter == mod_val) {
+ nexthop->interface = ifp;
+ nexthop->mrib_nexthop_addr.family = AF_INET;
+ nexthop->mrib_nexthop_addr.prefixlen = IPV4_MAX_BITLEN;
+ nexthop->mrib_nexthop_addr.u.prefix4 =
+ nh_node->gate.ipv4;
+ nexthop->mrib_metric_preference = pnc->distance;
+ nexthop->mrib_route_metric = pnc->metric;
+ nexthop->last_lookup = src->u.prefix4;
+ nexthop->last_lookup_time = pim_time_monotonic_usec();
+ nexthop->nbr = nbr;
+ found = 1;
+ if (PIM_DEBUG_ZEBRA) {
+ char buf[INET_ADDRSTRLEN];
+ char buf2[INET_ADDRSTRLEN];
+ char buf3[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src->u.prefix4, buf2,
+ sizeof(buf2));
+ pim_inet4_dump("<grp?>", grp->u.prefix4, buf3,
+ sizeof(buf3));
+ pim_inet4_dump(
+ "<rpf?>",
+ nexthop->mrib_nexthop_addr.u.prefix4,
+ buf, sizeof(buf));
+ zlog_debug(
+ "%s: (%s, %s) selected nhop interface %s addr %s mod_val %u iter %d ecmp %d",
+ __PRETTY_FUNCTION__, buf2, buf3,
+ ifp->name, buf, mod_val, nh_iter,
+ qpim_ecmp_enable);
+ }
+ }
+ nh_iter++;
+ }
+
+ if (found)
+ return 0;
+ else
+ return -1;
}
-/* This API is used to parse Registered address nexthop update coming from Zebra */
-int
-pim_parse_nexthop_update (int command, struct zclient *zclient,
- zebra_size_t length, vrf_id_t vrf_id)
+/* This API is used to parse Registered address nexthop update coming from Zebra
+ */
+int pim_parse_nexthop_update(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
{
- struct stream *s;
- struct prefix p;
- struct nexthop *nexthop;
- struct nexthop *nhlist_head = NULL;
- struct nexthop *nhlist_tail = NULL;
- uint32_t metric, distance;
- u_char nexthop_num = 0;
- int i;
- struct pim_rpf rpf;
- struct pim_nexthop_cache *pnc = NULL;
- struct pim_neighbor *nbr = NULL;
- struct interface *ifp = NULL;
- struct interface *ifp1 = NULL;
- struct pim_interface *pim_ifp = NULL;
- char str[INET_ADDRSTRLEN];
-
- s = zclient->ibuf;
- memset (&p, 0, sizeof (struct prefix));
- p.family = stream_getw (s);
- p.prefixlen = stream_getc (s);
- switch (p.family)
- {
- case AF_INET:
- p.u.prefix4.s_addr = stream_get_ipv4 (s);
- break;
- case AF_INET6:
- stream_get (&p.u.prefix6, s, 16);
- break;
- default:
- break;
- }
-
- if (command == ZEBRA_NEXTHOP_UPDATE)
- {
- rpf.rpf_addr.family = p.family;
- rpf.rpf_addr.prefixlen = p.prefixlen;
- rpf.rpf_addr.u.prefix4.s_addr = p.u.prefix4.s_addr;
- pnc = pim_nexthop_cache_find (&rpf);
- if (!pnc)
- {
- if (PIM_DEBUG_TRACE)
- {
- char buf[PREFIX2STR_BUFFER];
- prefix2str (&rpf.rpf_addr, buf, sizeof (buf));
- zlog_debug ("%s: Skipping NHT update, addr %s is not in local cached DB.",
- __PRETTY_FUNCTION__, buf);
- }
- return 0;
- }
- }
- else
- {
- /*
- * We do not currently handle ZEBRA_IMPORT_CHECK_UPDATE
- */
- return 0;
- }
-
- pnc->last_update = pim_time_monotonic_usec ();
- distance = stream_getc (s);
- metric = stream_getl (s);
- nexthop_num = stream_getc (s);
-
- if (nexthop_num)
- {
- pnc->nexthop_num = 0; //Only increment for pim enabled rpf.
-
- for (i = 0; i < nexthop_num; i++)
- {
- nexthop = nexthop_new ();
- nexthop->type = stream_getc (s);
- switch (nexthop->type)
- {
- case NEXTHOP_TYPE_IPV4:
- nexthop->gate.ipv4.s_addr = stream_get_ipv4 (s);
- nexthop->ifindex = stream_getl (s);
- break;
- case NEXTHOP_TYPE_IFINDEX:
- nexthop->ifindex = stream_getl (s);
- break;
- case NEXTHOP_TYPE_IPV4_IFINDEX:
- nexthop->gate.ipv4.s_addr = stream_get_ipv4 (s);
- nexthop->ifindex = stream_getl (s);
- break;
- case NEXTHOP_TYPE_IPV6:
- stream_get (&nexthop->gate.ipv6, s, 16);
- break;
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- stream_get (&nexthop->gate.ipv6, s, 16);
- nexthop->ifindex = stream_getl (s);
- ifp1 = if_lookup_by_index (nexthop->ifindex, VRF_DEFAULT);
- nbr = pim_neighbor_find_if (ifp1);
- /* Overwrite with Nbr address as NH addr */
- if (nbr)
- {
- nexthop->gate.ipv4 = nbr->source_addr;
- if (PIM_DEBUG_TRACE)
- {
- pim_inet4_dump ("<nht_nbr?>", nbr->source_addr, str,
- sizeof (str));
- zlog_debug ("%s: NHT using pim nbr addr %s interface %s as rpf",
- __PRETTY_FUNCTION__, str, ifp1->name);
- }
- }
- else
- {
- if (PIM_DEBUG_TRACE)
- {
- pim_ifp = ifp1->info;
- zlog_debug ("%s: NHT pim nbr not found on interface %s nbr count:%d ",
- __PRETTY_FUNCTION__, ifp1->name,
- pim_ifp->pim_neighbor_list->count);
- }
- //Mark nexthop address to 0 until PIM Nbr is resolved.
- nexthop->gate.ipv4.s_addr = PIM_NET_INADDR_ANY;
- }
-
- break;
- default:
- /* do nothing */
- break;
- }
-
- if (PIM_DEBUG_TRACE)
- {
- char p_str[PREFIX2STR_BUFFER];
- prefix2str (&p, p_str, sizeof (p_str));
- zlog_debug ("%s: NHT addr %s %d-nhop via %s type %d distance:%u metric:%u ",
- __PRETTY_FUNCTION__, p_str, i + 1,
- inet_ntoa (nexthop->gate.ipv4), nexthop->type, distance,
- metric);
- }
-
- ifp = if_lookup_by_index (nexthop->ifindex, VRF_DEFAULT);
- if (!ifp)
- {
- if (PIM_DEBUG_ZEBRA)
- {
- char buf[NEXTHOP_STRLEN];
- zlog_debug ("%s: could not find interface for ifindex %d (addr %s)",
- __PRETTY_FUNCTION__, nexthop->ifindex,
- nexthop2str (nexthop, buf, sizeof (buf)));
- }
- nexthop_free (nexthop);
- continue;
- }
-
- if (!ifp->info)
- {
- if (PIM_DEBUG_ZEBRA)
- {
- char buf[NEXTHOP_STRLEN];
- zlog_debug ("%s: multicast not enabled on input interface %s (ifindex=%d, addr %s)",
- __PRETTY_FUNCTION__, ifp->name, nexthop->ifindex,
- nexthop2str (nexthop, buf, sizeof (buf)));
- }
- nexthop_free (nexthop);
- continue;
- }
-
- if (nhlist_tail)
- {
- nhlist_tail->next = nexthop;
- nhlist_tail = nexthop;
- }
- else
- {
- nhlist_tail = nexthop;
- nhlist_head = nexthop;
- }
- //Only keep track of nexthops which are PIM enabled.
- pnc->nexthop_num++;
- }
- /* Reset existing pnc->nexthop before assigning new list */
- nexthops_free (pnc->nexthop);
- pnc->nexthop = nhlist_head;
- if (pnc->nexthop_num)
- {
- pnc->flags |= PIM_NEXTHOP_VALID;
- pnc->distance = distance;
- pnc->metric = metric;
- }
- }
- else
- {
- pnc->flags &= ~PIM_NEXTHOP_VALID;
- pnc->nexthop_num = nexthop_num;
- nexthops_free (pnc->nexthop);
- pnc->nexthop = NULL;
- }
-
- if (PIM_DEBUG_TRACE)
- {
- char buf[PREFIX2STR_BUFFER];
- prefix2str (&p, buf, sizeof (buf));
- zlog_debug ("%s: NHT Update for %s num_nh %d num_pim_nh %d vrf:%d up %d rp %d",
- __PRETTY_FUNCTION__, buf, nexthop_num, pnc->nexthop_num, vrf_id,
- listcount (pnc->upstream_list), listcount (pnc->rp_list));
- }
-
- pim_rpf_set_refresh_time ();
-
- if (listcount (pnc->rp_list))
- pim_update_rp_nh (pnc);
- if (listcount (pnc->upstream_list))
- pim_update_upstream_nh (pnc);
-
- return 0;
+ struct stream *s;
+ struct prefix p;
+ struct nexthop *nexthop;
+ struct nexthop *nhlist_head = NULL;
+ struct nexthop *nhlist_tail = NULL;
+ uint32_t metric, distance;
+ u_char nexthop_num = 0;
+ int i;
+ struct pim_rpf rpf;
+ struct pim_nexthop_cache *pnc = NULL;
+ struct pim_neighbor *nbr = NULL;
+ struct interface *ifp = NULL;
+ struct interface *ifp1 = NULL;
+ struct pim_interface *pim_ifp = NULL;
+ char str[INET_ADDRSTRLEN];
+
+ s = zclient->ibuf;
+ memset(&p, 0, sizeof(struct prefix));
+ p.family = stream_getw(s);
+ p.prefixlen = stream_getc(s);
+ switch (p.family) {
+ case AF_INET:
+ p.u.prefix4.s_addr = stream_get_ipv4(s);
+ break;
+ case AF_INET6:
+ stream_get(&p.u.prefix6, s, 16);
+ break;
+ default:
+ break;
+ }
+
+ if (command == ZEBRA_NEXTHOP_UPDATE) {
+ rpf.rpf_addr.family = p.family;
+ rpf.rpf_addr.prefixlen = p.prefixlen;
+ rpf.rpf_addr.u.prefix4.s_addr = p.u.prefix4.s_addr;
+ pnc = pim_nexthop_cache_find(&rpf);
+ if (!pnc) {
+ if (PIM_DEBUG_TRACE) {
+ char buf[PREFIX2STR_BUFFER];
+ prefix2str(&rpf.rpf_addr, buf, sizeof(buf));
+ zlog_debug(
+ "%s: Skipping NHT update, addr %s is not in local cached DB.",
+ __PRETTY_FUNCTION__, buf);
+ }
+ return 0;
+ }
+ } else {
+ /*
+ * We do not currently handle ZEBRA_IMPORT_CHECK_UPDATE
+ */
+ return 0;
+ }
+
+ pnc->last_update = pim_time_monotonic_usec();
+ distance = stream_getc(s);
+ metric = stream_getl(s);
+ nexthop_num = stream_getc(s);
+
+ if (nexthop_num) {
+ pnc->nexthop_num = 0; // Only increment for pim enabled rpf.
+
+ for (i = 0; i < nexthop_num; i++) {
+ nexthop = nexthop_new();
+ nexthop->type = stream_getc(s);
+ switch (nexthop->type) {
+ case NEXTHOP_TYPE_IPV4:
+ nexthop->gate.ipv4.s_addr = stream_get_ipv4(s);
+ nexthop->ifindex = stream_getl(s);
+ break;
+ case NEXTHOP_TYPE_IFINDEX:
+ nexthop->ifindex = stream_getl(s);
+ break;
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ nexthop->gate.ipv4.s_addr = stream_get_ipv4(s);
+ nexthop->ifindex = stream_getl(s);
+ break;
+ case NEXTHOP_TYPE_IPV6:
+ stream_get(&nexthop->gate.ipv6, s, 16);
+ break;
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ stream_get(&nexthop->gate.ipv6, s, 16);
+ nexthop->ifindex = stream_getl(s);
+ ifp1 = if_lookup_by_index(nexthop->ifindex,
+ VRF_DEFAULT);
+ nbr = pim_neighbor_find_if(ifp1);
+ /* Overwrite with Nbr address as NH addr */
+ if (nbr) {
+ nexthop->gate.ipv4 = nbr->source_addr;
+ if (PIM_DEBUG_TRACE) {
+ pim_inet4_dump("<nht_nbr?>",
+ nbr->source_addr,
+ str,
+ sizeof(str));
+ zlog_debug(
+ "%s: NHT using pim nbr addr %s interface %s as rpf",
+ __PRETTY_FUNCTION__,
+ str, ifp1->name);
+ }
+ } else {
+ if (PIM_DEBUG_TRACE) {
+ pim_ifp = ifp1->info;
+ zlog_debug(
+ "%s: NHT pim nbr not found on interface %s nbr count:%d ",
+ __PRETTY_FUNCTION__,
+ ifp1->name,
+ pim_ifp->pim_neighbor_list
+ ->count);
+ }
+ // Mark nexthop address to 0 until PIM
+ // Nbr is resolved.
+ nexthop->gate.ipv4.s_addr =
+ PIM_NET_INADDR_ANY;
+ }
+
+ break;
+ default:
+ /* do nothing */
+ break;
+ }
+
+ if (PIM_DEBUG_TRACE) {
+ char p_str[PREFIX2STR_BUFFER];
+ prefix2str(&p, p_str, sizeof(p_str));
+ zlog_debug(
+ "%s: NHT addr %s %d-nhop via %s type %d distance:%u metric:%u ",
+ __PRETTY_FUNCTION__, p_str, i + 1,
+ inet_ntoa(nexthop->gate.ipv4),
+ nexthop->type, distance, metric);
+ }
+
+ ifp = if_lookup_by_index(nexthop->ifindex, VRF_DEFAULT);
+ if (!ifp) {
+ if (PIM_DEBUG_ZEBRA) {
+ char buf[NEXTHOP_STRLEN];
+ zlog_debug(
+ "%s: could not find interface for ifindex %d (addr %s)",
+ __PRETTY_FUNCTION__,
+ nexthop->ifindex,
+ nexthop2str(nexthop, buf,
+ sizeof(buf)));
+ }
+ nexthop_free(nexthop);
+ continue;
+ }
+
+ if (!ifp->info) {
+ if (PIM_DEBUG_ZEBRA) {
+ char buf[NEXTHOP_STRLEN];
+ zlog_debug(
+ "%s: multicast not enabled on input interface %s (ifindex=%d, addr %s)",
+ __PRETTY_FUNCTION__, ifp->name,
+ nexthop->ifindex,
+ nexthop2str(nexthop, buf,
+ sizeof(buf)));
+ }
+ nexthop_free(nexthop);
+ continue;
+ }
+
+ if (nhlist_tail) {
+ nhlist_tail->next = nexthop;
+ nhlist_tail = nexthop;
+ } else {
+ nhlist_tail = nexthop;
+ nhlist_head = nexthop;
+ }
+ // Only keep track of nexthops which are PIM enabled.
+ pnc->nexthop_num++;
+ }
+ /* Reset existing pnc->nexthop before assigning new list */
+ nexthops_free(pnc->nexthop);
+ pnc->nexthop = nhlist_head;
+ if (pnc->nexthop_num) {
+ pnc->flags |= PIM_NEXTHOP_VALID;
+ pnc->distance = distance;
+ pnc->metric = metric;
+ }
+ } else {
+ pnc->flags &= ~PIM_NEXTHOP_VALID;
+ pnc->nexthop_num = nexthop_num;
+ nexthops_free(pnc->nexthop);
+ pnc->nexthop = NULL;
+ }
+
+ if (PIM_DEBUG_TRACE) {
+ char buf[PREFIX2STR_BUFFER];
+ prefix2str(&p, buf, sizeof(buf));
+ zlog_debug(
+ "%s: NHT Update for %s num_nh %d num_pim_nh %d vrf:%d up %d rp %d",
+ __PRETTY_FUNCTION__, buf, nexthop_num, pnc->nexthop_num,
+ vrf_id, listcount(pnc->upstream_list),
+ listcount(pnc->rp_list));
+ }
+
+ pim_rpf_set_refresh_time();
+
+ if (listcount(pnc->rp_list))
+ pim_update_rp_nh(pnc);
+ if (listcount(pnc->upstream_list))
+ pim_update_upstream_nh(pnc);
+
+ return 0;
}
-int
-pim_ecmp_nexthop_lookup (struct pim_nexthop *nexthop, struct in_addr addr,
- struct prefix *src, struct prefix *grp,
- int neighbor_needed)
+int pim_ecmp_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr,
+ struct prefix *src, struct prefix *grp,
+ int neighbor_needed)
{
- struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM];
- struct pim_neighbor *nbr = NULL;
- int num_ifindex;
- struct interface *ifp;
- int first_ifindex;
- int found = 0;
- uint8_t i = 0;
- uint32_t hash_val = 0, mod_val = 0;
-
- if (PIM_DEBUG_TRACE)
- {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump ("<addr?>", addr, addr_str, sizeof (addr_str));
- zlog_debug ("%s: Looking up: %s, last lookup time: %lld",
- __PRETTY_FUNCTION__, addr_str, nexthop->last_lookup_time);
- }
-
- memset (nexthop_tab, 0, sizeof (struct pim_zlookup_nexthop) * MULTIPATH_NUM);
- num_ifindex = zclient_lookup_nexthop (nexthop_tab, MULTIPATH_NUM, addr,
- PIM_NEXTHOP_LOOKUP_MAX);
- if (num_ifindex < 1)
- {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump ("<addr?>", addr, addr_str, sizeof (addr_str));
- zlog_warn ("%s %s: could not find nexthop ifindex for address %s",
- __FILE__, __PRETTY_FUNCTION__, addr_str);
- return -1;
- }
-
- //If PIM ECMP enable then choose ECMP path.
- if (qpim_ecmp_enable)
- {
- hash_val = pim_compute_ecmp_hash (src, grp);
- mod_val = hash_val % num_ifindex;
- if (PIM_DEBUG_PIM_TRACE_DETAIL)
- zlog_debug ("%s: hash_val %u mod_val %u",
- __PRETTY_FUNCTION__, hash_val, mod_val);
- }
-
- while (!found && (i < num_ifindex))
- {
- first_ifindex = nexthop_tab[i].ifindex;
-
- ifp = if_lookup_by_index (first_ifindex, VRF_DEFAULT);
- if (!ifp)
- {
- if (PIM_DEBUG_ZEBRA)
- {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump ("<addr?>", addr, addr_str, sizeof (addr_str));
- zlog_debug ("%s %s: could not find interface for ifindex %d (address %s)",
- __FILE__, __PRETTY_FUNCTION__, first_ifindex, addr_str);
- }
- if (i == mod_val)
- mod_val++;
- i++;
- continue;
- }
-
- if (!ifp->info)
- {
- if (PIM_DEBUG_ZEBRA)
- {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump ("<addr?>", addr, addr_str, sizeof (addr_str));
- zlog_debug ("%s: multicast not enabled on input interface %s (ifindex=%d, RPF for source %s)",
- __PRETTY_FUNCTION__, ifp->name, first_ifindex, addr_str);
- }
- if (i == mod_val)
- mod_val++;
- i++;
- continue;
- }
- if (neighbor_needed && !pim_if_connected_to_source (ifp, addr))
- {
- nbr = pim_neighbor_find (ifp, nexthop_tab[i].nexthop_addr.u.prefix4);
- if (PIM_DEBUG_PIM_TRACE_DETAIL)
- zlog_debug ("ifp name: %s, pim nbr: %p", ifp->name, nbr);
- if (!nbr && !if_is_loopback (ifp))
- {
- if (i == mod_val)
- mod_val++;
- i++;
- if (PIM_DEBUG_ZEBRA)
- {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump ("<addr?>", addr, addr_str,
- sizeof (addr_str));
- zlog_debug ("%s: NBR not found on input interface %s (RPF for source %s)",
- __PRETTY_FUNCTION__, ifp->name, addr_str);
- }
- continue;
- }
- }
-
- if (i == mod_val)
- {
- if (PIM_DEBUG_ZEBRA)
- {
- char nexthop_str[PREFIX_STRLEN];
- char addr_str[INET_ADDRSTRLEN];
- pim_addr_dump ("<nexthop?>", &nexthop_tab[i].nexthop_addr,
- nexthop_str, sizeof (nexthop_str));
- pim_inet4_dump ("<addr?>", addr, addr_str, sizeof (addr_str));
- zlog_debug ("%s %s: found nhop %s for addr %s interface %s metric %d dist %d",
- __FILE__, __PRETTY_FUNCTION__, nexthop_str, addr_str,
- ifp->name, nexthop_tab[i].route_metric,
- nexthop_tab[i].protocol_distance);
- }
- /* update nextop data */
- nexthop->interface = ifp;
- nexthop->mrib_nexthop_addr = nexthop_tab[i].nexthop_addr;
- nexthop->mrib_metric_preference = nexthop_tab[i].protocol_distance;
- nexthop->mrib_route_metric = nexthop_tab[i].route_metric;
- nexthop->last_lookup = addr;
- nexthop->last_lookup_time = pim_time_monotonic_usec();
- nexthop->nbr = nbr;
- found = 1;
- }
- i++;
- }
- if (found)
- return 0;
- else
- return -1;
+ struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM];
+ struct pim_neighbor *nbr = NULL;
+ int num_ifindex;
+ struct interface *ifp;
+ int first_ifindex;
+ int found = 0;
+ uint8_t i = 0;
+ uint32_t hash_val = 0, mod_val = 0;
+
+ if (PIM_DEBUG_TRACE) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+ zlog_debug("%s: Looking up: %s, last lookup time: %lld",
+ __PRETTY_FUNCTION__, addr_str,
+ nexthop->last_lookup_time);
+ }
+
+ memset(nexthop_tab, 0,
+ sizeof(struct pim_zlookup_nexthop) * MULTIPATH_NUM);
+ num_ifindex = zclient_lookup_nexthop(nexthop_tab, MULTIPATH_NUM, addr,
+ PIM_NEXTHOP_LOOKUP_MAX);
+ if (num_ifindex < 1) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+ zlog_warn(
+ "%s %s: could not find nexthop ifindex for address %s",
+ __FILE__, __PRETTY_FUNCTION__, addr_str);
+ return -1;
+ }
+
+ // If PIM ECMP enable then choose ECMP path.
+ if (qpim_ecmp_enable) {
+ hash_val = pim_compute_ecmp_hash(src, grp);
+ mod_val = hash_val % num_ifindex;
+ if (PIM_DEBUG_PIM_TRACE_DETAIL)
+ zlog_debug("%s: hash_val %u mod_val %u",
+ __PRETTY_FUNCTION__, hash_val, mod_val);
+ }
+
+ while (!found && (i < num_ifindex)) {
+ first_ifindex = nexthop_tab[i].ifindex;
+
+ ifp = if_lookup_by_index(first_ifindex, VRF_DEFAULT);
+ if (!ifp) {
+ if (PIM_DEBUG_ZEBRA) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str,
+ sizeof(addr_str));
+ zlog_debug(
+ "%s %s: could not find interface for ifindex %d (address %s)",
+ __FILE__, __PRETTY_FUNCTION__,
+ first_ifindex, addr_str);
+ }
+ if (i == mod_val)
+ mod_val++;
+ i++;
+ continue;
+ }
+
+ if (!ifp->info) {
+ if (PIM_DEBUG_ZEBRA) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str,
+ sizeof(addr_str));
+ zlog_debug(
+ "%s: multicast not enabled on input interface %s (ifindex=%d, RPF for source %s)",
+ __PRETTY_FUNCTION__, ifp->name,
+ first_ifindex, addr_str);
+ }
+ if (i == mod_val)
+ mod_val++;
+ i++;
+ continue;
+ }
+ if (neighbor_needed && !pim_if_connected_to_source(ifp, addr)) {
+ nbr = pim_neighbor_find(
+ ifp, nexthop_tab[i].nexthop_addr.u.prefix4);
+ if (PIM_DEBUG_PIM_TRACE_DETAIL)
+ zlog_debug("ifp name: %s, pim nbr: %p",
+ ifp->name, nbr);
+ if (!nbr && !if_is_loopback(ifp)) {
+ if (i == mod_val)
+ mod_val++;
+ i++;
+ if (PIM_DEBUG_ZEBRA) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr,
+ addr_str,
+ sizeof(addr_str));
+ zlog_debug(
+ "%s: NBR not found on input interface %s (RPF for source %s)",
+ __PRETTY_FUNCTION__, ifp->name,
+ addr_str);
+ }
+ continue;
+ }
+ }
+
+ if (i == mod_val) {
+ if (PIM_DEBUG_ZEBRA) {
+ char nexthop_str[PREFIX_STRLEN];
+ char addr_str[INET_ADDRSTRLEN];
+ pim_addr_dump("<nexthop?>",
+ &nexthop_tab[i].nexthop_addr,
+ nexthop_str, sizeof(nexthop_str));
+ pim_inet4_dump("<addr?>", addr, addr_str,
+ sizeof(addr_str));
+ zlog_debug(
+ "%s %s: found nhop %s for addr %s interface %s metric %d dist %d",
+ __FILE__, __PRETTY_FUNCTION__,
+ nexthop_str, addr_str, ifp->name,
+ nexthop_tab[i].route_metric,
+ nexthop_tab[i].protocol_distance);
+ }
+ /* update nextop data */
+ nexthop->interface = ifp;
+ nexthop->mrib_nexthop_addr =
+ nexthop_tab[i].nexthop_addr;
+ nexthop->mrib_metric_preference =
+ nexthop_tab[i].protocol_distance;
+ nexthop->mrib_route_metric =
+ nexthop_tab[i].route_metric;
+ nexthop->last_lookup = addr;
+ nexthop->last_lookup_time = pim_time_monotonic_usec();
+ nexthop->nbr = nbr;
+ found = 1;
+ }
+ i++;
+ }
+ if (found)
+ return 0;
+ else
+ return -1;
}
-int pim_ecmp_fib_lookup_if_vif_index(struct in_addr addr,
- struct prefix *src, struct prefix *grp)
+int pim_ecmp_fib_lookup_if_vif_index(struct in_addr addr, struct prefix *src,
+ struct prefix *grp)
{
- struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM];
- int num_ifindex;
- int vif_index;
- ifindex_t first_ifindex;
- uint32_t hash_val = 0, mod_val = 0;
-
- memset (nexthop_tab, 0, sizeof (struct pim_zlookup_nexthop) * MULTIPATH_NUM);
- num_ifindex = zclient_lookup_nexthop(nexthop_tab, MULTIPATH_NUM, addr,
- PIM_NEXTHOP_LOOKUP_MAX);
- if (num_ifindex < 1)
- {
- if (PIM_DEBUG_ZEBRA)
- {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_debug("%s %s: could not find nexthop ifindex for address %s",
- __FILE__, __PRETTY_FUNCTION__,
- addr_str);
- }
- return -1;
- }
-
- //If PIM ECMP enable then choose ECMP path.
- if (qpim_ecmp_enable)
- {
- hash_val = pim_compute_ecmp_hash (src, grp);
- mod_val = hash_val % num_ifindex;
- if (PIM_DEBUG_PIM_TRACE_DETAIL)
- zlog_debug ("%s: hash_val %u mod_val %u",
- __PRETTY_FUNCTION__, hash_val, mod_val);
- }
-
- first_ifindex = nexthop_tab[mod_val].ifindex;
-
- if (PIM_DEBUG_ZEBRA)
- {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", addr, addr_str, sizeof(addr_str));
- zlog_debug("%s %s: found nexthop ifindex=%d (interface %s) for address %s",
- __FILE__, __PRETTY_FUNCTION__,
- first_ifindex, ifindex2ifname(first_ifindex, VRF_DEFAULT), addr_str);
- }
-
- vif_index = pim_if_find_vifindex_by_ifindex(first_ifindex);
-
- if (vif_index < 0)
- {
- if (PIM_DEBUG_ZEBRA)
- {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_debug("%s %s: low vif_index=%d < 1 nexthop for address %s",
- __FILE__, __PRETTY_FUNCTION__,
- vif_index, addr_str);
- }
- return -2;
- }
-
- return vif_index;
+ struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM];
+ int num_ifindex;
+ int vif_index;
+ ifindex_t first_ifindex;
+ uint32_t hash_val = 0, mod_val = 0;
+
+ memset(nexthop_tab, 0,
+ sizeof(struct pim_zlookup_nexthop) * MULTIPATH_NUM);
+ num_ifindex = zclient_lookup_nexthop(nexthop_tab, MULTIPATH_NUM, addr,
+ PIM_NEXTHOP_LOOKUP_MAX);
+ if (num_ifindex < 1) {
+ if (PIM_DEBUG_ZEBRA) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str,
+ sizeof(addr_str));
+ zlog_debug(
+ "%s %s: could not find nexthop ifindex for address %s",
+ __FILE__, __PRETTY_FUNCTION__, addr_str);
+ }
+ return -1;
+ }
+
+ // If PIM ECMP enable then choose ECMP path.
+ if (qpim_ecmp_enable) {
+ hash_val = pim_compute_ecmp_hash(src, grp);
+ mod_val = hash_val % num_ifindex;
+ if (PIM_DEBUG_PIM_TRACE_DETAIL)
+ zlog_debug("%s: hash_val %u mod_val %u",
+ __PRETTY_FUNCTION__, hash_val, mod_val);
+ }
+
+ first_ifindex = nexthop_tab[mod_val].ifindex;
+
+ if (PIM_DEBUG_ZEBRA) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<ifaddr?>", addr, addr_str, sizeof(addr_str));
+ zlog_debug(
+ "%s %s: found nexthop ifindex=%d (interface %s) for address %s",
+ __FILE__, __PRETTY_FUNCTION__, first_ifindex,
+ ifindex2ifname(first_ifindex, VRF_DEFAULT), addr_str);
+ }
+
+ vif_index = pim_if_find_vifindex_by_ifindex(first_ifindex);
+
+ if (vif_index < 0) {
+ if (PIM_DEBUG_ZEBRA) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str,
+ sizeof(addr_str));
+ zlog_debug(
+ "%s %s: low vif_index=%d < 1 nexthop for address %s",
+ __FILE__, __PRETTY_FUNCTION__, vif_index,
+ addr_str);
+ }
+ return -2;
+ }
+
+ return vif_index;
}
diff --git a/pimd/pim_nht.h b/pimd/pim_nht.h
index 6bd224992..fb8d83623 100644
--- a/pimd/pim_nht.h
+++ b/pimd/pim_nht.h
@@ -30,42 +30,42 @@
#include "pim_rpf.h"
/* PIM nexthop cache value structure. */
-struct pim_nexthop_cache
-{
- struct pim_rpf rpf;
- /* IGP route's metric. */
- u_int32_t metric;
- uint32_t distance;
- /* Nexthop number and nexthop linked list. */
- u_char nexthop_num;
- struct nexthop *nexthop;
- int64_t last_update;
- u_int16_t flags;
+struct pim_nexthop_cache {
+ struct pim_rpf rpf;
+ /* IGP route's metric. */
+ u_int32_t metric;
+ uint32_t distance;
+ /* Nexthop number and nexthop linked list. */
+ u_char nexthop_num;
+ struct nexthop *nexthop;
+ int64_t last_update;
+ u_int16_t flags;
#define PIM_NEXTHOP_VALID (1 << 0)
- struct list *rp_list;
- struct list *upstream_list;
+ struct list *rp_list;
+ struct list *upstream_list;
};
-int pim_parse_nexthop_update (int command, struct zclient *zclient,
- zebra_size_t length, vrf_id_t vrf_id);
-int pim_find_or_track_nexthop (struct prefix *addr, struct pim_upstream *up,
- struct rp_info *rp, struct pim_nexthop_cache *out_pnc);
-void pim_delete_tracked_nexthop (struct prefix *addr, struct pim_upstream *up,
- struct rp_info *rp);
-struct pim_nexthop_cache *pim_nexthop_cache_add (struct pim_rpf *rpf_addr);
-struct pim_nexthop_cache *pim_nexthop_cache_find (struct pim_rpf *rpf);
-uint32_t pim_compute_ecmp_hash (struct prefix *src, struct prefix *grp);
-int pim_ecmp_nexthop_search (struct pim_nexthop_cache * pnc,
- struct pim_nexthop *nexthop, struct prefix *src,
- struct prefix *grp, int neighbor_needed);
-int pim_ecmp_nexthop_lookup (struct pim_nexthop *nexthop, struct in_addr addr,
- struct prefix *src, struct prefix *grp,
- int neighbor_needed);
-void pim_sendmsg_zebra_rnh (struct zclient *zclient, struct pim_nexthop_cache *pnc,
- int command);
-int pim_update_rp_nh (struct pim_nexthop_cache *pnc);
-void pim_resolve_upstream_nh (struct prefix *nht_p);
-int pim_ecmp_fib_lookup_if_vif_index(struct in_addr addr,
- struct prefix *src, struct prefix *grp);
+int pim_parse_nexthop_update(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id);
+int pim_find_or_track_nexthop(struct prefix *addr, struct pim_upstream *up,
+ struct rp_info *rp,
+ struct pim_nexthop_cache *out_pnc);
+void pim_delete_tracked_nexthop(struct prefix *addr, struct pim_upstream *up,
+ struct rp_info *rp);
+struct pim_nexthop_cache *pim_nexthop_cache_add(struct pim_rpf *rpf_addr);
+struct pim_nexthop_cache *pim_nexthop_cache_find(struct pim_rpf *rpf);
+uint32_t pim_compute_ecmp_hash(struct prefix *src, struct prefix *grp);
+int pim_ecmp_nexthop_search(struct pim_nexthop_cache *pnc,
+ struct pim_nexthop *nexthop, struct prefix *src,
+ struct prefix *grp, int neighbor_needed);
+int pim_ecmp_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr,
+ struct prefix *src, struct prefix *grp,
+ int neighbor_needed);
+void pim_sendmsg_zebra_rnh(struct zclient *zclient,
+ struct pim_nexthop_cache *pnc, int command);
+int pim_update_rp_nh(struct pim_nexthop_cache *pnc);
+void pim_resolve_upstream_nh(struct prefix *nht_p);
+int pim_ecmp_fib_lookup_if_vif_index(struct in_addr addr, struct prefix *src,
+ struct prefix *grp);
#endif
diff --git a/pimd/pim_oil.c b/pimd/pim_oil.c
index 66be2be6f..aeef0ff4e 100644
--- a/pimd/pim_oil.c
+++ b/pimd/pim_oil.c
@@ -35,435 +35,477 @@
struct list *pim_channel_oil_list = NULL;
struct hash *pim_channel_oil_hash = NULL;
-char *
-pim_channel_oil_dump (struct channel_oil *c_oil, char *buf, size_t size)
+char *pim_channel_oil_dump(struct channel_oil *c_oil, char *buf, size_t size)
{
- struct prefix_sg sg;
- int i;
-
- memset (buf, 0, size);
- sg.src = c_oil->oil.mfcc_origin;
- sg.grp = c_oil->oil.mfcc_mcastgrp;
- sprintf(buf, "%s IIF: %d, OIFS: ",
- pim_str_sg_dump (&sg), c_oil->oil.mfcc_parent);
-
- for (i = 0 ; i < MAXVIFS ; i++)
- {
- if (c_oil->oil.mfcc_ttls[i] != 0)
- {
- char buf1[10];
- sprintf(buf1, "%d ", i);
- strcat(buf, buf1);
- }
- }
-
- return buf;
+ struct prefix_sg sg;
+ int i;
+
+ memset(buf, 0, size);
+ sg.src = c_oil->oil.mfcc_origin;
+ sg.grp = c_oil->oil.mfcc_mcastgrp;
+ sprintf(buf, "%s IIF: %d, OIFS: ", pim_str_sg_dump(&sg),
+ c_oil->oil.mfcc_parent);
+
+ for (i = 0; i < MAXVIFS; i++) {
+ if (c_oil->oil.mfcc_ttls[i] != 0) {
+ char buf1[10];
+ sprintf(buf1, "%d ", i);
+ strcat(buf, buf1);
+ }
+ }
+
+ return buf;
}
-static int
-pim_channel_oil_compare (struct channel_oil *c1, struct channel_oil *c2)
+static int pim_channel_oil_compare(struct channel_oil *c1,
+ struct channel_oil *c2)
{
- if (ntohl(c1->oil.mfcc_mcastgrp.s_addr) < ntohl(c2->oil.mfcc_mcastgrp.s_addr))
- return -1;
+ if (ntohl(c1->oil.mfcc_mcastgrp.s_addr)
+ < ntohl(c2->oil.mfcc_mcastgrp.s_addr))
+ return -1;
- if (ntohl(c1->oil.mfcc_mcastgrp.s_addr) > ntohl(c2->oil.mfcc_mcastgrp.s_addr))
- return 1;
+ if (ntohl(c1->oil.mfcc_mcastgrp.s_addr)
+ > ntohl(c2->oil.mfcc_mcastgrp.s_addr))
+ return 1;
- if (ntohl(c1->oil.mfcc_origin.s_addr) < ntohl(c2->oil.mfcc_origin.s_addr))
- return -1;
+ if (ntohl(c1->oil.mfcc_origin.s_addr)
+ < ntohl(c2->oil.mfcc_origin.s_addr))
+ return -1;
- if (ntohl(c1->oil.mfcc_origin.s_addr) > ntohl(c2->oil.mfcc_origin.s_addr))
- return 1;
+ if (ntohl(c1->oil.mfcc_origin.s_addr)
+ > ntohl(c2->oil.mfcc_origin.s_addr))
+ return 1;
- return 0;
+ return 0;
}
-static int
-pim_oil_equal (const void *arg1, const void *arg2)
+static int pim_oil_equal(const void *arg1, const void *arg2)
{
- const struct channel_oil *c1 = (const struct channel_oil *)arg1;
- const struct channel_oil *c2 = (const struct channel_oil *)arg2;
+ const struct channel_oil *c1 = (const struct channel_oil *)arg1;
+ const struct channel_oil *c2 = (const struct channel_oil *)arg2;
- if ((c1->oil.mfcc_mcastgrp.s_addr == c2->oil.mfcc_mcastgrp.s_addr) &&
- (c1->oil.mfcc_origin.s_addr == c2->oil.mfcc_origin.s_addr))
- return 1;
+ if ((c1->oil.mfcc_mcastgrp.s_addr == c2->oil.mfcc_mcastgrp.s_addr)
+ && (c1->oil.mfcc_origin.s_addr == c2->oil.mfcc_origin.s_addr))
+ return 1;
- return 0;
+ return 0;
}
-static unsigned int
-pim_oil_hash_key (void *arg)
+static unsigned int pim_oil_hash_key(void *arg)
{
- struct channel_oil *oil = (struct channel_oil *)arg;
+ struct channel_oil *oil = (struct channel_oil *)arg;
- return jhash_2words (oil->oil.mfcc_mcastgrp.s_addr, oil->oil.mfcc_origin.s_addr, 0);
+ return jhash_2words(oil->oil.mfcc_mcastgrp.s_addr,
+ oil->oil.mfcc_origin.s_addr, 0);
}
-void
-pim_oil_init (void)
+void pim_oil_init(void)
{
- pim_channel_oil_hash = hash_create_size (8192, pim_oil_hash_key,
- pim_oil_equal, NULL);
-
- pim_channel_oil_list = list_new();
- if (!pim_channel_oil_list) {
- zlog_err("%s %s: failure: channel_oil_list=list_new()",
- __FILE__, __PRETTY_FUNCTION__);
- return;
- }
- pim_channel_oil_list->del = (void (*)(void *)) pim_channel_oil_free;
- pim_channel_oil_list->cmp = (int (*)(void *, void *)) pim_channel_oil_compare;
+ pim_channel_oil_hash =
+ hash_create_size(8192, pim_oil_hash_key, pim_oil_equal, NULL);
+
+ pim_channel_oil_list = list_new();
+ if (!pim_channel_oil_list) {
+ zlog_err("%s %s: failure: channel_oil_list=list_new()",
+ __FILE__, __PRETTY_FUNCTION__);
+ return;
+ }
+ pim_channel_oil_list->del = (void (*)(void *))pim_channel_oil_free;
+ pim_channel_oil_list->cmp =
+ (int (*)(void *, void *))pim_channel_oil_compare;
}
-void
-pim_oil_terminate (void)
+void pim_oil_terminate(void)
{
- if (pim_channel_oil_list)
- list_free(pim_channel_oil_list);
- pim_channel_oil_list = NULL;
+ if (pim_channel_oil_list)
+ list_free(pim_channel_oil_list);
+ pim_channel_oil_list = NULL;
- if (pim_channel_oil_hash)
- hash_free (pim_channel_oil_hash);
- pim_channel_oil_hash = NULL;
+ if (pim_channel_oil_hash)
+ hash_free(pim_channel_oil_hash);
+ pim_channel_oil_hash = NULL;
}
void pim_channel_oil_free(struct channel_oil *c_oil)
{
- XFREE(MTYPE_PIM_CHANNEL_OIL, c_oil);
+ XFREE(MTYPE_PIM_CHANNEL_OIL, c_oil);
}
-static struct channel_oil *
-pim_find_channel_oil(struct prefix_sg *sg)
+static struct channel_oil *pim_find_channel_oil(struct prefix_sg *sg)
{
- struct channel_oil *c_oil = NULL;
- struct channel_oil lookup;
+ struct channel_oil *c_oil = NULL;
+ struct channel_oil lookup;
- lookup.oil.mfcc_mcastgrp = sg->grp;
- lookup.oil.mfcc_origin = sg->src;
+ lookup.oil.mfcc_mcastgrp = sg->grp;
+ lookup.oil.mfcc_origin = sg->src;
- c_oil = hash_lookup (pim_channel_oil_hash, &lookup);
+ c_oil = hash_lookup(pim_channel_oil_hash, &lookup);
- return c_oil;
+ return c_oil;
}
struct channel_oil *pim_channel_oil_add(struct prefix_sg *sg,
int input_vif_index)
{
- struct channel_oil *c_oil;
- struct interface *ifp;
-
- c_oil = pim_find_channel_oil(sg);
- if (c_oil) {
- if (c_oil->oil.mfcc_parent != input_vif_index)
- {
- c_oil->oil_inherited_rescan = 1;
- if (PIM_DEBUG_MROUTE)
- zlog_debug ("%s: Existing channel oil %s points to %d, modifying to point at %d",
- __PRETTY_FUNCTION__, pim_str_sg_dump(sg), c_oil->oil.mfcc_parent, input_vif_index);
- }
- c_oil->oil.mfcc_parent = input_vif_index;
- ++c_oil->oil_ref_count;
- c_oil->up = pim_upstream_find(sg); //channel might be present prior to upstream
- return c_oil;
- }
-
- ifp = pim_if_find_by_vif_index(input_vif_index);
- if (!ifp) {
- /* warning only */
- zlog_warn("%s: (S,G)=%s could not find input interface for input_vif_index=%d",
- __PRETTY_FUNCTION__,
- pim_str_sg_dump (sg), input_vif_index);
- }
-
- c_oil = XCALLOC(MTYPE_PIM_CHANNEL_OIL, sizeof(*c_oil));
- if (!c_oil) {
- zlog_err("PIM XCALLOC(%zu) failure", sizeof(*c_oil));
- return NULL;
- }
-
- c_oil->oil.mfcc_mcastgrp = sg->grp;
- c_oil->oil.mfcc_origin = sg->src;
- c_oil = hash_get (pim_channel_oil_hash, c_oil, hash_alloc_intern);
-
- c_oil->oil.mfcc_parent = input_vif_index;
- c_oil->oil_ref_count = 1;
- c_oil->installed = 0;
- c_oil->up = pim_upstream_find(sg);
-
- listnode_add_sort(pim_channel_oil_list, c_oil);
-
- return c_oil;
+ struct channel_oil *c_oil;
+ struct interface *ifp;
+
+ c_oil = pim_find_channel_oil(sg);
+ if (c_oil) {
+ if (c_oil->oil.mfcc_parent != input_vif_index) {
+ c_oil->oil_inherited_rescan = 1;
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug(
+ "%s: Existing channel oil %s points to %d, modifying to point at %d",
+ __PRETTY_FUNCTION__,
+ pim_str_sg_dump(sg),
+ c_oil->oil.mfcc_parent,
+ input_vif_index);
+ }
+ c_oil->oil.mfcc_parent = input_vif_index;
+ ++c_oil->oil_ref_count;
+ c_oil->up = pim_upstream_find(
+ sg); // channel might be present prior to upstream
+ return c_oil;
+ }
+
+ ifp = pim_if_find_by_vif_index(input_vif_index);
+ if (!ifp) {
+ /* warning only */
+ zlog_warn(
+ "%s: (S,G)=%s could not find input interface for input_vif_index=%d",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(sg),
+ input_vif_index);
+ }
+
+ c_oil = XCALLOC(MTYPE_PIM_CHANNEL_OIL, sizeof(*c_oil));
+ if (!c_oil) {
+ zlog_err("PIM XCALLOC(%zu) failure", sizeof(*c_oil));
+ return NULL;
+ }
+
+ c_oil->oil.mfcc_mcastgrp = sg->grp;
+ c_oil->oil.mfcc_origin = sg->src;
+ c_oil = hash_get(pim_channel_oil_hash, c_oil, hash_alloc_intern);
+
+ c_oil->oil.mfcc_parent = input_vif_index;
+ c_oil->oil_ref_count = 1;
+ c_oil->installed = 0;
+ c_oil->up = pim_upstream_find(sg);
+
+ listnode_add_sort(pim_channel_oil_list, c_oil);
+
+ return c_oil;
}
void pim_channel_oil_del(struct channel_oil *c_oil)
{
- --c_oil->oil_ref_count;
-
- if (c_oil->oil_ref_count < 1) {
- /*
- * notice that listnode_delete() can't be moved
- * into pim_channel_oil_free() because the later is
- * called by list_delete_all_node()
- */
- c_oil->up = NULL;
- listnode_delete(pim_channel_oil_list, c_oil);
- hash_release (pim_channel_oil_hash, c_oil);
-
- pim_channel_oil_free(c_oil);
- }
+ --c_oil->oil_ref_count;
+
+ if (c_oil->oil_ref_count < 1) {
+ /*
+ * notice that listnode_delete() can't be moved
+ * into pim_channel_oil_free() because the later is
+ * called by list_delete_all_node()
+ */
+ c_oil->up = NULL;
+ listnode_delete(pim_channel_oil_list, c_oil);
+ hash_release(pim_channel_oil_hash, c_oil);
+
+ pim_channel_oil_free(c_oil);
+ }
}
-int
-pim_channel_del_oif (struct channel_oil *channel_oil,
- struct interface *oif,
- uint32_t proto_mask)
+int pim_channel_del_oif(struct channel_oil *channel_oil, struct interface *oif,
+ uint32_t proto_mask)
{
- struct pim_interface *pim_ifp;
-
- zassert (channel_oil);
- zassert (oif);
-
- pim_ifp = oif->info;
-
- /*
- * Don't do anything if we've been asked to remove a source
- * that is not actually on it.
- */
- if (!(channel_oil->oif_flags[pim_ifp->mroute_vif_index] & proto_mask))
- {
- if (PIM_DEBUG_MROUTE)
- {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- zlog_debug("%s %s: no existing protocol mask %u(%u) for requested OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)",
- __FILE__, __PRETTY_FUNCTION__,
- proto_mask, channel_oil->oif_flags[pim_ifp->mroute_vif_index],
- oif->name, pim_ifp->mroute_vif_index,
- channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index],
- source_str, group_str);
+ struct pim_interface *pim_ifp;
+
+ zassert(channel_oil);
+ zassert(oif);
+
+ pim_ifp = oif->info;
+
+ /*
+ * Don't do anything if we've been asked to remove a source
+ * that is not actually on it.
+ */
+ if (!(channel_oil->oif_flags[pim_ifp->mroute_vif_index] & proto_mask)) {
+ if (PIM_DEBUG_MROUTE) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>",
+ channel_oil->oil.mfcc_mcastgrp,
+ group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>",
+ channel_oil->oil.mfcc_origin, source_str,
+ sizeof(source_str));
+ zlog_debug(
+ "%s %s: no existing protocol mask %u(%u) for requested OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)",
+ __FILE__, __PRETTY_FUNCTION__, proto_mask,
+ channel_oil
+ ->oif_flags[pim_ifp->mroute_vif_index],
+ oif->name, pim_ifp->mroute_vif_index,
+ channel_oil->oil
+ .mfcc_ttls[pim_ifp->mroute_vif_index],
+ source_str, group_str);
+ }
+ return 0;
+ }
+
+ channel_oil->oif_flags[pim_ifp->mroute_vif_index] &= ~proto_mask;
+
+ if (channel_oil->oif_flags[pim_ifp->mroute_vif_index]) {
+ if (PIM_DEBUG_MROUTE) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>",
+ channel_oil->oil.mfcc_mcastgrp,
+ group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>",
+ channel_oil->oil.mfcc_origin, source_str,
+ sizeof(source_str));
+ zlog_debug(
+ "%s %s: other protocol masks remain for requested OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)",
+ __FILE__, __PRETTY_FUNCTION__, oif->name,
+ pim_ifp->mroute_vif_index,
+ channel_oil->oil
+ .mfcc_ttls[pim_ifp->mroute_vif_index],
+ source_str, group_str);
+ }
+ return 0;
+ }
+
+ channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] = 0;
+
+ if (pim_mroute_add(channel_oil, __PRETTY_FUNCTION__)) {
+ if (PIM_DEBUG_MROUTE) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>",
+ channel_oil->oil.mfcc_mcastgrp,
+ group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>",
+ channel_oil->oil.mfcc_origin, source_str,
+ sizeof(source_str));
+ zlog_debug(
+ "%s %s: could not remove output interface %s (vif_index=%d) for channel (S,G)=(%s,%s)",
+ __FILE__, __PRETTY_FUNCTION__, oif->name,
+ pim_ifp->mroute_vif_index, source_str,
+ group_str);
+ }
+ return -1;
}
- return 0;
- }
-
- channel_oil->oif_flags[pim_ifp->mroute_vif_index] &= ~proto_mask;
-
- if (channel_oil->oif_flags[pim_ifp->mroute_vif_index])
- {
- if (PIM_DEBUG_MROUTE)
- {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- zlog_debug("%s %s: other protocol masks remain for requested OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)",
- __FILE__, __PRETTY_FUNCTION__,
- oif->name, pim_ifp->mroute_vif_index,
- channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index],
- source_str, group_str);
+
+ --channel_oil->oil_size;
+
+ if (PIM_DEBUG_MROUTE) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp,
+ group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin,
+ source_str, sizeof(source_str));
+ zlog_debug(
+ "%s %s: (S,G)=(%s,%s): proto_mask=%u IIF:%d OIF=%s vif_index=%d",
+ __FILE__, __PRETTY_FUNCTION__, source_str, group_str,
+ proto_mask, channel_oil->oil.mfcc_parent, oif->name,
+ pim_ifp->mroute_vif_index);
}
- return 0;
- }
-
- channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] = 0;
-
- if (pim_mroute_add (channel_oil, __PRETTY_FUNCTION__)) {
- if (PIM_DEBUG_MROUTE)
- {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- zlog_debug("%s %s: could not remove output interface %s (vif_index=%d) for channel (S,G)=(%s,%s)",
- __FILE__, __PRETTY_FUNCTION__,
- oif->name, pim_ifp->mroute_vif_index,
- source_str, group_str);
- }
- return -1;
- }
-
- --channel_oil->oil_size;
-
- if (PIM_DEBUG_MROUTE)
- {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- zlog_debug("%s %s: (S,G)=(%s,%s): proto_mask=%u IIF:%d OIF=%s vif_index=%d",
- __FILE__, __PRETTY_FUNCTION__,
- source_str, group_str,
- proto_mask, channel_oil->oil.mfcc_parent ,oif->name, pim_ifp->mroute_vif_index);
- }
-
- return 0;
+
+ return 0;
}
-int pim_channel_add_oif(struct channel_oil *channel_oil,
- struct interface *oif,
- uint32_t proto_mask)
+int pim_channel_add_oif(struct channel_oil *channel_oil, struct interface *oif,
+ uint32_t proto_mask)
{
- struct pim_interface *pim_ifp;
- int old_ttl;
-
- /*
- * If we've gotten here we've gone bad, but let's
- * not take down pim
- */
- if (!channel_oil)
- {
- zlog_warn ("Attempt to Add OIF for non-existent channel oil");
- return -1;
- }
+ struct pim_interface *pim_ifp;
+ int old_ttl;
+
+ /*
+ * If we've gotten here we've gone bad, but let's
+ * not take down pim
+ */
+ if (!channel_oil) {
+ zlog_warn("Attempt to Add OIF for non-existent channel oil");
+ return -1;
+ }
- pim_ifp = oif->info;
+ pim_ifp = oif->info;
#ifdef PIM_ENFORCE_LOOPFREE_MFC
- /*
- Prevent creating MFC entry with OIF=IIF.
-
- This is a protection against implementation mistakes.
-
- PIM protocol implicitely ensures loopfree multicast topology.
-
- IGMP must be protected against adding looped MFC entries created
- by both source and receiver attached to the same interface. See
- TODO T22.
- */
- if (pim_ifp->mroute_vif_index == channel_oil->oil.mfcc_parent) {
- channel_oil->oil_inherited_rescan = 1;
- if (PIM_DEBUG_MROUTE)
- {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- zlog_debug("%s %s: refusing protocol mask %u request for IIF=OIF=%s (vif_index=%d) for channel (S,G)=(%s,%s)",
- __FILE__, __PRETTY_FUNCTION__,
- proto_mask, oif->name, pim_ifp->mroute_vif_index,
- source_str, group_str);
- }
- return -2;
- }
+ /*
+ Prevent creating MFC entry with OIF=IIF.
+
+ This is a protection against implementation mistakes.
+
+ PIM protocol implicitely ensures loopfree multicast topology.
+
+ IGMP must be protected against adding looped MFC entries created
+ by both source and receiver attached to the same interface. See
+ TODO T22.
+ */
+ if (pim_ifp->mroute_vif_index == channel_oil->oil.mfcc_parent) {
+ channel_oil->oil_inherited_rescan = 1;
+ if (PIM_DEBUG_MROUTE) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>",
+ channel_oil->oil.mfcc_mcastgrp,
+ group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>",
+ channel_oil->oil.mfcc_origin, source_str,
+ sizeof(source_str));
+ zlog_debug(
+ "%s %s: refusing protocol mask %u request for IIF=OIF=%s (vif_index=%d) for channel (S,G)=(%s,%s)",
+ __FILE__, __PRETTY_FUNCTION__, proto_mask,
+ oif->name, pim_ifp->mroute_vif_index,
+ source_str, group_str);
+ }
+ return -2;
+ }
#endif
- /* Prevent single protocol from subscribing same interface to
- channel (S,G) multiple times */
- if (channel_oil->oif_flags[pim_ifp->mroute_vif_index] & proto_mask) {
- if (PIM_DEBUG_MROUTE)
- {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- zlog_debug("%s %s: existing protocol mask %u requested OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)",
- __FILE__, __PRETTY_FUNCTION__,
- proto_mask, oif->name, pim_ifp->mroute_vif_index,
- channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index],
- source_str, group_str);
- }
- return -3;
- }
-
- /* Allow other protocol to request subscription of same interface to
- * channel (S,G), we need to note this information
- */
- if (channel_oil->oif_flags[pim_ifp->mroute_vif_index] & PIM_OIF_FLAG_PROTO_ANY) {
-
- channel_oil->oif_creation[pim_ifp->mroute_vif_index] = pim_time_monotonic_sec();
- channel_oil->oif_flags[pim_ifp->mroute_vif_index] |= proto_mask;
- /* Check the OIF really exists before returning, and only log
- warning otherwise */
- if (channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] < 1) {
- {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- zlog_warn("%s %s: new protocol mask %u requested nonexistent OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)",
- __FILE__, __PRETTY_FUNCTION__,
- proto_mask, oif->name, pim_ifp->mroute_vif_index,
- channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index],
- source_str, group_str);
- }
- }
-
- return 0;
- }
-
- old_ttl = channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index];
-
- if (old_ttl > 0) {
- if (PIM_DEBUG_MROUTE)
- {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- zlog_debug("%s %s: interface %s (vif_index=%d) is existing output for channel (S,G)=(%s,%s)",
- __FILE__, __PRETTY_FUNCTION__,
- oif->name, pim_ifp->mroute_vif_index,
- source_str, group_str);
- }
- return -4;
- }
-
- channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] = PIM_MROUTE_MIN_TTL;
-
- if (pim_mroute_add(channel_oil, __PRETTY_FUNCTION__)) {
- if (PIM_DEBUG_MROUTE)
- {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- zlog_debug("%s %s: could not add output interface %s (vif_index=%d) for channel (S,G)=(%s,%s)",
- __FILE__, __PRETTY_FUNCTION__,
- oif->name, pim_ifp->mroute_vif_index,
- source_str, group_str);
- }
-
- channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] = old_ttl;
- return -5;
- }
-
- channel_oil->oif_creation[pim_ifp->mroute_vif_index] = pim_time_monotonic_sec();
- ++channel_oil->oil_size;
- channel_oil->oif_flags[pim_ifp->mroute_vif_index] |= proto_mask;
-
- if (PIM_DEBUG_MROUTE) {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- zlog_debug("%s %s: (S,G)=(%s,%s): proto_mask=%u OIF=%s vif_index=%d: DONE",
- __FILE__, __PRETTY_FUNCTION__,
- source_str, group_str,
- proto_mask, oif->name, pim_ifp->mroute_vif_index);
- }
-
- return 0;
+ /* Prevent single protocol from subscribing same interface to
+ channel (S,G) multiple times */
+ if (channel_oil->oif_flags[pim_ifp->mroute_vif_index] & proto_mask) {
+ if (PIM_DEBUG_MROUTE) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>",
+ channel_oil->oil.mfcc_mcastgrp,
+ group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>",
+ channel_oil->oil.mfcc_origin, source_str,
+ sizeof(source_str));
+ zlog_debug(
+ "%s %s: existing protocol mask %u requested OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)",
+ __FILE__, __PRETTY_FUNCTION__, proto_mask,
+ oif->name, pim_ifp->mroute_vif_index,
+ channel_oil->oil
+ .mfcc_ttls[pim_ifp->mroute_vif_index],
+ source_str, group_str);
+ }
+ return -3;
+ }
+
+ /* Allow other protocol to request subscription of same interface to
+ * channel (S,G), we need to note this information
+ */
+ if (channel_oil->oif_flags[pim_ifp->mroute_vif_index]
+ & PIM_OIF_FLAG_PROTO_ANY) {
+
+ channel_oil->oif_creation[pim_ifp->mroute_vif_index] =
+ pim_time_monotonic_sec();
+ channel_oil->oif_flags[pim_ifp->mroute_vif_index] |= proto_mask;
+ /* Check the OIF really exists before returning, and only log
+ warning otherwise */
+ if (channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] < 1) {
+ {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>",
+ channel_oil->oil.mfcc_mcastgrp,
+ group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>",
+ channel_oil->oil.mfcc_origin,
+ source_str, sizeof(source_str));
+ zlog_warn(
+ "%s %s: new protocol mask %u requested nonexistent OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)",
+ __FILE__, __PRETTY_FUNCTION__,
+ proto_mask, oif->name,
+ pim_ifp->mroute_vif_index,
+ channel_oil->oil.mfcc_ttls
+ [pim_ifp->mroute_vif_index],
+ source_str, group_str);
+ }
+ }
+
+ return 0;
+ }
+
+ old_ttl = channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index];
+
+ if (old_ttl > 0) {
+ if (PIM_DEBUG_MROUTE) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>",
+ channel_oil->oil.mfcc_mcastgrp,
+ group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>",
+ channel_oil->oil.mfcc_origin, source_str,
+ sizeof(source_str));
+ zlog_debug(
+ "%s %s: interface %s (vif_index=%d) is existing output for channel (S,G)=(%s,%s)",
+ __FILE__, __PRETTY_FUNCTION__, oif->name,
+ pim_ifp->mroute_vif_index, source_str,
+ group_str);
+ }
+ return -4;
+ }
+
+ channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] =
+ PIM_MROUTE_MIN_TTL;
+
+ if (pim_mroute_add(channel_oil, __PRETTY_FUNCTION__)) {
+ if (PIM_DEBUG_MROUTE) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>",
+ channel_oil->oil.mfcc_mcastgrp,
+ group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>",
+ channel_oil->oil.mfcc_origin, source_str,
+ sizeof(source_str));
+ zlog_debug(
+ "%s %s: could not add output interface %s (vif_index=%d) for channel (S,G)=(%s,%s)",
+ __FILE__, __PRETTY_FUNCTION__, oif->name,
+ pim_ifp->mroute_vif_index, source_str,
+ group_str);
+ }
+
+ channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] = old_ttl;
+ return -5;
+ }
+
+ channel_oil->oif_creation[pim_ifp->mroute_vif_index] =
+ pim_time_monotonic_sec();
+ ++channel_oil->oil_size;
+ channel_oil->oif_flags[pim_ifp->mroute_vif_index] |= proto_mask;
+
+ if (PIM_DEBUG_MROUTE) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp,
+ group_str, sizeof(group_str));
+ pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin,
+ source_str, sizeof(source_str));
+ zlog_debug(
+ "%s %s: (S,G)=(%s,%s): proto_mask=%u OIF=%s vif_index=%d: DONE",
+ __FILE__, __PRETTY_FUNCTION__, source_str, group_str,
+ proto_mask, oif->name, pim_ifp->mroute_vif_index);
+ }
+
+ return 0;
}
-int
-pim_channel_oil_empty (struct channel_oil *c_oil)
+int pim_channel_oil_empty(struct channel_oil *c_oil)
{
- static uint32_t zero[MAXVIFS];
- static int inited = 0;
-
- if (!c_oil)
- return 1;
- /*
- * Not sure that this is necessary, but I would rather ensure
- * that this works.
- */
- if (!inited)
- {
- memset(&zero, 0, sizeof(uint32_t) * MAXVIFS);
- inited = 1;
- }
-
- return !memcmp(c_oil->oif_flags, zero, MAXVIFS * sizeof(uint32_t));
+ static uint32_t zero[MAXVIFS];
+ static int inited = 0;
+
+ if (!c_oil)
+ return 1;
+ /*
+ * Not sure that this is necessary, but I would rather ensure
+ * that this works.
+ */
+ if (!inited) {
+ memset(&zero, 0, sizeof(uint32_t) * MAXVIFS);
+ inited = 1;
+ }
+
+ return !memcmp(c_oil->oif_flags, zero, MAXVIFS * sizeof(uint32_t));
}
diff --git a/pimd/pim_oil.h b/pimd/pim_oil.h
index 02c7e740e..f537062c7 100644
--- a/pimd/pim_oil.h
+++ b/pimd/pim_oil.h
@@ -34,10 +34,9 @@
#define PIM_OIF_FLAG_PROTO_PIM (1 << 1)
#define PIM_OIF_FLAG_PROTO_SOURCE (1 << 2)
#define PIM_OIF_FLAG_PROTO_STAR (1 << 3)
-#define PIM_OIF_FLAG_PROTO_ANY (PIM_OIF_FLAG_PROTO_IGMP | \
- PIM_OIF_FLAG_PROTO_PIM | \
- PIM_OIF_FLAG_PROTO_SOURCE | \
- PIM_OIF_FLAG_PROTO_STAR)
+#define PIM_OIF_FLAG_PROTO_ANY \
+ (PIM_OIF_FLAG_PROTO_IGMP | PIM_OIF_FLAG_PROTO_PIM \
+ | PIM_OIF_FLAG_PROTO_SOURCE | PIM_OIF_FLAG_PROTO_STAR)
/*
* We need a pimreg vif id from the kernel.
@@ -50,16 +49,14 @@
#define PIM_OIF_PIM_REGISTER_VIF 0
#define PIM_MAX_USABLE_VIFS (MAXVIFS - 1)
-
-struct channel_counts
-{
- unsigned long long lastused;
- unsigned long pktcnt;
- unsigned long oldpktcnt;
- unsigned long bytecnt;
- unsigned long oldbytecnt;
- unsigned long wrong_if;
- unsigned long oldwrong_if;
+struct channel_counts {
+ unsigned long long lastused;
+ unsigned long pktcnt;
+ unsigned long oldpktcnt;
+ unsigned long bytecnt;
+ unsigned long oldbytecnt;
+ unsigned long wrong_if;
+ unsigned long oldwrong_if;
};
/*
@@ -70,35 +67,33 @@ struct channel_counts
*/
struct channel_oil {
- struct mfcctl oil;
- int installed;
- int oil_inherited_rescan;
- int oil_size;
- int oil_ref_count;
- time_t oif_creation[MAXVIFS];
- uint32_t oif_flags[MAXVIFS];
- struct channel_counts cc;
- struct pim_upstream *up;
+ struct mfcctl oil;
+ int installed;
+ int oil_inherited_rescan;
+ int oil_size;
+ int oil_ref_count;
+ time_t oif_creation[MAXVIFS];
+ uint32_t oif_flags[MAXVIFS];
+ struct channel_counts cc;
+ struct pim_upstream *up;
};
extern struct list *pim_channel_oil_list;
-void pim_oil_init (void);
-void pim_oil_terminate (void);
+void pim_oil_init(void);
+void pim_oil_terminate(void);
void pim_channel_oil_free(struct channel_oil *c_oil);
struct channel_oil *pim_channel_oil_add(struct prefix_sg *sg,
int input_vif_index);
void pim_channel_oil_del(struct channel_oil *c_oil);
-int pim_channel_add_oif(struct channel_oil *c_oil,
- struct interface *oif,
+int pim_channel_add_oif(struct channel_oil *c_oil, struct interface *oif,
+ uint32_t proto_mask);
+int pim_channel_del_oif(struct channel_oil *c_oil, struct interface *oif,
uint32_t proto_mask);
-int pim_channel_del_oif (struct channel_oil *c_oil,
- struct interface *oif,
- uint32_t proto_mask);
-int pim_channel_oil_empty (struct channel_oil *c_oil);
+int pim_channel_oil_empty(struct channel_oil *c_oil);
-char *pim_channel_oil_dump (struct channel_oil *c_oil, char *buf, size_t size);
+char *pim_channel_oil_dump(struct channel_oil *c_oil, char *buf, size_t size);
#endif /* PIM_OIL_H */
diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c
index f6a5bb122..21892f347 100644
--- a/pimd/pim_pim.c
+++ b/pimd/pim_pim.c
@@ -40,670 +40,673 @@
#include "pim_register.h"
static int on_pim_hello_send(struct thread *t);
-static int pim_hello_send(struct interface *ifp,
- uint16_t holdtime);
+static int pim_hello_send(struct interface *ifp, uint16_t holdtime);
-static
-const char *pim_pim_msgtype2str (enum pim_msg_type type)
+static const char *pim_pim_msgtype2str(enum pim_msg_type type)
{
- switch (type)
- {
- case PIM_MSG_TYPE_HELLO: return "HELLO";
- case PIM_MSG_TYPE_REGISTER: return "REGISTER";
- case PIM_MSG_TYPE_REG_STOP: return "REGSTOP";
- case PIM_MSG_TYPE_JOIN_PRUNE: return "JOINPRUNE";
- case PIM_MSG_TYPE_BOOTSTRAP: return "BOOT";
- case PIM_MSG_TYPE_ASSERT: return "ASSERT";
- case PIM_MSG_TYPE_GRAFT: return "GRAFT";
- case PIM_MSG_TYPE_GRAFT_ACK: return "GACK";
- case PIM_MSG_TYPE_CANDIDATE: return "CANDIDATE";
- }
-
- return "UNKNOWN";
+ switch (type) {
+ case PIM_MSG_TYPE_HELLO:
+ return "HELLO";
+ case PIM_MSG_TYPE_REGISTER:
+ return "REGISTER";
+ case PIM_MSG_TYPE_REG_STOP:
+ return "REGSTOP";
+ case PIM_MSG_TYPE_JOIN_PRUNE:
+ return "JOINPRUNE";
+ case PIM_MSG_TYPE_BOOTSTRAP:
+ return "BOOT";
+ case PIM_MSG_TYPE_ASSERT:
+ return "ASSERT";
+ case PIM_MSG_TYPE_GRAFT:
+ return "GRAFT";
+ case PIM_MSG_TYPE_GRAFT_ACK:
+ return "GACK";
+ case PIM_MSG_TYPE_CANDIDATE:
+ return "CANDIDATE";
+ }
+
+ return "UNKNOWN";
}
static void sock_close(struct interface *ifp)
{
- struct pim_interface *pim_ifp = ifp->info;
-
- if (PIM_DEBUG_PIM_TRACE) {
- if (pim_ifp->t_pim_sock_read) {
- zlog_debug("Cancelling READ event for PIM socket fd=%d on interface %s",
- pim_ifp->pim_sock_fd,
- ifp->name);
- }
- }
- THREAD_OFF(pim_ifp->t_pim_sock_read);
-
- if (PIM_DEBUG_PIM_TRACE) {
- if (pim_ifp->t_pim_hello_timer) {
- zlog_debug("Cancelling PIM hello timer for interface %s",
- ifp->name);
- }
- }
- THREAD_OFF(pim_ifp->t_pim_hello_timer);
-
- if (PIM_DEBUG_PIM_TRACE) {
- zlog_debug("Deleting PIM socket fd=%d on interface %s",
- pim_ifp->pim_sock_fd, ifp->name);
- }
-
- /*
- * If the fd is already deleted no need to do anything here
- */
- if (pim_ifp->pim_sock_fd > 0 && close(pim_ifp->pim_sock_fd)) {
- zlog_warn("Failure closing PIM socket fd=%d on interface %s: errno=%d: %s",
- pim_ifp->pim_sock_fd, ifp->name,
- errno, safe_strerror(errno));
- }
-
- pim_ifp->pim_sock_fd = -1;
- pim_ifp->pim_sock_creation = 0;
+ struct pim_interface *pim_ifp = ifp->info;
+
+ if (PIM_DEBUG_PIM_TRACE) {
+ if (pim_ifp->t_pim_sock_read) {
+ zlog_debug(
+ "Cancelling READ event for PIM socket fd=%d on interface %s",
+ pim_ifp->pim_sock_fd, ifp->name);
+ }
+ }
+ THREAD_OFF(pim_ifp->t_pim_sock_read);
+
+ if (PIM_DEBUG_PIM_TRACE) {
+ if (pim_ifp->t_pim_hello_timer) {
+ zlog_debug(
+ "Cancelling PIM hello timer for interface %s",
+ ifp->name);
+ }
+ }
+ THREAD_OFF(pim_ifp->t_pim_hello_timer);
+
+ if (PIM_DEBUG_PIM_TRACE) {
+ zlog_debug("Deleting PIM socket fd=%d on interface %s",
+ pim_ifp->pim_sock_fd, ifp->name);
+ }
+
+ /*
+ * If the fd is already deleted no need to do anything here
+ */
+ if (pim_ifp->pim_sock_fd > 0 && close(pim_ifp->pim_sock_fd)) {
+ zlog_warn(
+ "Failure closing PIM socket fd=%d on interface %s: errno=%d: %s",
+ pim_ifp->pim_sock_fd, ifp->name, errno,
+ safe_strerror(errno));
+ }
+
+ pim_ifp->pim_sock_fd = -1;
+ pim_ifp->pim_sock_creation = 0;
}
void pim_sock_delete(struct interface *ifp, const char *delete_message)
{
- zlog_info("PIM INTERFACE DOWN: on interface %s: %s",
- ifp->name, delete_message);
-
- if (!ifp->info) {
- zlog_err("%s: %s: but PIM not enabled on interface %s (!)",
- __PRETTY_FUNCTION__, delete_message, ifp->name);
- return;
- }
-
- /*
- RFC 4601: 4.3.1. Sending Hello Messages
-
- Before an interface goes down or changes primary IP address, a Hello
- message with a zero HoldTime should be sent immediately (with the
- old IP address if the IP address changed).
- */
- pim_hello_send(ifp, 0 /* zero-sec holdtime */);
-
- pim_neighbor_delete_all(ifp, delete_message);
-
- sock_close(ifp);
+ zlog_info("PIM INTERFACE DOWN: on interface %s: %s", ifp->name,
+ delete_message);
+
+ if (!ifp->info) {
+ zlog_err("%s: %s: but PIM not enabled on interface %s (!)",
+ __PRETTY_FUNCTION__, delete_message, ifp->name);
+ return;
+ }
+
+ /*
+ RFC 4601: 4.3.1. Sending Hello Messages
+
+ Before an interface goes down or changes primary IP address, a Hello
+ message with a zero HoldTime should be sent immediately (with the
+ old IP address if the IP address changed).
+ */
+ pim_hello_send(ifp, 0 /* zero-sec holdtime */);
+
+ pim_neighbor_delete_all(ifp, delete_message);
+
+ sock_close(ifp);
}
int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len)
{
- struct ip *ip_hdr;
- size_t ip_hlen; /* ip header length in bytes */
- char src_str[INET_ADDRSTRLEN];
- char dst_str[INET_ADDRSTRLEN];
- uint8_t *pim_msg;
- int pim_msg_len;
- uint16_t pim_checksum; /* received checksum */
- uint16_t checksum; /* computed checksum */
- struct pim_neighbor *neigh;
- struct pim_msg_header *header;
-
- if (len < sizeof(*ip_hdr)) {
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug("PIM packet size=%zu shorter than minimum=%zu",
- len, sizeof(*ip_hdr));
- return -1;
- }
-
- ip_hdr = (struct ip *) buf;
- ip_hlen = ip_hdr->ip_hl << 2; /* ip_hl gives length in 4-byte words */
-
- pim_msg = buf + ip_hlen;
- pim_msg_len = len - ip_hlen;
-
- header = (struct pim_msg_header *)pim_msg;
- if (pim_msg_len < PIM_PIM_MIN_LEN) {
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug("PIM message size=%d shorter than minimum=%d",
- pim_msg_len, PIM_PIM_MIN_LEN);
- return -1;
- }
-
- if (header->ver != PIM_PROTO_VERSION) {
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug("Ignoring PIM pkt from %s with unsupported version: %d",
- ifp->name, header->ver);
- return -1;
- }
-
- /* save received checksum */
- pim_checksum = header->checksum;
-
- /* for computing checksum */
- header->checksum = 0;
-
- if (header->type == PIM_MSG_TYPE_REGISTER)
- {
- /* First 8 byte header checksum */
- checksum = in_cksum (pim_msg, PIM_MSG_REGISTER_LEN);
- if (checksum != pim_checksum)
- {
- checksum = in_cksum (pim_msg, pim_msg_len);
- if (checksum != pim_checksum)
- {
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug
- ("Ignoring PIM pkt from %s with invalid checksum: received=%x calculated=%x",
- ifp->name, pim_checksum, checksum);
-
- return -1;
- }
- }
- }
- else
- {
- checksum = in_cksum (pim_msg, pim_msg_len);
- if (checksum != pim_checksum)
- {
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug
- ("Ignoring PIM pkt from %s with invalid checksum: received=%x calculated=%x",
- ifp->name, pim_checksum, checksum);
-
- return -1;
- }
- }
-
- if (PIM_DEBUG_PIM_PACKETS) {
- pim_inet4_dump("<src?>", ip_hdr->ip_src, src_str, sizeof(src_str));
- pim_inet4_dump("<dst?>", ip_hdr->ip_dst, dst_str, sizeof(dst_str));
- zlog_debug("Recv PIM %s packet from %s to %s on %s: ttl=%d pim_version=%d pim_msg_size=%d checksum=%x",
- pim_pim_msgtype2str (header->type), src_str, dst_str, ifp->name,
- ip_hdr->ip_ttl, header->ver, pim_msg_len, checksum);
- if (PIM_DEBUG_PIM_PACKETDUMP_RECV) {
- pim_pkt_dump(__PRETTY_FUNCTION__, pim_msg, pim_msg_len);
- }
- }
-
- switch (header->type)
- {
- case PIM_MSG_TYPE_HELLO:
- return pim_hello_recv (ifp,
- ip_hdr->ip_src,
- pim_msg + PIM_MSG_HEADER_LEN,
- pim_msg_len - PIM_MSG_HEADER_LEN);
- break;
- case PIM_MSG_TYPE_REGISTER:
- return pim_register_recv (ifp,
- ip_hdr->ip_dst,
- ip_hdr->ip_src,
- pim_msg + PIM_MSG_HEADER_LEN,
- pim_msg_len - PIM_MSG_HEADER_LEN);
- break;
- case PIM_MSG_TYPE_REG_STOP:
- return pim_register_stop_recv (pim_msg + PIM_MSG_HEADER_LEN,
- pim_msg_len - PIM_MSG_HEADER_LEN);
- break;
- case PIM_MSG_TYPE_JOIN_PRUNE:
- neigh = pim_neighbor_find(ifp, ip_hdr->ip_src);
- if (!neigh) {
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug("%s %s: non-hello PIM message type=%d from non-neighbor %s on %s",
- __FILE__, __PRETTY_FUNCTION__,
- header->type, src_str, ifp->name);
- return -1;
- }
- pim_neighbor_timer_reset(neigh, neigh->holdtime);
- return pim_joinprune_recv(ifp, neigh,
- ip_hdr->ip_src,
- pim_msg + PIM_MSG_HEADER_LEN,
- pim_msg_len - PIM_MSG_HEADER_LEN);
- break;
- case PIM_MSG_TYPE_ASSERT:
- neigh = pim_neighbor_find(ifp, ip_hdr->ip_src);
- if (!neigh) {
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug("%s %s: non-hello PIM message type=%d from non-neighbor %s on %s",
- __FILE__, __PRETTY_FUNCTION__,
- header->type, src_str, ifp->name);
+ struct ip *ip_hdr;
+ size_t ip_hlen; /* ip header length in bytes */
+ char src_str[INET_ADDRSTRLEN];
+ char dst_str[INET_ADDRSTRLEN];
+ uint8_t *pim_msg;
+ int pim_msg_len;
+ uint16_t pim_checksum; /* received checksum */
+ uint16_t checksum; /* computed checksum */
+ struct pim_neighbor *neigh;
+ struct pim_msg_header *header;
+
+ if (len < sizeof(*ip_hdr)) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "PIM packet size=%zu shorter than minimum=%zu",
+ len, sizeof(*ip_hdr));
+ return -1;
+ }
+
+ ip_hdr = (struct ip *)buf;
+ ip_hlen = ip_hdr->ip_hl << 2; /* ip_hl gives length in 4-byte words */
+
+ pim_msg = buf + ip_hlen;
+ pim_msg_len = len - ip_hlen;
+
+ header = (struct pim_msg_header *)pim_msg;
+ if (pim_msg_len < PIM_PIM_MIN_LEN) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "PIM message size=%d shorter than minimum=%d",
+ pim_msg_len, PIM_PIM_MIN_LEN);
+ return -1;
+ }
+
+ if (header->ver != PIM_PROTO_VERSION) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "Ignoring PIM pkt from %s with unsupported version: %d",
+ ifp->name, header->ver);
+ return -1;
+ }
+
+ /* save received checksum */
+ pim_checksum = header->checksum;
+
+ /* for computing checksum */
+ header->checksum = 0;
+
+ if (header->type == PIM_MSG_TYPE_REGISTER) {
+ /* First 8 byte header checksum */
+ checksum = in_cksum(pim_msg, PIM_MSG_REGISTER_LEN);
+ if (checksum != pim_checksum) {
+ checksum = in_cksum(pim_msg, pim_msg_len);
+ if (checksum != pim_checksum) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "Ignoring PIM pkt from %s with invalid checksum: received=%x calculated=%x",
+ ifp->name, pim_checksum,
+ checksum);
+
+ return -1;
+ }
+ }
+ } else {
+ checksum = in_cksum(pim_msg, pim_msg_len);
+ if (checksum != pim_checksum) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "Ignoring PIM pkt from %s with invalid checksum: received=%x calculated=%x",
+ ifp->name, pim_checksum, checksum);
+
+ return -1;
+ }
+ }
+
+ if (PIM_DEBUG_PIM_PACKETS) {
+ pim_inet4_dump("<src?>", ip_hdr->ip_src, src_str,
+ sizeof(src_str));
+ pim_inet4_dump("<dst?>", ip_hdr->ip_dst, dst_str,
+ sizeof(dst_str));
+ zlog_debug(
+ "Recv PIM %s packet from %s to %s on %s: ttl=%d pim_version=%d pim_msg_size=%d checksum=%x",
+ pim_pim_msgtype2str(header->type), src_str, dst_str,
+ ifp->name, ip_hdr->ip_ttl, header->ver, pim_msg_len,
+ checksum);
+ if (PIM_DEBUG_PIM_PACKETDUMP_RECV) {
+ pim_pkt_dump(__PRETTY_FUNCTION__, pim_msg, pim_msg_len);
+ }
+ }
+
+ switch (header->type) {
+ case PIM_MSG_TYPE_HELLO:
+ return pim_hello_recv(ifp, ip_hdr->ip_src,
+ pim_msg + PIM_MSG_HEADER_LEN,
+ pim_msg_len - PIM_MSG_HEADER_LEN);
+ break;
+ case PIM_MSG_TYPE_REGISTER:
+ return pim_register_recv(ifp, ip_hdr->ip_dst, ip_hdr->ip_src,
+ pim_msg + PIM_MSG_HEADER_LEN,
+ pim_msg_len - PIM_MSG_HEADER_LEN);
+ break;
+ case PIM_MSG_TYPE_REG_STOP:
+ return pim_register_stop_recv(pim_msg + PIM_MSG_HEADER_LEN,
+ pim_msg_len - PIM_MSG_HEADER_LEN);
+ break;
+ case PIM_MSG_TYPE_JOIN_PRUNE:
+ neigh = pim_neighbor_find(ifp, ip_hdr->ip_src);
+ if (!neigh) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "%s %s: non-hello PIM message type=%d from non-neighbor %s on %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ header->type, src_str, ifp->name);
+ return -1;
+ }
+ pim_neighbor_timer_reset(neigh, neigh->holdtime);
+ return pim_joinprune_recv(ifp, neigh, ip_hdr->ip_src,
+ pim_msg + PIM_MSG_HEADER_LEN,
+ pim_msg_len - PIM_MSG_HEADER_LEN);
+ break;
+ case PIM_MSG_TYPE_ASSERT:
+ neigh = pim_neighbor_find(ifp, ip_hdr->ip_src);
+ if (!neigh) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "%s %s: non-hello PIM message type=%d from non-neighbor %s on %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ header->type, src_str, ifp->name);
+ return -1;
+ }
+ pim_neighbor_timer_reset(neigh, neigh->holdtime);
+ return pim_assert_recv(ifp, neigh, ip_hdr->ip_src,
+ pim_msg + PIM_MSG_HEADER_LEN,
+ pim_msg_len - PIM_MSG_HEADER_LEN);
+ break;
+ default:
+ if (PIM_DEBUG_PIM_PACKETS) {
+ zlog_debug(
+ "Recv PIM packet type %d which is not currently understood",
+ header->type);
+ }
+ return -1;
+ }
return -1;
- }
- pim_neighbor_timer_reset(neigh, neigh->holdtime);
- return pim_assert_recv(ifp, neigh,
- ip_hdr->ip_src,
- pim_msg + PIM_MSG_HEADER_LEN,
- pim_msg_len - PIM_MSG_HEADER_LEN);
- break;
- default:
- if (PIM_DEBUG_PIM_PACKETS) {
- zlog_debug("Recv PIM packet type %d which is not currently understood",
- header->type);
- }
- return -1;
- }
- return -1;
}
static void pim_sock_read_on(struct interface *ifp);
static int pim_sock_read(struct thread *t)
{
- struct interface *ifp;
- struct pim_interface *pim_ifp;
- int fd;
- struct sockaddr_in from;
- struct sockaddr_in to;
- socklen_t fromlen = sizeof(from);
- socklen_t tolen = sizeof(to);
- uint8_t buf[PIM_PIM_BUFSIZE_READ];
- int len;
- ifindex_t ifindex = -1;
- int result = -1; /* defaults to bad */
- static long long count = 0;
- int cont = 1;
-
- ifp = THREAD_ARG(t);
- fd = THREAD_FD(t);
-
- pim_ifp = ifp->info;
-
- while (cont)
- {
- len = pim_socket_recvfromto(fd, buf, sizeof(buf),
- &from, &fromlen,
- &to, &tolen,
- &ifindex);
- if (len < 0)
- {
- if (errno == EINTR)
- continue;
- if (errno == EWOULDBLOCK || errno == EAGAIN)
- break;
-
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug ("Received errno: %d %s", errno, safe_strerror (errno));
- goto done;
- }
+ struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ int fd;
+ struct sockaddr_in from;
+ struct sockaddr_in to;
+ socklen_t fromlen = sizeof(from);
+ socklen_t tolen = sizeof(to);
+ uint8_t buf[PIM_PIM_BUFSIZE_READ];
+ int len;
+ ifindex_t ifindex = -1;
+ int result = -1; /* defaults to bad */
+ static long long count = 0;
+ int cont = 1;
+
+ ifp = THREAD_ARG(t);
+ fd = THREAD_FD(t);
+
+ pim_ifp = ifp->info;
+
+ while (cont) {
+ len = pim_socket_recvfromto(fd, buf, sizeof(buf), &from,
+ &fromlen, &to, &tolen, &ifindex);
+ if (len < 0) {
+ if (errno == EINTR)
+ continue;
+ if (errno == EWOULDBLOCK || errno == EAGAIN)
+ break;
+
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug("Received errno: %d %s", errno,
+ safe_strerror(errno));
+ goto done;
+ }
#ifdef PIM_CHECK_RECV_IFINDEX_SANITY
- /* ifindex sanity check */
- if (ifindex != (int) ifp->ifindex) {
- char from_str[INET_ADDRSTRLEN];
- char to_str[INET_ADDRSTRLEN];
- struct interface *recv_ifp;
-
- if (!inet_ntop(AF_INET, &from.sin_addr, from_str , sizeof(from_str)))
- sprintf(from_str, "<from?>");
- if (!inet_ntop(AF_INET, &to.sin_addr, to_str , sizeof(to_str)))
- sprintf(to_str, "<to?>");
-
- recv_ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
- if (recv_ifp) {
- zassert(ifindex == (int) recv_ifp->ifindex);
- }
+ /* ifindex sanity check */
+ if (ifindex != (int)ifp->ifindex) {
+ char from_str[INET_ADDRSTRLEN];
+ char to_str[INET_ADDRSTRLEN];
+ struct interface *recv_ifp;
+
+ if (!inet_ntop(AF_INET, &from.sin_addr, from_str,
+ sizeof(from_str)))
+ sprintf(from_str, "<from?>");
+ if (!inet_ntop(AF_INET, &to.sin_addr, to_str,
+ sizeof(to_str)))
+ sprintf(to_str, "<to?>");
+
+ recv_ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
+ if (recv_ifp) {
+ zassert(ifindex == (int)recv_ifp->ifindex);
+ }
#ifdef PIM_REPORT_RECV_IFINDEX_MISMATCH
- zlog_warn("Interface mismatch: recv PIM pkt from %s to %s on fd=%d: recv_ifindex=%d (%s) sock_ifindex=%d (%s)",
- from_str, to_str, fd,
- ifindex, recv_ifp ? recv_ifp->name : "<if-notfound>",
- ifp->ifindex, ifp->name);
+ zlog_warn(
+ "Interface mismatch: recv PIM pkt from %s to %s on fd=%d: recv_ifindex=%d (%s) sock_ifindex=%d (%s)",
+ from_str, to_str, fd, ifindex,
+ recv_ifp ? recv_ifp->name : "<if-notfound>",
+ ifp->ifindex, ifp->name);
#endif
- goto done;
- }
+ goto done;
+ }
#endif
- int fail = pim_pim_packet(ifp, buf, len);
- if (fail) {
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug("%s: pim_pim_packet() return=%d",
- __PRETTY_FUNCTION__, fail);
- goto done;
- }
-
- count++;
- if (count % qpim_packet_process == 0)
- cont = 0;
- }
+ int fail = pim_pim_packet(ifp, buf, len);
+ if (fail) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug("%s: pim_pim_packet() return=%d",
+ __PRETTY_FUNCTION__, fail);
+ goto done;
+ }
+
+ count++;
+ if (count % qpim_packet_process == 0)
+ cont = 0;
+ }
- result = 0; /* good */
+ result = 0; /* good */
- done:
- pim_sock_read_on(ifp);
+done:
+ pim_sock_read_on(ifp);
- if (result) {
- ++pim_ifp->pim_ifstat_hello_recvfail;
- }
+ if (result) {
+ ++pim_ifp->pim_ifstat_hello_recvfail;
+ }
- return result;
+ return result;
}
static void pim_sock_read_on(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
+ struct pim_interface *pim_ifp;
- zassert(ifp);
- zassert(ifp->info);
+ zassert(ifp);
+ zassert(ifp->info);
- pim_ifp = ifp->info;
+ pim_ifp = ifp->info;
- if (PIM_DEBUG_PIM_TRACE_DETAIL) {
- zlog_debug("Scheduling READ event on PIM socket fd=%d",
- pim_ifp->pim_sock_fd);
- }
- pim_ifp->t_pim_sock_read = NULL;
- thread_add_read(master, pim_sock_read, ifp, pim_ifp->pim_sock_fd,
- &pim_ifp->t_pim_sock_read);
+ if (PIM_DEBUG_PIM_TRACE_DETAIL) {
+ zlog_debug("Scheduling READ event on PIM socket fd=%d",
+ pim_ifp->pim_sock_fd);
+ }
+ pim_ifp->t_pim_sock_read = NULL;
+ thread_add_read(master, pim_sock_read, ifp, pim_ifp->pim_sock_fd,
+ &pim_ifp->t_pim_sock_read);
}
static int pim_sock_open(struct interface *ifp)
{
- int fd;
- struct pim_interface *pim_ifp = ifp->info;
-
- fd = pim_socket_mcast(IPPROTO_PIM, pim_ifp->primary_address, ifp, 0 /* loop=false */);
- if (fd < 0)
- return -1;
-
- if (pim_socket_join(fd, qpim_all_pim_routers_addr, pim_ifp->primary_address, ifp->ifindex)) {
- close(fd);
- return -2;
- }
+ int fd;
+ struct pim_interface *pim_ifp = ifp->info;
+
+ fd = pim_socket_mcast(IPPROTO_PIM, pim_ifp->primary_address, ifp,
+ 0 /* loop=false */);
+ if (fd < 0)
+ return -1;
+
+ if (pim_socket_join(fd, qpim_all_pim_routers_addr,
+ pim_ifp->primary_address, ifp->ifindex)) {
+ close(fd);
+ return -2;
+ }
- return fd;
+ return fd;
}
void pim_ifstat_reset(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
+ struct pim_interface *pim_ifp;
- zassert(ifp);
+ zassert(ifp);
- pim_ifp = ifp->info;
- if (!pim_ifp) {
- return;
- }
+ pim_ifp = ifp->info;
+ if (!pim_ifp) {
+ return;
+ }
- pim_ifp->pim_ifstat_start = pim_time_monotonic_sec();
- pim_ifp->pim_ifstat_hello_sent = 0;
- pim_ifp->pim_ifstat_hello_sendfail = 0;
- pim_ifp->pim_ifstat_hello_recv = 0;
- pim_ifp->pim_ifstat_hello_recvfail = 0;
+ pim_ifp->pim_ifstat_start = pim_time_monotonic_sec();
+ pim_ifp->pim_ifstat_hello_sent = 0;
+ pim_ifp->pim_ifstat_hello_sendfail = 0;
+ pim_ifp->pim_ifstat_hello_recv = 0;
+ pim_ifp->pim_ifstat_hello_recvfail = 0;
}
void pim_sock_reset(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
-
- zassert(ifp);
- zassert(ifp->info);
-
- pim_ifp = ifp->info;
-
- pim_ifp->primary_address = pim_find_primary_addr(ifp);
-
- pim_ifp->pim_sock_fd = -1;
- pim_ifp->pim_sock_creation = 0;
- pim_ifp->t_pim_sock_read = NULL;
-
- pim_ifp->t_pim_hello_timer = NULL;
- pim_ifp->pim_hello_period = PIM_DEFAULT_HELLO_PERIOD;
- pim_ifp->pim_default_holdtime = -1; /* unset: means 3.5 * pim_hello_period */
- pim_ifp->pim_triggered_hello_delay = PIM_DEFAULT_TRIGGERED_HELLO_DELAY;
- pim_ifp->pim_dr_priority = PIM_DEFAULT_DR_PRIORITY;
- pim_ifp->pim_propagation_delay_msec = PIM_DEFAULT_PROPAGATION_DELAY_MSEC;
- pim_ifp->pim_override_interval_msec = PIM_DEFAULT_OVERRIDE_INTERVAL_MSEC;
- if (PIM_DEFAULT_CAN_DISABLE_JOIN_SUPPRESSION) {
- PIM_IF_DO_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options);
- }
- else {
- PIM_IF_DONT_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options);
- }
-
- /* neighbors without lan_delay */
- pim_ifp->pim_number_of_nonlandelay_neighbors = 0;
- pim_ifp->pim_neighbors_highest_propagation_delay_msec = 0;
- pim_ifp->pim_neighbors_highest_override_interval_msec = 0;
-
- /* DR Election */
- pim_ifp->pim_dr_election_last = 0; /* timestamp */
- pim_ifp->pim_dr_election_count = 0;
- pim_ifp->pim_dr_election_changes = 0;
- pim_ifp->pim_dr_num_nondrpri_neighbors = 0; /* neighbors without dr_pri */
- pim_ifp->pim_dr_addr = pim_ifp->primary_address;
-
- pim_ifstat_reset(ifp);
+ struct pim_interface *pim_ifp;
+
+ zassert(ifp);
+ zassert(ifp->info);
+
+ pim_ifp = ifp->info;
+
+ pim_ifp->primary_address = pim_find_primary_addr(ifp);
+
+ pim_ifp->pim_sock_fd = -1;
+ pim_ifp->pim_sock_creation = 0;
+ pim_ifp->t_pim_sock_read = NULL;
+
+ pim_ifp->t_pim_hello_timer = NULL;
+ pim_ifp->pim_hello_period = PIM_DEFAULT_HELLO_PERIOD;
+ pim_ifp->pim_default_holdtime =
+ -1; /* unset: means 3.5 * pim_hello_period */
+ pim_ifp->pim_triggered_hello_delay = PIM_DEFAULT_TRIGGERED_HELLO_DELAY;
+ pim_ifp->pim_dr_priority = PIM_DEFAULT_DR_PRIORITY;
+ pim_ifp->pim_propagation_delay_msec =
+ PIM_DEFAULT_PROPAGATION_DELAY_MSEC;
+ pim_ifp->pim_override_interval_msec =
+ PIM_DEFAULT_OVERRIDE_INTERVAL_MSEC;
+ if (PIM_DEFAULT_CAN_DISABLE_JOIN_SUPPRESSION) {
+ PIM_IF_DO_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options);
+ } else {
+ PIM_IF_DONT_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options);
+ }
+
+ /* neighbors without lan_delay */
+ pim_ifp->pim_number_of_nonlandelay_neighbors = 0;
+ pim_ifp->pim_neighbors_highest_propagation_delay_msec = 0;
+ pim_ifp->pim_neighbors_highest_override_interval_msec = 0;
+
+ /* DR Election */
+ pim_ifp->pim_dr_election_last = 0; /* timestamp */
+ pim_ifp->pim_dr_election_count = 0;
+ pim_ifp->pim_dr_election_changes = 0;
+ pim_ifp->pim_dr_num_nondrpri_neighbors =
+ 0; /* neighbors without dr_pri */
+ pim_ifp->pim_dr_addr = pim_ifp->primary_address;
+
+ pim_ifstat_reset(ifp);
}
static uint16_t ip_id = 0;
-static int
-pim_msg_send_frame (int fd, char *buf, size_t len,
- struct sockaddr *dst, size_t salen)
+static int pim_msg_send_frame(int fd, char *buf, size_t len,
+ struct sockaddr *dst, size_t salen)
{
- struct ip *ip = (struct ip *)buf;
-
- while (sendto (fd, buf, len, MSG_DONTWAIT, dst, salen) < 0)
- {
- char dst_str[INET_ADDRSTRLEN];
-
- switch (errno)
- {
- case EMSGSIZE:
- {
- size_t hdrsize = sizeof (struct ip);
- size_t newlen1 = ((len - hdrsize) / 2 ) & 0xFFF8;
- size_t sendlen = newlen1 + hdrsize;
- size_t offset = ntohs (ip->ip_off);
-
- ip->ip_len = htons (sendlen);
- ip->ip_off = htons (offset | IP_MF);
- if (pim_msg_send_frame (fd, buf, sendlen, dst, salen) == 0)
- {
- struct ip *ip2 = (struct ip *)(buf + newlen1);
- size_t newlen2 = len - sendlen;
- sendlen = newlen2 + hdrsize;
-
- memcpy (ip2, ip, hdrsize);
- ip2->ip_len = htons (sendlen);
- ip2->ip_off = htons (offset + (newlen1 >> 3));
- return pim_msg_send_frame (fd, (char *)ip2, sendlen, dst, salen);
- }
- }
-
- return -1;
- break;
- default:
- if (PIM_DEBUG_PIM_PACKETS)
- {
- pim_inet4_dump ("<dst?>", ip->ip_dst, dst_str, sizeof (dst_str));
- zlog_warn ("%s: sendto() failure to %s: fd=%d msg_size=%zd: errno=%d: %s",
- __PRETTY_FUNCTION__,
- dst_str, fd, len,
- errno, safe_strerror(errno));
- }
- return -1;
- break;
+ struct ip *ip = (struct ip *)buf;
+
+ while (sendto(fd, buf, len, MSG_DONTWAIT, dst, salen) < 0) {
+ char dst_str[INET_ADDRSTRLEN];
+
+ switch (errno) {
+ case EMSGSIZE: {
+ size_t hdrsize = sizeof(struct ip);
+ size_t newlen1 = ((len - hdrsize) / 2) & 0xFFF8;
+ size_t sendlen = newlen1 + hdrsize;
+ size_t offset = ntohs(ip->ip_off);
+
+ ip->ip_len = htons(sendlen);
+ ip->ip_off = htons(offset | IP_MF);
+ if (pim_msg_send_frame(fd, buf, sendlen, dst, salen)
+ == 0) {
+ struct ip *ip2 = (struct ip *)(buf + newlen1);
+ size_t newlen2 = len - sendlen;
+ sendlen = newlen2 + hdrsize;
+
+ memcpy(ip2, ip, hdrsize);
+ ip2->ip_len = htons(sendlen);
+ ip2->ip_off = htons(offset + (newlen1 >> 3));
+ return pim_msg_send_frame(fd, (char *)ip2,
+ sendlen, dst, salen);
+ }
+ }
+
+ return -1;
+ break;
+ default:
+ if (PIM_DEBUG_PIM_PACKETS) {
+ pim_inet4_dump("<dst?>", ip->ip_dst, dst_str,
+ sizeof(dst_str));
+ zlog_warn(
+ "%s: sendto() failure to %s: fd=%d msg_size=%zd: errno=%d: %s",
+ __PRETTY_FUNCTION__, dst_str, fd, len,
+ errno, safe_strerror(errno));
+ }
+ return -1;
+ break;
+ }
}
- }
- return 0;
+ return 0;
}
-int
-pim_msg_send(int fd, struct in_addr src,
- struct in_addr dst, uint8_t *pim_msg,
- int pim_msg_size, const char *ifname)
+int pim_msg_send(int fd, struct in_addr src, struct in_addr dst,
+ uint8_t *pim_msg, int pim_msg_size, const char *ifname)
{
- struct sockaddr_in to;
- socklen_t tolen;
- unsigned char buffer[10000];
- unsigned char *msg_start;
- uint8_t ttl = MAXTTL;
- struct pim_msg_header *header;
- struct ip *ip;
-
- memset (buffer, 0, 10000);
- int sendlen = sizeof (struct ip) + pim_msg_size;
-
- msg_start = buffer + sizeof (struct ip);
- memcpy (msg_start, pim_msg, pim_msg_size);
-
- header = (struct pim_msg_header *)pim_msg;
- /*
- * Omnios apparently doesn't have a #define for IP default
- * ttl that is the same as all other platforms.
- */
+ struct sockaddr_in to;
+ socklen_t tolen;
+ unsigned char buffer[10000];
+ unsigned char *msg_start;
+ uint8_t ttl = MAXTTL;
+ struct pim_msg_header *header;
+ struct ip *ip;
+
+ memset(buffer, 0, 10000);
+ int sendlen = sizeof(struct ip) + pim_msg_size;
+
+ msg_start = buffer + sizeof(struct ip);
+ memcpy(msg_start, pim_msg, pim_msg_size);
+
+ header = (struct pim_msg_header *)pim_msg;
+/*
+ * Omnios apparently doesn't have a #define for IP default
+ * ttl that is the same as all other platforms.
+ */
#ifndef IPDEFTTL
#define IPDEFTTL 64
#endif
- /* TTL for packets destine to ALL-PIM-ROUTERS is 1 */
- switch (header->type)
- {
- case PIM_MSG_TYPE_HELLO:
- case PIM_MSG_TYPE_JOIN_PRUNE:
- case PIM_MSG_TYPE_BOOTSTRAP:
- case PIM_MSG_TYPE_ASSERT:
- ttl = 1;
- break;
- case PIM_MSG_TYPE_REGISTER:
- case PIM_MSG_TYPE_REG_STOP:
- case PIM_MSG_TYPE_GRAFT:
- case PIM_MSG_TYPE_GRAFT_ACK:
- case PIM_MSG_TYPE_CANDIDATE:
- ttl = IPDEFTTL;
- break;
- default:
- ttl = MAXTTL;
- break;
- }
-
- ip = (struct ip *) buffer;
- ip->ip_id = htons (++ip_id);
- ip->ip_hl = 5;
- ip->ip_v = 4;
- ip->ip_p = PIM_IP_PROTO_PIM;
- ip->ip_src = src;
- ip->ip_dst = dst;
- ip->ip_ttl = ttl;
- ip->ip_len = htons (sendlen);
-
- if (PIM_DEBUG_PIM_PACKETS) {
- struct pim_msg_header *header = (struct pim_msg_header *)pim_msg;
- char dst_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<dst?>", dst, dst_str, sizeof(dst_str));
- zlog_debug("%s: to %s on %s: msg_size=%d checksum=%x",
- __PRETTY_FUNCTION__,
- dst_str, ifname, pim_msg_size,
- header->checksum);
- }
-
- memset(&to, 0, sizeof(to));
- to.sin_family = AF_INET;
- to.sin_addr = dst;
- tolen = sizeof(to);
-
- if (PIM_DEBUG_PIM_PACKETDUMP_SEND) {
- pim_pkt_dump(__PRETTY_FUNCTION__, pim_msg, pim_msg_size);
- }
-
- pim_msg_send_frame (fd, (char *)buffer, sendlen,
- (struct sockaddr *)&to, tolen);
- return 0;
+ /* TTL for packets destine to ALL-PIM-ROUTERS is 1 */
+ switch (header->type) {
+ case PIM_MSG_TYPE_HELLO:
+ case PIM_MSG_TYPE_JOIN_PRUNE:
+ case PIM_MSG_TYPE_BOOTSTRAP:
+ case PIM_MSG_TYPE_ASSERT:
+ ttl = 1;
+ break;
+ case PIM_MSG_TYPE_REGISTER:
+ case PIM_MSG_TYPE_REG_STOP:
+ case PIM_MSG_TYPE_GRAFT:
+ case PIM_MSG_TYPE_GRAFT_ACK:
+ case PIM_MSG_TYPE_CANDIDATE:
+ ttl = IPDEFTTL;
+ break;
+ default:
+ ttl = MAXTTL;
+ break;
+ }
+
+ ip = (struct ip *)buffer;
+ ip->ip_id = htons(++ip_id);
+ ip->ip_hl = 5;
+ ip->ip_v = 4;
+ ip->ip_p = PIM_IP_PROTO_PIM;
+ ip->ip_src = src;
+ ip->ip_dst = dst;
+ ip->ip_ttl = ttl;
+ ip->ip_len = htons(sendlen);
+
+ if (PIM_DEBUG_PIM_PACKETS) {
+ struct pim_msg_header *header =
+ (struct pim_msg_header *)pim_msg;
+ char dst_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<dst?>", dst, dst_str, sizeof(dst_str));
+ zlog_debug("%s: to %s on %s: msg_size=%d checksum=%x",
+ __PRETTY_FUNCTION__, dst_str, ifname, pim_msg_size,
+ header->checksum);
+ }
+
+ memset(&to, 0, sizeof(to));
+ to.sin_family = AF_INET;
+ to.sin_addr = dst;
+ tolen = sizeof(to);
+
+ if (PIM_DEBUG_PIM_PACKETDUMP_SEND) {
+ pim_pkt_dump(__PRETTY_FUNCTION__, pim_msg, pim_msg_size);
+ }
+
+ pim_msg_send_frame(fd, (char *)buffer, sendlen, (struct sockaddr *)&to,
+ tolen);
+ return 0;
}
-static int hello_send(struct interface *ifp,
- uint16_t holdtime)
+static int hello_send(struct interface *ifp, uint16_t holdtime)
{
- uint8_t pim_msg[PIM_PIM_BUFSIZE_WRITE];
- struct pim_interface *pim_ifp;
- int pim_tlv_size;
- int pim_msg_size;
-
- pim_ifp = ifp->info;
-
- if (PIM_DEBUG_PIM_HELLO) {
- char dst_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<dst?>", qpim_all_pim_routers_addr, dst_str, sizeof(dst_str));
- zlog_debug("%s: to %s on %s: holdt=%u prop_d=%u overr_i=%u dis_join_supp=%d dr_prio=%u gen_id=%08x addrs=%d",
- __PRETTY_FUNCTION__,
- dst_str, ifp->name,
- holdtime,
- pim_ifp->pim_propagation_delay_msec, pim_ifp->pim_override_interval_msec,
- PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options),
- pim_ifp->pim_dr_priority, pim_ifp->pim_generation_id,
- listcount(ifp->connected));
- }
-
- pim_tlv_size = pim_hello_build_tlv(ifp,
- pim_msg + PIM_PIM_MIN_LEN,
- sizeof(pim_msg) - PIM_PIM_MIN_LEN,
- holdtime,
- pim_ifp->pim_dr_priority,
- pim_ifp->pim_generation_id,
- pim_ifp->pim_propagation_delay_msec,
- pim_ifp->pim_override_interval_msec,
- PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options));
- if (pim_tlv_size < 0) {
- return -1;
- }
-
- pim_msg_size = pim_tlv_size + PIM_PIM_MIN_LEN;
-
- zassert(pim_msg_size >= PIM_PIM_MIN_LEN);
- zassert(pim_msg_size <= PIM_PIM_BUFSIZE_WRITE);
-
- pim_msg_build_header(pim_msg, pim_msg_size, PIM_MSG_TYPE_HELLO);
-
- if (pim_msg_send(pim_ifp->pim_sock_fd,
- pim_ifp->primary_address,
- qpim_all_pim_routers_addr,
- pim_msg,
- pim_msg_size,
- ifp->name)) {
- if (PIM_DEBUG_PIM_HELLO) {
- zlog_debug("%s: could not send PIM message on interface %s",
- __PRETTY_FUNCTION__, ifp->name);
- }
- return -2;
- }
-
- return 0;
+ uint8_t pim_msg[PIM_PIM_BUFSIZE_WRITE];
+ struct pim_interface *pim_ifp;
+ int pim_tlv_size;
+ int pim_msg_size;
+
+ pim_ifp = ifp->info;
+
+ if (PIM_DEBUG_PIM_HELLO) {
+ char dst_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<dst?>", qpim_all_pim_routers_addr, dst_str,
+ sizeof(dst_str));
+ zlog_debug(
+ "%s: to %s on %s: holdt=%u prop_d=%u overr_i=%u dis_join_supp=%d dr_prio=%u gen_id=%08x addrs=%d",
+ __PRETTY_FUNCTION__, dst_str, ifp->name, holdtime,
+ pim_ifp->pim_propagation_delay_msec,
+ pim_ifp->pim_override_interval_msec,
+ PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(
+ pim_ifp->options),
+ pim_ifp->pim_dr_priority, pim_ifp->pim_generation_id,
+ listcount(ifp->connected));
+ }
+
+ pim_tlv_size = pim_hello_build_tlv(
+ ifp, pim_msg + PIM_PIM_MIN_LEN,
+ sizeof(pim_msg) - PIM_PIM_MIN_LEN, holdtime,
+ pim_ifp->pim_dr_priority, pim_ifp->pim_generation_id,
+ pim_ifp->pim_propagation_delay_msec,
+ pim_ifp->pim_override_interval_msec,
+ PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options));
+ if (pim_tlv_size < 0) {
+ return -1;
+ }
+
+ pim_msg_size = pim_tlv_size + PIM_PIM_MIN_LEN;
+
+ zassert(pim_msg_size >= PIM_PIM_MIN_LEN);
+ zassert(pim_msg_size <= PIM_PIM_BUFSIZE_WRITE);
+
+ pim_msg_build_header(pim_msg, pim_msg_size, PIM_MSG_TYPE_HELLO);
+
+ if (pim_msg_send(pim_ifp->pim_sock_fd, pim_ifp->primary_address,
+ qpim_all_pim_routers_addr, pim_msg, pim_msg_size,
+ ifp->name)) {
+ if (PIM_DEBUG_PIM_HELLO) {
+ zlog_debug(
+ "%s: could not send PIM message on interface %s",
+ __PRETTY_FUNCTION__, ifp->name);
+ }
+ return -2;
+ }
+
+ return 0;
}
-static int pim_hello_send(struct interface *ifp,
- uint16_t holdtime)
+static int pim_hello_send(struct interface *ifp, uint16_t holdtime)
{
- struct pim_interface *pim_ifp;
+ struct pim_interface *pim_ifp;
- zassert(ifp);
- pim_ifp = ifp->info;
- zassert(pim_ifp);
+ zassert(ifp);
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
- if (if_is_loopback (ifp))
- return 0;
+ if (if_is_loopback(ifp))
+ return 0;
- if (hello_send(ifp, holdtime)) {
- ++pim_ifp->pim_ifstat_hello_sendfail;
+ if (hello_send(ifp, holdtime)) {
+ ++pim_ifp->pim_ifstat_hello_sendfail;
- if (PIM_DEBUG_PIM_HELLO) {
- zlog_warn("Could not send PIM hello on interface %s",
- ifp->name);
- }
- return -1;
- }
+ if (PIM_DEBUG_PIM_HELLO) {
+ zlog_warn("Could not send PIM hello on interface %s",
+ ifp->name);
+ }
+ return -1;
+ }
- ++pim_ifp->pim_ifstat_hello_sent;
+ ++pim_ifp->pim_ifstat_hello_sent;
- return 0;
+ return 0;
}
static void hello_resched(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
-
- zassert(ifp);
- pim_ifp = ifp->info;
- zassert(pim_ifp);
-
- if (PIM_DEBUG_PIM_HELLO) {
- zlog_debug("Rescheduling %d sec hello on interface %s",
- pim_ifp->pim_hello_period, ifp->name);
- }
- THREAD_OFF(pim_ifp->t_pim_hello_timer);
- thread_add_timer(master, on_pim_hello_send, ifp, pim_ifp->pim_hello_period,
- &pim_ifp->t_pim_hello_timer);
+ struct pim_interface *pim_ifp;
+
+ zassert(ifp);
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+
+ if (PIM_DEBUG_PIM_HELLO) {
+ zlog_debug("Rescheduling %d sec hello on interface %s",
+ pim_ifp->pim_hello_period, ifp->name);
+ }
+ THREAD_OFF(pim_ifp->t_pim_hello_timer);
+ thread_add_timer(master, on_pim_hello_send, ifp,
+ pim_ifp->pim_hello_period,
+ &pim_ifp->t_pim_hello_timer);
}
/*
@@ -711,22 +714,22 @@ static void hello_resched(struct interface *ifp)
*/
static int on_pim_hello_send(struct thread *t)
{
- struct pim_interface *pim_ifp;
- struct interface *ifp;
+ struct pim_interface *pim_ifp;
+ struct interface *ifp;
- ifp = THREAD_ARG(t);
+ ifp = THREAD_ARG(t);
- pim_ifp = ifp->info;
+ pim_ifp = ifp->info;
- /*
- * Schedule next hello
- */
- hello_resched(ifp);
+ /*
+ * Schedule next hello
+ */
+ hello_resched(ifp);
- /*
- * Send hello
- */
- return pim_hello_send(ifp, PIM_IF_DEFAULT_HOLDTIME(pim_ifp));
+ /*
+ * Send hello
+ */
+ return pim_hello_send(ifp, PIM_IF_DEFAULT_HOLDTIME(pim_ifp));
}
/*
@@ -740,21 +743,21 @@ static int on_pim_hello_send(struct thread *t)
*/
void pim_hello_restart_now(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
+ struct pim_interface *pim_ifp;
- zassert(ifp);
- pim_ifp = ifp->info;
- zassert(pim_ifp);
+ zassert(ifp);
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
- /*
- * Reset next hello timer
- */
- hello_resched(ifp);
+ /*
+ * Reset next hello timer
+ */
+ hello_resched(ifp);
- /*
- * Immediately send hello
- */
- pim_hello_send(ifp, PIM_IF_DEFAULT_HOLDTIME(pim_ifp));
+ /*
+ * Immediately send hello
+ */
+ pim_hello_send(ifp, PIM_IF_DEFAULT_HOLDTIME(pim_ifp));
}
/*
@@ -768,105 +771,109 @@ void pim_hello_restart_now(struct interface *ifp)
*/
void pim_hello_restart_triggered(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
- int triggered_hello_delay_msec;
- int random_msec;
-
- zassert(ifp);
- pim_ifp = ifp->info;
- zassert(pim_ifp);
-
- /*
- * There exists situations where we have the a RPF out this
- * interface, but we haven't formed a neighbor yet. This
- * happens especially during interface flaps. While
- * we would like to handle this more gracefully in other
- * parts of the code. In order to get us up and running
- * let's just send the hello immediate'ish
- * This should be revisited when we get nexthop tracking
- * in and when we have a better handle on safely
- * handling the rpf information for upstreams that
- * we cannot legally reach yet.
- */
- triggered_hello_delay_msec = 1;
- //triggered_hello_delay_msec = 1000 * pim_ifp->pim_triggered_hello_delay;
-
- if (pim_ifp->t_pim_hello_timer) {
- long remain_msec = pim_time_timer_remain_msec(pim_ifp->t_pim_hello_timer);
- if (remain_msec <= triggered_hello_delay_msec) {
- /* Rescheduling hello would increase the delay, then it's faster
- to just wait for the scheduled periodic hello. */
- return;
- }
-
- THREAD_OFF(pim_ifp->t_pim_hello_timer);
- }
-
- random_msec = triggered_hello_delay_msec;
- //random_msec = random() % (triggered_hello_delay_msec + 1);
-
- if (PIM_DEBUG_PIM_HELLO) {
- zlog_debug("Scheduling %d msec triggered hello on interface %s",
- random_msec, ifp->name);
- }
-
- thread_add_timer_msec(master, on_pim_hello_send, ifp, random_msec,
- &pim_ifp->t_pim_hello_timer);
+ struct pim_interface *pim_ifp;
+ int triggered_hello_delay_msec;
+ int random_msec;
+
+ zassert(ifp);
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+
+ /*
+ * There exists situations where we have the a RPF out this
+ * interface, but we haven't formed a neighbor yet. This
+ * happens especially during interface flaps. While
+ * we would like to handle this more gracefully in other
+ * parts of the code. In order to get us up and running
+ * let's just send the hello immediate'ish
+ * This should be revisited when we get nexthop tracking
+ * in and when we have a better handle on safely
+ * handling the rpf information for upstreams that
+ * we cannot legally reach yet.
+ */
+ triggered_hello_delay_msec = 1;
+ // triggered_hello_delay_msec = 1000 *
+ // pim_ifp->pim_triggered_hello_delay;
+
+ if (pim_ifp->t_pim_hello_timer) {
+ long remain_msec =
+ pim_time_timer_remain_msec(pim_ifp->t_pim_hello_timer);
+ if (remain_msec <= triggered_hello_delay_msec) {
+ /* Rescheduling hello would increase the delay, then
+ it's faster
+ to just wait for the scheduled periodic hello. */
+ return;
+ }
+
+ THREAD_OFF(pim_ifp->t_pim_hello_timer);
+ }
+
+ random_msec = triggered_hello_delay_msec;
+ // random_msec = random() % (triggered_hello_delay_msec + 1);
+
+ if (PIM_DEBUG_PIM_HELLO) {
+ zlog_debug("Scheduling %d msec triggered hello on interface %s",
+ random_msec, ifp->name);
+ }
+
+ thread_add_timer_msec(master, on_pim_hello_send, ifp, random_msec,
+ &pim_ifp->t_pim_hello_timer);
}
int pim_sock_add(struct interface *ifp)
{
- struct pim_interface *pim_ifp;
- uint32_t old_genid;
-
- pim_ifp = ifp->info;
- zassert(pim_ifp);
-
- if (pim_ifp->pim_sock_fd >= 0) {
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug("Can't recreate existing PIM socket fd=%d for interface %s",
- pim_ifp->pim_sock_fd, ifp->name);
- return -1;
- }
-
- pim_ifp->pim_sock_fd = pim_sock_open(ifp);
- if (pim_ifp->pim_sock_fd < 0) {
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug("Could not open PIM socket on interface %s",
- ifp->name);
- return -2;
- }
-
- pim_socket_ip_hdr (pim_ifp->pim_sock_fd);
-
- pim_ifp->t_pim_sock_read = NULL;
- pim_ifp->pim_sock_creation = pim_time_monotonic_sec();
-
- /*
- * Just ensure that the new generation id
- * actually chooses something different.
- * Actually ran across a case where this
- * happened, pre-switch to random().
- * While this is unlikely to happen now
- * let's make sure it doesn't.
- */
- old_genid = pim_ifp->pim_generation_id;
-
- while (old_genid == pim_ifp->pim_generation_id)
- pim_ifp->pim_generation_id = random();
-
- zlog_info("PIM INTERFACE UP: on interface %s ifindex=%d",
- ifp->name, ifp->ifindex);
-
- /*
- * Start receiving PIM messages
- */
- pim_sock_read_on(ifp);
-
- /*
- * Start sending PIM hello's
- */
- pim_hello_restart_triggered(ifp);
-
- return 0;
+ struct pim_interface *pim_ifp;
+ uint32_t old_genid;
+
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+
+ if (pim_ifp->pim_sock_fd >= 0) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "Can't recreate existing PIM socket fd=%d for interface %s",
+ pim_ifp->pim_sock_fd, ifp->name);
+ return -1;
+ }
+
+ pim_ifp->pim_sock_fd = pim_sock_open(ifp);
+ if (pim_ifp->pim_sock_fd < 0) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug("Could not open PIM socket on interface %s",
+ ifp->name);
+ return -2;
+ }
+
+ pim_socket_ip_hdr(pim_ifp->pim_sock_fd);
+
+ pim_ifp->t_pim_sock_read = NULL;
+ pim_ifp->pim_sock_creation = pim_time_monotonic_sec();
+
+ /*
+ * Just ensure that the new generation id
+ * actually chooses something different.
+ * Actually ran across a case where this
+ * happened, pre-switch to random().
+ * While this is unlikely to happen now
+ * let's make sure it doesn't.
+ */
+ old_genid = pim_ifp->pim_generation_id;
+
+ while (old_genid == pim_ifp->pim_generation_id)
+ pim_ifp->pim_generation_id = random();
+
+ zlog_info("PIM INTERFACE UP: on interface %s ifindex=%d", ifp->name,
+ ifp->ifindex);
+
+ /*
+ * Start receiving PIM messages
+ */
+ pim_sock_read_on(ifp);
+
+ /*
+ * Start sending PIM hello's
+ */
+ pim_hello_restart_triggered(ifp);
+
+ return 0;
}
diff --git a/pimd/pim_pim.h b/pimd/pim_pim.h
index 7e2872184..e930ab7c2 100644
--- a/pimd/pim_pim.h
+++ b/pimd/pim_pim.h
@@ -36,15 +36,15 @@
#define PIM_DEFAULT_T_PERIODIC (60) /* RFC 4601: 4.11. Timer Values */
enum pim_msg_type {
- PIM_MSG_TYPE_HELLO = 0,
- PIM_MSG_TYPE_REGISTER,
- PIM_MSG_TYPE_REG_STOP,
- PIM_MSG_TYPE_JOIN_PRUNE,
- PIM_MSG_TYPE_BOOTSTRAP,
- PIM_MSG_TYPE_ASSERT,
- PIM_MSG_TYPE_GRAFT,
- PIM_MSG_TYPE_GRAFT_ACK,
- PIM_MSG_TYPE_CANDIDATE
+ PIM_MSG_TYPE_HELLO = 0,
+ PIM_MSG_TYPE_REGISTER,
+ PIM_MSG_TYPE_REG_STOP,
+ PIM_MSG_TYPE_JOIN_PRUNE,
+ PIM_MSG_TYPE_BOOTSTRAP,
+ PIM_MSG_TYPE_ASSERT,
+ PIM_MSG_TYPE_GRAFT,
+ PIM_MSG_TYPE_GRAFT_ACK,
+ PIM_MSG_TYPE_CANDIDATE
};
void pim_ifstat_reset(struct interface *ifp);
@@ -56,11 +56,7 @@ void pim_hello_restart_triggered(struct interface *ifp);
int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len);
-int pim_msg_send(int fd,
- struct in_addr src,
- struct in_addr dst,
- uint8_t *pim_msg,
- int pim_msg_size,
- const char *ifname);
+int pim_msg_send(int fd, struct in_addr src, struct in_addr dst,
+ uint8_t *pim_msg, int pim_msg_size, const char *ifname);
#endif /* PIM_PIM_H */
diff --git a/pimd/pim_register.c b/pimd/pim_register.c
index 682a6401c..1cbe1dcf7 100644
--- a/pimd/pim_register.c
+++ b/pimd/pim_register.c
@@ -46,179 +46,173 @@
struct thread *send_test_packet_timer = NULL;
-void
-pim_register_join (struct pim_upstream *up)
+void pim_register_join(struct pim_upstream *up)
{
- if (pim_is_grp_ssm (up->sg.grp))
- {
- if (PIM_DEBUG_PIM_EVENTS)
- zlog_debug ("%s register setup skipped as group is SSM", up->sg_str);
- return;
- }
-
- pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM);
- up->reg_state = PIM_REG_JOIN;
+ if (pim_is_grp_ssm(up->sg.grp)) {
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_debug("%s register setup skipped as group is SSM",
+ up->sg_str);
+ return;
+ }
+
+ pim_channel_add_oif(up->channel_oil, pim_regiface,
+ PIM_OIF_FLAG_PROTO_PIM);
+ up->reg_state = PIM_REG_JOIN;
}
-void
-pim_register_stop_send (struct interface *ifp, struct prefix_sg *sg,
- struct in_addr src, struct in_addr originator)
+void pim_register_stop_send(struct interface *ifp, struct prefix_sg *sg,
+ struct in_addr src, struct in_addr originator)
{
- struct pim_interface *pinfo;
- unsigned char buffer[10000];
- unsigned int b1length = 0;
- unsigned int length;
- uint8_t *b1;
- struct prefix p;
-
- if (PIM_DEBUG_PIM_REG)
- {
- zlog_debug ("Sending Register stop for %s to %s on %s",
- pim_str_sg_dump (sg), inet_ntoa(originator), ifp->name);
- }
-
- memset (buffer, 0, 10000);
- b1 = (uint8_t *)buffer + PIM_MSG_REGISTER_STOP_LEN;
-
- length = pim_encode_addr_group (b1, AFI_IP, 0, 0, sg->grp);
- b1length += length;
- b1 += length;
-
- p.family = AF_INET;
- p.u.prefix4 = sg->src;
- p.prefixlen = 32;
- length = pim_encode_addr_ucast (b1, &p);
- b1length += length;
-
- pim_msg_build_header (buffer, b1length + PIM_MSG_REGISTER_STOP_LEN, PIM_MSG_TYPE_REG_STOP);
-
- pinfo = (struct pim_interface *)ifp->info;
- if (!pinfo)
- {
- if (PIM_DEBUG_PIM_TRACE)
- zlog_debug ("%s: No pinfo!\n", __PRETTY_FUNCTION__);
- return;
- }
- if (pim_msg_send (pinfo->pim_sock_fd, src, originator,
- buffer, b1length + PIM_MSG_REGISTER_STOP_LEN,
- ifp->name))
- {
- if (PIM_DEBUG_PIM_TRACE)
- {
- zlog_debug ("%s: could not send PIM register stop message on interface %s",
- __PRETTY_FUNCTION__, ifp->name);
+ struct pim_interface *pinfo;
+ unsigned char buffer[10000];
+ unsigned int b1length = 0;
+ unsigned int length;
+ uint8_t *b1;
+ struct prefix p;
+
+ if (PIM_DEBUG_PIM_REG) {
+ zlog_debug("Sending Register stop for %s to %s on %s",
+ pim_str_sg_dump(sg), inet_ntoa(originator),
+ ifp->name);
+ }
+
+ memset(buffer, 0, 10000);
+ b1 = (uint8_t *)buffer + PIM_MSG_REGISTER_STOP_LEN;
+
+ length = pim_encode_addr_group(b1, AFI_IP, 0, 0, sg->grp);
+ b1length += length;
+ b1 += length;
+
+ p.family = AF_INET;
+ p.u.prefix4 = sg->src;
+ p.prefixlen = 32;
+ length = pim_encode_addr_ucast(b1, &p);
+ b1length += length;
+
+ pim_msg_build_header(buffer, b1length + PIM_MSG_REGISTER_STOP_LEN,
+ PIM_MSG_TYPE_REG_STOP);
+
+ pinfo = (struct pim_interface *)ifp->info;
+ if (!pinfo) {
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug("%s: No pinfo!\n", __PRETTY_FUNCTION__);
+ return;
}
- }
- ++pinfo->pim_ifstat_reg_stop_send;
+ if (pim_msg_send(pinfo->pim_sock_fd, src, originator, buffer,
+ b1length + PIM_MSG_REGISTER_STOP_LEN, ifp->name)) {
+ if (PIM_DEBUG_PIM_TRACE) {
+ zlog_debug(
+ "%s: could not send PIM register stop message on interface %s",
+ __PRETTY_FUNCTION__, ifp->name);
+ }
+ }
+ ++pinfo->pim_ifstat_reg_stop_send;
}
-int
-pim_register_stop_recv (uint8_t *buf, int buf_size)
+int pim_register_stop_recv(uint8_t *buf, int buf_size)
{
- struct pim_upstream *upstream = NULL;
- struct prefix source;
- struct prefix_sg sg;
- int l;
-
- memset (&sg, 0, sizeof (struct prefix_sg));
- l = pim_parse_addr_group (&sg, buf, buf_size);
- buf += l;
- buf_size -= l;
- pim_parse_addr_ucast (&source, buf, buf_size);
- sg.src = source.u.prefix4;
-
- upstream = pim_upstream_find (&sg);
- if (!upstream)
- {
- return 0;
- }
-
- if (PIM_DEBUG_PIM_REG)
- zlog_debug ("Received Register stop for %s",
- upstream->sg_str);
-
- switch (upstream->reg_state)
- {
- case PIM_REG_NOINFO:
- case PIM_REG_PRUNE:
- return 0;
- break;
- case PIM_REG_JOIN:
- upstream->reg_state = PIM_REG_PRUNE;
- pim_channel_del_oif (upstream->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM);
- pim_upstream_start_register_stop_timer (upstream, 0);
- break;
- case PIM_REG_JOIN_PENDING:
- upstream->reg_state = PIM_REG_PRUNE;
- pim_upstream_start_register_stop_timer (upstream, 0);
- return 0;
- break;
- }
-
- return 0;
+ struct pim_upstream *upstream = NULL;
+ struct prefix source;
+ struct prefix_sg sg;
+ int l;
+
+ memset(&sg, 0, sizeof(struct prefix_sg));
+ l = pim_parse_addr_group(&sg, buf, buf_size);
+ buf += l;
+ buf_size -= l;
+ pim_parse_addr_ucast(&source, buf, buf_size);
+ sg.src = source.u.prefix4;
+
+ upstream = pim_upstream_find(&sg);
+ if (!upstream) {
+ return 0;
+ }
+
+ if (PIM_DEBUG_PIM_REG)
+ zlog_debug("Received Register stop for %s", upstream->sg_str);
+
+ switch (upstream->reg_state) {
+ case PIM_REG_NOINFO:
+ case PIM_REG_PRUNE:
+ return 0;
+ break;
+ case PIM_REG_JOIN:
+ upstream->reg_state = PIM_REG_PRUNE;
+ pim_channel_del_oif(upstream->channel_oil, pim_regiface,
+ PIM_OIF_FLAG_PROTO_PIM);
+ pim_upstream_start_register_stop_timer(upstream, 0);
+ break;
+ case PIM_REG_JOIN_PENDING:
+ upstream->reg_state = PIM_REG_PRUNE;
+ pim_upstream_start_register_stop_timer(upstream, 0);
+ return 0;
+ break;
+ }
+
+ return 0;
}
-void
-pim_register_send (const uint8_t *buf, int buf_size, struct in_addr src, struct pim_rpf *rpg, int null_register, struct pim_upstream *up)
+void pim_register_send(const uint8_t *buf, int buf_size, struct in_addr src,
+ struct pim_rpf *rpg, int null_register,
+ struct pim_upstream *up)
{
- unsigned char buffer[10000];
- unsigned char *b1;
- struct pim_interface *pinfo;
- struct interface *ifp;
-
- if (PIM_DEBUG_PIM_REG)
- {
- zlog_debug ("Sending %s %sRegister Packet to %s",
- up->sg_str, null_register ? "NULL " : "",
- inet_ntoa (rpg->rpf_addr.u.prefix4));
- }
-
- ifp = rpg->source_nexthop.interface;
- if (!ifp)
- {
- if (PIM_DEBUG_PIM_REG)
- zlog_debug ("%s: No interface to transmit register on", __PRETTY_FUNCTION__);
- return;
- }
- pinfo = (struct pim_interface *)ifp->info;
- if (!pinfo) {
- if (PIM_DEBUG_PIM_REG)
- zlog_debug("%s: Interface: %s not configured for pim to trasmit on!\n", __PRETTY_FUNCTION__, ifp->name);
- return;
- }
-
- if (PIM_DEBUG_PIM_REG)
- {
- char rp_str[INET_ADDRSTRLEN];
- strncpy (rp_str, inet_ntoa (rpg->rpf_addr.u.prefix4), INET_ADDRSTRLEN-1);
- zlog_debug ("%s: Sending %s %sRegister Packet to %s on %s",
- __PRETTY_FUNCTION__, up->sg_str,
- null_register ? "NULL " : "", rp_str, ifp->name);
- }
-
- memset(buffer, 0, 10000);
- b1 = buffer + PIM_MSG_HEADER_LEN;
- *b1 |= null_register << 6;
- b1 = buffer + PIM_MSG_REGISTER_LEN;
-
- memcpy(b1, (const unsigned char *)buf, buf_size);
-
- pim_msg_build_header(buffer, buf_size + PIM_MSG_REGISTER_LEN, PIM_MSG_TYPE_REGISTER);
-
- ++pinfo->pim_ifstat_reg_send;
-
- if (pim_msg_send(pinfo->pim_sock_fd,
- src,
- rpg->rpf_addr.u.prefix4,
- buffer,
- buf_size + PIM_MSG_REGISTER_LEN,
- ifp->name)) {
- if (PIM_DEBUG_PIM_TRACE) {
- zlog_debug("%s: could not send PIM register message on interface %s",
- __PRETTY_FUNCTION__, ifp->name);
- }
- return;
- }
+ unsigned char buffer[10000];
+ unsigned char *b1;
+ struct pim_interface *pinfo;
+ struct interface *ifp;
+
+ if (PIM_DEBUG_PIM_REG) {
+ zlog_debug("Sending %s %sRegister Packet to %s", up->sg_str,
+ null_register ? "NULL " : "",
+ inet_ntoa(rpg->rpf_addr.u.prefix4));
+ }
+
+ ifp = rpg->source_nexthop.interface;
+ if (!ifp) {
+ if (PIM_DEBUG_PIM_REG)
+ zlog_debug("%s: No interface to transmit register on",
+ __PRETTY_FUNCTION__);
+ return;
+ }
+ pinfo = (struct pim_interface *)ifp->info;
+ if (!pinfo) {
+ if (PIM_DEBUG_PIM_REG)
+ zlog_debug(
+ "%s: Interface: %s not configured for pim to trasmit on!\n",
+ __PRETTY_FUNCTION__, ifp->name);
+ return;
+ }
+
+ if (PIM_DEBUG_PIM_REG) {
+ char rp_str[INET_ADDRSTRLEN];
+ strncpy(rp_str, inet_ntoa(rpg->rpf_addr.u.prefix4),
+ INET_ADDRSTRLEN - 1);
+ zlog_debug("%s: Sending %s %sRegister Packet to %s on %s",
+ __PRETTY_FUNCTION__, up->sg_str,
+ null_register ? "NULL " : "", rp_str, ifp->name);
+ }
+
+ memset(buffer, 0, 10000);
+ b1 = buffer + PIM_MSG_HEADER_LEN;
+ *b1 |= null_register << 6;
+ b1 = buffer + PIM_MSG_REGISTER_LEN;
+
+ memcpy(b1, (const unsigned char *)buf, buf_size);
+
+ pim_msg_build_header(buffer, buf_size + PIM_MSG_REGISTER_LEN,
+ PIM_MSG_TYPE_REGISTER);
+
+ ++pinfo->pim_ifstat_reg_send;
+
+ if (pim_msg_send(pinfo->pim_sock_fd, src, rpg->rpf_addr.u.prefix4,
+ buffer, buf_size + PIM_MSG_REGISTER_LEN, ifp->name)) {
+ if (PIM_DEBUG_PIM_TRACE) {
+ zlog_debug(
+ "%s: could not send PIM register message on interface %s",
+ __PRETTY_FUNCTION__, ifp->name);
+ }
+ return;
+ }
}
/*
@@ -265,155 +259,160 @@ pim_register_send (const uint8_t *buf, int buf_size, struct in_addr src, struct
* }
* }
*/
-int
-pim_register_recv (struct interface *ifp,
- struct in_addr dest_addr,
- struct in_addr src_addr,
- uint8_t *tlv_buf, int tlv_buf_size)
+int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,
+ struct in_addr src_addr, uint8_t *tlv_buf,
+ int tlv_buf_size)
{
- int sentRegisterStop = 0;
- struct ip *ip_hdr;
- struct prefix_sg sg;
- uint32_t *bits;
- int i_am_rp = 0;
- struct pim_interface *pim_ifp = NULL;
+ int sentRegisterStop = 0;
+ struct ip *ip_hdr;
+ struct prefix_sg sg;
+ uint32_t *bits;
+ int i_am_rp = 0;
+ struct pim_interface *pim_ifp = NULL;
#define PIM_MSG_REGISTER_BIT_RESERVED_LEN 4
- ip_hdr = (struct ip *)(tlv_buf + PIM_MSG_REGISTER_BIT_RESERVED_LEN);
-
- if (!pim_rp_check_is_my_ip_address (ip_hdr->ip_dst, dest_addr)) {
- if (PIM_DEBUG_PIM_REG) {
- char dest[INET_ADDRSTRLEN];
-
- pim_inet4_dump ("<dst?>", dest_addr, dest, sizeof(dest));
- zlog_debug ("%s: Received Register message for %s that I do not own", __func__,
- dest);
- }
- return 0;
- }
-
- pim_ifp = ifp->info;
- zassert(pim_ifp);
- ++pim_ifp->pim_ifstat_reg_recv;
-
- /*
- * Please note this is not drawn to get the correct bit/data size
- *
- * The entirety of the REGISTER packet looks like this:
- * -------------------------------------------------------------
- * | Ver | Type | Reserved | Checksum |
- * |-----------------------------------------------------------|
- * |B|N| Reserved 2 |
- * |-----------------------------------------------------------|
- * | Encap | IP HDR |
- * | Mcast | |
- * | Packet |--------------------------------------------------|
- * | | Mcast Data |
- * | | |
- * ...
- *
- * tlv_buf when received from the caller points at the B bit
- * We need to know the inner source and dest
- */
- bits = (uint32_t *)tlv_buf;
-
- /*
- * tlv_buf points to the start of the |B|N|... Reserved
- * Line above. So we need to add 4 bytes to get to the
- * start of the actual Encapsulated data.
- */
- memset (&sg, 0, sizeof (struct prefix_sg));
- sg.src = ip_hdr->ip_src;
- sg.grp = ip_hdr->ip_dst;
-
- i_am_rp = I_am_RP (sg.grp);
-
- if (PIM_DEBUG_PIM_REG)
- {
- char src_str[INET_ADDRSTRLEN];
-
- pim_inet4_dump ("<src?>", src_addr, src_str, sizeof (src_str));
- zlog_debug ("Received Register message(%s) from %s on %s, rp: %d",
- pim_str_sg_dump (&sg), src_str, ifp->name, i_am_rp);
- }
-
- if (i_am_rp && (dest_addr.s_addr == ((RP (sg.grp))->rpf_addr.u.prefix4.s_addr))) {
- sentRegisterStop = 0;
-
- if (*bits & PIM_REGISTER_BORDER_BIT) {
- struct in_addr pimbr = pim_br_get_pmbr (&sg);
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug("%s: Received Register message with Border bit set", __func__);
-
- if (pimbr.s_addr == pim_br_unknown.s_addr)
- pim_br_set_pmbr(&sg, src_addr);
- else if (src_addr.s_addr != pimbr.s_addr) {
- pim_register_stop_send (ifp, &sg, dest_addr, src_addr);
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug("%s: Sending register-Stop to %s and dropping mr. packet",
- __func__, "Sender");
- /* Drop Packet Silently */
+ ip_hdr = (struct ip *)(tlv_buf + PIM_MSG_REGISTER_BIT_RESERVED_LEN);
+
+ if (!pim_rp_check_is_my_ip_address(ip_hdr->ip_dst, dest_addr)) {
+ if (PIM_DEBUG_PIM_REG) {
+ char dest[INET_ADDRSTRLEN];
+
+ pim_inet4_dump("<dst?>", dest_addr, dest, sizeof(dest));
+ zlog_debug(
+ "%s: Received Register message for %s that I do not own",
+ __func__, dest);
+ }
+ return 0;
+ }
+
+ pim_ifp = ifp->info;
+ zassert(pim_ifp);
+ ++pim_ifp->pim_ifstat_reg_recv;
+
+ /*
+ * Please note this is not drawn to get the correct bit/data size
+ *
+ * The entirety of the REGISTER packet looks like this:
+ * -------------------------------------------------------------
+ * | Ver | Type | Reserved | Checksum |
+ * |-----------------------------------------------------------|
+ * |B|N| Reserved 2 |
+ * |-----------------------------------------------------------|
+ * | Encap | IP HDR |
+ * | Mcast | |
+ * | Packet |--------------------------------------------------|
+ * | | Mcast Data |
+ * | | |
+ * ...
+ *
+ * tlv_buf when received from the caller points at the B bit
+ * We need to know the inner source and dest
+ */
+ bits = (uint32_t *)tlv_buf;
+
+ /*
+ * tlv_buf points to the start of the |B|N|... Reserved
+ * Line above. So we need to add 4 bytes to get to the
+ * start of the actual Encapsulated data.
+ */
+ memset(&sg, 0, sizeof(struct prefix_sg));
+ sg.src = ip_hdr->ip_src;
+ sg.grp = ip_hdr->ip_dst;
+
+ i_am_rp = I_am_RP(sg.grp);
+
+ if (PIM_DEBUG_PIM_REG) {
+ char src_str[INET_ADDRSTRLEN];
+
+ pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ zlog_debug(
+ "Received Register message(%s) from %s on %s, rp: %d",
+ pim_str_sg_dump(&sg), src_str, ifp->name, i_am_rp);
+ }
+
+ if (i_am_rp && (dest_addr.s_addr
+ == ((RP(sg.grp))->rpf_addr.u.prefix4.s_addr))) {
+ sentRegisterStop = 0;
+
+ if (*bits & PIM_REGISTER_BORDER_BIT) {
+ struct in_addr pimbr = pim_br_get_pmbr(&sg);
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "%s: Received Register message with Border bit set",
+ __func__);
+
+ if (pimbr.s_addr == pim_br_unknown.s_addr)
+ pim_br_set_pmbr(&sg, src_addr);
+ else if (src_addr.s_addr != pimbr.s_addr) {
+ pim_register_stop_send(ifp, &sg, dest_addr,
+ src_addr);
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug(
+ "%s: Sending register-Stop to %s and dropping mr. packet",
+ __func__, "Sender");
+ /* Drop Packet Silently */
+ return 0;
+ }
+ }
+
+ struct pim_upstream *upstream = pim_upstream_find(&sg);
+ /*
+ * If we don't have a place to send ignore the packet
+ */
+ if (!upstream) {
+ upstream = pim_upstream_add(
+ &sg, ifp, PIM_UPSTREAM_FLAG_MASK_SRC_STREAM,
+ __PRETTY_FUNCTION__);
+ if (!upstream) {
+ zlog_warn("Failure to create upstream state");
+ return 1;
+ }
+
+ upstream->upstream_register = src_addr;
+ }
+
+ if ((upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE)
+ || ((SwitchToSptDesired(&sg))
+ && pim_upstream_inherited_olist(upstream) == 0)) {
+ // pim_scan_individual_oil (upstream->channel_oil);
+ pim_register_stop_send(ifp, &sg, dest_addr, src_addr);
+ sentRegisterStop = 1;
+ } else {
+ if (PIM_DEBUG_PIM_REG)
+ zlog_debug("(%s) sptbit: %d", upstream->sg_str,
+ upstream->sptbit);
+ }
+ if ((upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE)
+ || (SwitchToSptDesired(&sg))) {
+ if (sentRegisterStop) {
+ pim_upstream_keep_alive_timer_start(
+ upstream, qpim_rp_keep_alive_time);
+ } else {
+ pim_upstream_keep_alive_timer_start(
+ upstream, qpim_keep_alive_time);
+ }
+ }
+
+ if (!(upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE)
+ && !(*bits & PIM_REGISTER_NR_BIT)) {
+ // decapsulate and forward the iner packet to
+ // inherited_olist(S,G,rpt)
+ // This is taken care of by the kernel for us
+ }
+ pim_upstream_msdp_reg_timer_start(upstream);
+ } else {
+ if (PIM_DEBUG_PIM_REG) {
+ if (!i_am_rp)
+ zlog_debug(
+ "Received Register packet for %s, Rejecting packet because I am not the RP configured for group",
+ pim_str_sg_dump(&sg));
+ else
+ zlog_debug(
+ "Received Register packet for %s, Rejecting packet because the dst ip address is not the actual RP",
+ pim_str_sg_dump(&sg));
+ }
+ pim_register_stop_send(ifp, &sg, dest_addr, src_addr);
+ }
+
return 0;
- }
- }
-
- struct pim_upstream *upstream = pim_upstream_find (&sg);
- /*
- * If we don't have a place to send ignore the packet
- */
- if (!upstream)
- {
- upstream = pim_upstream_add (&sg, ifp,
- PIM_UPSTREAM_FLAG_MASK_SRC_STREAM,
- __PRETTY_FUNCTION__);
- if (!upstream)
- {
- zlog_warn ("Failure to create upstream state");
- return 1;
- }
-
- upstream->upstream_register = src_addr;
- }
-
- if ((upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE) ||
- ((SwitchToSptDesired(&sg)) &&
- pim_upstream_inherited_olist (upstream) == 0)) {
- //pim_scan_individual_oil (upstream->channel_oil);
- pim_register_stop_send (ifp, &sg, dest_addr, src_addr);
- sentRegisterStop = 1;
- } else {
- if (PIM_DEBUG_PIM_REG)
- zlog_debug ("(%s) sptbit: %d", upstream->sg_str, upstream->sptbit);
- }
- if ((upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE) ||
- (SwitchToSptDesired(&sg))) {
- if (sentRegisterStop) {
- pim_upstream_keep_alive_timer_start (upstream, qpim_rp_keep_alive_time);
- } else {
- pim_upstream_keep_alive_timer_start (upstream, qpim_keep_alive_time);
- }
- }
-
- if (!(upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE) &&
- !(*bits & PIM_REGISTER_NR_BIT))
- {
- //decapsulate and forward the iner packet to
- //inherited_olist(S,G,rpt)
- // This is taken care of by the kernel for us
- }
- pim_upstream_msdp_reg_timer_start(upstream);
- } else {
- if (PIM_DEBUG_PIM_REG)
- {
- if (!i_am_rp)
- zlog_debug ("Received Register packet for %s, Rejecting packet because I am not the RP configured for group",
- pim_str_sg_dump (&sg));
- else
- zlog_debug ("Received Register packet for %s, Rejecting packet because the dst ip address is not the actual RP",
- pim_str_sg_dump (&sg));
- }
- pim_register_stop_send (ifp, &sg, dest_addr, src_addr);
- }
-
- return 0;
}
diff --git a/pimd/pim_register.h b/pimd/pim_register.h
index adb703c61..ad3deb2b2 100644
--- a/pimd/pim_register.h
+++ b/pimd/pim_register.h
@@ -30,15 +30,17 @@
#define PIM_MSG_REGISTER_LEN (8)
#define PIM_MSG_REGISTER_STOP_LEN (4)
-int pim_register_stop_recv (uint8_t *buf, int buf_size);
-
-int pim_register_recv (struct interface *ifp,
- struct in_addr dest_addr,
- struct in_addr src_addr,
- uint8_t *tlv_buf, int tlv_buf_size);
-
-void pim_register_send (const uint8_t *buf, int buf_size, struct in_addr src, struct pim_rpf *rpg, int null_register, struct pim_upstream *up);
-void pim_register_stop_send (struct interface *ifp, struct prefix_sg *sg, struct in_addr src, struct in_addr originator);
-void pim_register_join (struct pim_upstream *up);
+int pim_register_stop_recv(uint8_t *buf, int buf_size);
+
+int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,
+ struct in_addr src_addr, uint8_t *tlv_buf,
+ int tlv_buf_size);
+
+void pim_register_send(const uint8_t *buf, int buf_size, struct in_addr src,
+ struct pim_rpf *rpg, int null_register,
+ struct pim_upstream *up);
+void pim_register_stop_send(struct interface *ifp, struct prefix_sg *sg,
+ struct in_addr src, struct in_addr originator);
+void pim_register_join(struct pim_upstream *up);
#endif
diff --git a/pimd/pim_routemap.c b/pimd/pim_routemap.c
index 20c716c3e..6d06229b9 100644
--- a/pimd/pim_routemap.c
+++ b/pimd/pim_routemap.c
@@ -27,55 +27,49 @@
#include "pimd.h"
-static void
-pim_route_map_mark_update (const char *rmap_name)
+static void pim_route_map_mark_update(const char *rmap_name)
{
- // placeholder
- return;
+ // placeholder
+ return;
}
-static void
-pim_route_map_add (const char *rmap_name)
+static void pim_route_map_add(const char *rmap_name)
{
- if (route_map_mark_updated(rmap_name, 0) == 0)
- pim_route_map_mark_update(rmap_name);
+ if (route_map_mark_updated(rmap_name, 0) == 0)
+ pim_route_map_mark_update(rmap_name);
- route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED);
+ route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED);
}
-static void
-pim_route_map_delete (const char *rmap_name)
+static void pim_route_map_delete(const char *rmap_name)
{
- if (route_map_mark_updated(rmap_name, 1) == 0)
- pim_route_map_mark_update(rmap_name);
+ if (route_map_mark_updated(rmap_name, 1) == 0)
+ pim_route_map_mark_update(rmap_name);
- route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_DELETED);
+ route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_DELETED);
}
-static void
-pim_route_map_event (route_map_event_t event, const char *rmap_name)
+static void pim_route_map_event(route_map_event_t event, const char *rmap_name)
{
- if (route_map_mark_updated(rmap_name, 0) == 0)
- pim_route_map_mark_update(rmap_name);
+ if (route_map_mark_updated(rmap_name, 0) == 0)
+ pim_route_map_mark_update(rmap_name);
- route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED);
+ route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED);
}
-void
-pim_route_map_init (void)
+void pim_route_map_init(void)
{
- route_map_init ();
+ route_map_init();
- route_map_add_hook (pim_route_map_add);
- route_map_delete_hook (pim_route_map_delete);
- route_map_event_hook (pim_route_map_event);
+ route_map_add_hook(pim_route_map_add);
+ route_map_delete_hook(pim_route_map_delete);
+ route_map_event_hook(pim_route_map_event);
}
-void
-pim_route_map_terminate (void)
+void pim_route_map_terminate(void)
{
- route_map_add_hook (NULL);
- route_map_delete_hook (NULL);
- route_map_event_hook (NULL);
- route_map_finish();
+ route_map_add_hook(NULL);
+ route_map_delete_hook(NULL);
+ route_map_event_hook(NULL);
+ route_map_finish();
}
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c
index 28300dbdf..2fe0143a8 100644
--- a/pimd/pim_rp.c
+++ b/pimd/pim_rp.c
@@ -48,158 +48,147 @@
static struct list *qpim_rp_list = NULL;
static struct rp_info *tail = NULL;
-static void
-pim_rp_info_free (struct rp_info *rp_info)
+static void pim_rp_info_free(struct rp_info *rp_info)
{
- XFREE (MTYPE_PIM_RP, rp_info);
+ XFREE(MTYPE_PIM_RP, rp_info);
}
-int
-pim_rp_list_cmp (void *v1, void *v2)
+int pim_rp_list_cmp(void *v1, void *v2)
{
- struct rp_info *rp1 = (struct rp_info *)v1;
- struct rp_info *rp2 = (struct rp_info *)v2;
-
- /*
- * Sort by RP IP address
- */
- if (rp1->rp.rpf_addr.u.prefix4.s_addr < rp2->rp.rpf_addr.u.prefix4.s_addr)
- return -1;
-
- if (rp1->rp.rpf_addr.u.prefix4.s_addr > rp2->rp.rpf_addr.u.prefix4.s_addr)
- return 1;
-
- /*
- * Sort by group IP address
- */
- if (rp1->group.u.prefix4.s_addr < rp2->group.u.prefix4.s_addr)
- return -1;
-
- if (rp1->group.u.prefix4.s_addr > rp2->group.u.prefix4.s_addr)
- return 1;
-
- return 0;
+ struct rp_info *rp1 = (struct rp_info *)v1;
+ struct rp_info *rp2 = (struct rp_info *)v2;
+
+ /*
+ * Sort by RP IP address
+ */
+ if (rp1->rp.rpf_addr.u.prefix4.s_addr
+ < rp2->rp.rpf_addr.u.prefix4.s_addr)
+ return -1;
+
+ if (rp1->rp.rpf_addr.u.prefix4.s_addr
+ > rp2->rp.rpf_addr.u.prefix4.s_addr)
+ return 1;
+
+ /*
+ * Sort by group IP address
+ */
+ if (rp1->group.u.prefix4.s_addr < rp2->group.u.prefix4.s_addr)
+ return -1;
+
+ if (rp1->group.u.prefix4.s_addr > rp2->group.u.prefix4.s_addr)
+ return 1;
+
+ return 0;
}
-void
-pim_rp_init (void)
+void pim_rp_init(void)
{
- struct rp_info *rp_info;
+ struct rp_info *rp_info;
- qpim_rp_list = list_new ();
- qpim_rp_list->del = (void (*)(void *))pim_rp_info_free;
- qpim_rp_list->cmp = pim_rp_list_cmp;
+ qpim_rp_list = list_new();
+ qpim_rp_list->del = (void (*)(void *))pim_rp_info_free;
+ qpim_rp_list->cmp = pim_rp_list_cmp;
- rp_info = XCALLOC (MTYPE_PIM_RP, sizeof (*rp_info));
+ rp_info = XCALLOC(MTYPE_PIM_RP, sizeof(*rp_info));
- if (!rp_info)
- return;
+ if (!rp_info)
+ return;
- str2prefix ("224.0.0.0/4", &rp_info->group);
- rp_info->group.family = AF_INET;
- rp_info->rp.rpf_addr.family = AF_INET;
- rp_info->rp.rpf_addr.prefixlen = IPV4_MAX_PREFIXLEN;
- rp_info->rp.rpf_addr.u.prefix4.s_addr = INADDR_NONE;
- tail = rp_info;
+ str2prefix("224.0.0.0/4", &rp_info->group);
+ rp_info->group.family = AF_INET;
+ rp_info->rp.rpf_addr.family = AF_INET;
+ rp_info->rp.rpf_addr.prefixlen = IPV4_MAX_PREFIXLEN;
+ rp_info->rp.rpf_addr.u.prefix4.s_addr = INADDR_NONE;
+ tail = rp_info;
- listnode_add (qpim_rp_list, rp_info);
+ listnode_add(qpim_rp_list, rp_info);
}
-void
-pim_rp_free (void)
+void pim_rp_free(void)
{
- if (qpim_rp_list)
- list_delete (qpim_rp_list);
- qpim_rp_list = NULL;
+ if (qpim_rp_list)
+ list_delete(qpim_rp_list);
+ qpim_rp_list = NULL;
}
/*
* Given an RP's prefix-list, return the RP's rp_info for that prefix-list
*/
-static struct rp_info *
-pim_rp_find_prefix_list (struct in_addr rp, const char *plist)
+static struct rp_info *pim_rp_find_prefix_list(struct in_addr rp,
+ const char *plist)
{
- struct listnode *node;
- struct rp_info *rp_info;
-
- for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
- {
- if (rp.s_addr == rp_info->rp.rpf_addr.u.prefix4.s_addr &&
- rp_info->plist && strcmp(rp_info->plist, plist) == 0)
- {
- return rp_info;
- }
- }
-
- return NULL;
+ struct listnode *node;
+ struct rp_info *rp_info;
+
+ for (ALL_LIST_ELEMENTS_RO(qpim_rp_list, node, rp_info)) {
+ if (rp.s_addr == rp_info->rp.rpf_addr.u.prefix4.s_addr
+ && rp_info->plist && strcmp(rp_info->plist, plist) == 0) {
+ return rp_info;
+ }
+ }
+
+ return NULL;
}
/*
* Return true if plist is used by any rp_info
*/
-static int
-pim_rp_prefix_list_used (const char *plist)
+static int pim_rp_prefix_list_used(const char *plist)
{
- struct listnode *node;
- struct rp_info *rp_info;
-
- for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
- {
- if (rp_info->plist && strcmp(rp_info->plist, plist) == 0)
- {
- return 1;
- }
- }
-
- return 0;
+ struct listnode *node;
+ struct rp_info *rp_info;
+
+ for (ALL_LIST_ELEMENTS_RO(qpim_rp_list, node, rp_info)) {
+ if (rp_info->plist && strcmp(rp_info->plist, plist) == 0) {
+ return 1;
+ }
+ }
+
+ return 0;
}
/*
- * Given an RP's address, return the RP's rp_info that is an exact match for 'group'
+ * Given an RP's address, return the RP's rp_info that is an exact match for
+ * 'group'
*/
-static struct rp_info *
-pim_rp_find_exact (struct in_addr rp, struct prefix *group)
+static struct rp_info *pim_rp_find_exact(struct in_addr rp,
+ struct prefix *group)
{
- struct listnode *node;
- struct rp_info *rp_info;
+ struct listnode *node;
+ struct rp_info *rp_info;
- for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
- {
- if (rp.s_addr == rp_info->rp.rpf_addr.u.prefix4.s_addr &&
- prefix_same (&rp_info->group, group))
- return rp_info;
- }
+ for (ALL_LIST_ELEMENTS_RO(qpim_rp_list, node, rp_info)) {
+ if (rp.s_addr == rp_info->rp.rpf_addr.u.prefix4.s_addr
+ && prefix_same(&rp_info->group, group))
+ return rp_info;
+ }
- return NULL;
+ return NULL;
}
/*
* Given a group, return the rp_info for that group
*/
-static struct rp_info *
-pim_rp_find_match_group (struct prefix *group)
+static struct rp_info *pim_rp_find_match_group(struct prefix *group)
{
- struct listnode *node;
- struct rp_info *rp_info;
- struct prefix_list *plist;
-
- for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
- {
- if (rp_info->plist)
- {
- plist = prefix_list_lookup (AFI_IP, rp_info->plist);
-
- if (plist && prefix_list_apply (plist, group) == PREFIX_PERMIT)
- return rp_info;
- }
- else
- {
- if (prefix_match (&rp_info->group, group))
- return rp_info;
- }
- }
-
- return NULL;
+ struct listnode *node;
+ struct rp_info *rp_info;
+ struct prefix_list *plist;
+
+ for (ALL_LIST_ELEMENTS_RO(qpim_rp_list, node, rp_info)) {
+ if (rp_info->plist) {
+ plist = prefix_list_lookup(AFI_IP, rp_info->plist);
+
+ if (plist
+ && prefix_list_apply(plist, group) == PREFIX_PERMIT)
+ return rp_info;
+ } else {
+ if (prefix_match(&rp_info->group, group))
+ return rp_info;
+ }
+ }
+
+ return NULL;
}
/*
@@ -209,480 +198,475 @@ pim_rp_find_match_group (struct prefix *group)
*
* This is a placeholder function for now.
*/
-static void
-pim_rp_refresh_group_to_rp_mapping()
+static void pim_rp_refresh_group_to_rp_mapping()
{
- pim_msdp_i_am_rp_changed();
+ pim_msdp_i_am_rp_changed();
}
-void
-pim_rp_prefix_list_update (struct prefix_list *plist)
+void pim_rp_prefix_list_update(struct prefix_list *plist)
{
- struct listnode *node;
- struct rp_info *rp_info;
- int refresh_needed = 0;
-
- for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
- {
- if (rp_info->plist && strcmp(rp_info->plist, prefix_list_name (plist)) == 0)
- {
- refresh_needed = 1;
- break;
- }
- }
-
- if (refresh_needed)
- pim_rp_refresh_group_to_rp_mapping();
+ struct listnode *node;
+ struct rp_info *rp_info;
+ int refresh_needed = 0;
+
+ for (ALL_LIST_ELEMENTS_RO(qpim_rp_list, node, rp_info)) {
+ if (rp_info->plist
+ && strcmp(rp_info->plist, prefix_list_name(plist)) == 0) {
+ refresh_needed = 1;
+ break;
+ }
+ }
+
+ if (refresh_needed)
+ pim_rp_refresh_group_to_rp_mapping();
}
-static int
-pim_rp_check_interface_addrs(struct rp_info *rp_info,
- struct pim_interface *pim_ifp)
+static int pim_rp_check_interface_addrs(struct rp_info *rp_info,
+ struct pim_interface *pim_ifp)
{
- struct listnode *node;
- struct pim_secondary_addr *sec_addr;
+ struct listnode *node;
+ struct pim_secondary_addr *sec_addr;
- if (pim_ifp->primary_address.s_addr == rp_info->rp.rpf_addr.u.prefix4.s_addr)
- return 1;
+ if (pim_ifp->primary_address.s_addr
+ == rp_info->rp.rpf_addr.u.prefix4.s_addr)
+ return 1;
- if (!pim_ifp->sec_addr_list) {
- return 0;
- }
+ if (!pim_ifp->sec_addr_list) {
+ return 0;
+ }
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, node, sec_addr)) {
- if (prefix_same(&sec_addr->addr, &rp_info->rp.rpf_addr)) {
- return 1;
- }
- }
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, node, sec_addr)) {
+ if (prefix_same(&sec_addr->addr, &rp_info->rp.rpf_addr)) {
+ return 1;
+ }
+ }
- return 0;
+ return 0;
}
-static void
-pim_rp_check_interfaces (struct rp_info *rp_info)
+static void pim_rp_check_interfaces(struct rp_info *rp_info)
{
- struct listnode *node;
- struct interface *ifp;
+ struct listnode *node;
+ struct interface *ifp;
- rp_info->i_am_rp = 0;
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
- {
- struct pim_interface *pim_ifp = ifp->info;
+ rp_info->i_am_rp = 0;
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ struct pim_interface *pim_ifp = ifp->info;
- if (!pim_ifp)
- continue;
+ if (!pim_ifp)
+ continue;
- if (pim_rp_check_interface_addrs(rp_info, pim_ifp)) {
- rp_info->i_am_rp = 1;
- }
- }
+ if (pim_rp_check_interface_addrs(rp_info, pim_ifp)) {
+ rp_info->i_am_rp = 1;
+ }
+ }
}
-int
-pim_rp_new (const char *rp, const char *group_range, const char *plist)
+int pim_rp_new(const char *rp, const char *group_range, const char *plist)
{
- int result = 0;
- struct rp_info *rp_info;
- struct rp_info *rp_all;
- struct prefix group_all;
- struct listnode *node, *nnode;
- struct rp_info *tmp_rp_info;
- char buffer[BUFSIZ];
- struct prefix nht_p;
- struct pim_nexthop_cache pnc;
-
- rp_info = XCALLOC (MTYPE_PIM_RP, sizeof (*rp_info));
- if (!rp_info)
- return PIM_MALLOC_FAIL;
-
- if (group_range == NULL)
- result = str2prefix ("224.0.0.0/4", &rp_info->group);
- else
- result = str2prefix (group_range, &rp_info->group);
-
- if (!result)
- {
- XFREE (MTYPE_PIM_RP, rp_info);
- return PIM_GROUP_BAD_ADDRESS;
- }
-
- rp_info->rp.rpf_addr.family = AF_INET;
- rp_info->rp.rpf_addr.prefixlen = IPV4_MAX_PREFIXLEN;
- result = inet_pton (rp_info->rp.rpf_addr.family, rp, &rp_info->rp.rpf_addr.u.prefix4);
-
- if (result <= 0)
- {
- XFREE (MTYPE_PIM_RP, rp_info);
- return PIM_RP_BAD_ADDRESS;
- }
-
- if (plist)
- {
- /*
- * Return if the prefix-list is already configured for this RP
- */
- if (pim_rp_find_prefix_list (rp_info->rp.rpf_addr.u.prefix4, plist))
- {
- XFREE (MTYPE_PIM_RP, rp_info);
- return PIM_SUCCESS;
- }
-
- /*
- * Barf if the prefix-list is already configured for an RP
- */
- if (pim_rp_prefix_list_used (plist))
- {
- XFREE (MTYPE_PIM_RP, rp_info);
- return PIM_RP_PFXLIST_IN_USE;
- }
-
- /*
- * Free any existing rp_info entries for this RP
- */
- for (ALL_LIST_ELEMENTS (qpim_rp_list, node, nnode, tmp_rp_info))
- {
- if (rp_info->rp.rpf_addr.u.prefix4.s_addr == tmp_rp_info->rp.rpf_addr.u.prefix4.s_addr)
- {
- if (tmp_rp_info->plist)
- pim_rp_del (rp, NULL, tmp_rp_info->plist);
- else
- pim_rp_del (rp, prefix2str(&tmp_rp_info->group, buffer, BUFSIZ), NULL);
- }
- }
-
- rp_info->plist = XSTRDUP(MTYPE_PIM_FILTER_NAME, plist);
- }
- else
- {
- str2prefix ("224.0.0.0/4", &group_all);
- rp_all = pim_rp_find_match_group(&group_all);
-
- /*
- * Barf if group is a non-multicast subnet
- */
- if (! prefix_match (&rp_all->group, &rp_info->group))
- {
- XFREE (MTYPE_PIM_RP, rp_info);
- return PIM_GROUP_BAD_ADDRESS;
- }
-
- /*
- * Remove any prefix-list rp_info entries for this RP
- */
- for (ALL_LIST_ELEMENTS (qpim_rp_list, node, nnode, tmp_rp_info))
- {
- if (tmp_rp_info->plist &&
- rp_info->rp.rpf_addr.u.prefix4.s_addr == tmp_rp_info->rp.rpf_addr.u.prefix4.s_addr)
- {
- pim_rp_del (rp, NULL, tmp_rp_info->plist);
- }
- }
-
- /*
- * Take over the 224.0.0.0/4 group if the rp is INADDR_NONE
- */
- if (prefix_same (&rp_all->group, &rp_info->group) &&
- pim_rpf_addr_is_inaddr_none (&rp_all->rp))
- {
- rp_all->rp.rpf_addr = rp_info->rp.rpf_addr;
- XFREE (MTYPE_PIM_RP, rp_info);
-
- /* Register addr with Zebra NHT */
- nht_p.family = AF_INET;
- nht_p.prefixlen = IPV4_MAX_BITLEN;
- nht_p.u.prefix4 = rp_all->rp.rpf_addr.u.prefix4; //RP address
- if (PIM_DEBUG_PIM_TRACE)
- {
- char buf[PREFIX2STR_BUFFER];
- char buf1[PREFIX2STR_BUFFER];
- prefix2str (&nht_p, buf, sizeof (buf));
- prefix2str (&rp_all->group, buf1, sizeof (buf1));
- zlog_debug ("%s: NHT Register rp_all addr %s grp %s ",
- __PRETTY_FUNCTION__, buf, buf1);
- }
- memset (&pnc, 0, sizeof (struct pim_nexthop_cache));
- if ((pim_find_or_track_nexthop (&nht_p, NULL, rp_all, &pnc)) == 1)
- {
- //Compute PIM RPF using Cached nexthop
- if ((pim_ecmp_nexthop_search (&pnc, &rp_all->rp.source_nexthop,
- &nht_p, &rp_all->group, 1)) != 0)
- return PIM_RP_NO_PATH;
- }
- else
- {
- if (pim_nexthop_lookup (&rp_all->rp.source_nexthop, rp_all->rp.rpf_addr.u.prefix4, 1) != 0)
- return PIM_RP_NO_PATH;
- }
- pim_rp_check_interfaces (rp_all);
- pim_rp_refresh_group_to_rp_mapping ();
- return PIM_SUCCESS;
- }
-
- /*
- * Return if the group is already configured for this RP
- */
- if (pim_rp_find_exact (rp_info->rp.rpf_addr.u.prefix4, &rp_info->group))
- {
- XFREE (MTYPE_PIM_RP, rp_info);
- return PIM_SUCCESS;
- }
-
- /*
- * Barf if this group is already covered by some other RP
- */
- tmp_rp_info = pim_rp_find_match_group (&rp_info->group);
-
- if (tmp_rp_info)
- {
- if (tmp_rp_info->plist)
- {
- XFREE (MTYPE_PIM_RP, rp_info);
- return PIM_GROUP_PFXLIST_OVERLAP;
- }
- else
- {
- /*
- * If the only RP that covers this group is an RP configured for
- * 224.0.0.0/4 that is fine, ignore that one. For all others
- * though we must return PIM_GROUP_OVERLAP
- */
- if (! prefix_same (&group_all, &tmp_rp_info->group))
- {
- XFREE (MTYPE_PIM_RP, rp_info);
- return PIM_GROUP_OVERLAP;
- }
- }
- }
- }
-
- listnode_add_sort (qpim_rp_list, rp_info);
-
- /* Register addr with Zebra NHT */
- nht_p.family = AF_INET;
- nht_p.prefixlen = IPV4_MAX_BITLEN;
- nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
- if (PIM_DEBUG_PIM_TRACE)
- {
- char buf[PREFIX2STR_BUFFER];
- char buf1[PREFIX2STR_BUFFER];
- prefix2str (&nht_p, buf, sizeof (buf));
- prefix2str (&rp_info->group, buf1, sizeof (buf1));
- zlog_debug ("%s: NHT Register RP addr %s grp %s with Zebra ",
- __PRETTY_FUNCTION__, buf, buf1);
- }
-
- memset (&pnc, 0, sizeof (struct pim_nexthop_cache));
- if ((pim_find_or_track_nexthop (&nht_p, NULL, rp_info, &pnc)) == 1)
- {
- //Compute PIM RPF using Cached nexthop
- if (pim_ecmp_nexthop_search (&pnc, &rp_info->rp.source_nexthop,
- &nht_p, &rp_info->group, 1) != 0)
- return PIM_RP_NO_PATH;
- }
- else
- {
- if (pim_nexthop_lookup (&rp_info->rp.source_nexthop, rp_info->rp.rpf_addr.u.prefix4, 1) != 0)
- return PIM_RP_NO_PATH;
- }
-
- pim_rp_check_interfaces (rp_info);
- pim_rp_refresh_group_to_rp_mapping ();
- return PIM_SUCCESS;
+ int result = 0;
+ struct rp_info *rp_info;
+ struct rp_info *rp_all;
+ struct prefix group_all;
+ struct listnode *node, *nnode;
+ struct rp_info *tmp_rp_info;
+ char buffer[BUFSIZ];
+ struct prefix nht_p;
+ struct pim_nexthop_cache pnc;
+
+ rp_info = XCALLOC(MTYPE_PIM_RP, sizeof(*rp_info));
+ if (!rp_info)
+ return PIM_MALLOC_FAIL;
+
+ if (group_range == NULL)
+ result = str2prefix("224.0.0.0/4", &rp_info->group);
+ else
+ result = str2prefix(group_range, &rp_info->group);
+
+ if (!result) {
+ XFREE(MTYPE_PIM_RP, rp_info);
+ return PIM_GROUP_BAD_ADDRESS;
+ }
+
+ rp_info->rp.rpf_addr.family = AF_INET;
+ rp_info->rp.rpf_addr.prefixlen = IPV4_MAX_PREFIXLEN;
+ result = inet_pton(rp_info->rp.rpf_addr.family, rp,
+ &rp_info->rp.rpf_addr.u.prefix4);
+
+ if (result <= 0) {
+ XFREE(MTYPE_PIM_RP, rp_info);
+ return PIM_RP_BAD_ADDRESS;
+ }
+
+ if (plist) {
+ /*
+ * Return if the prefix-list is already configured for this RP
+ */
+ if (pim_rp_find_prefix_list(rp_info->rp.rpf_addr.u.prefix4,
+ plist)) {
+ XFREE(MTYPE_PIM_RP, rp_info);
+ return PIM_SUCCESS;
+ }
+
+ /*
+ * Barf if the prefix-list is already configured for an RP
+ */
+ if (pim_rp_prefix_list_used(plist)) {
+ XFREE(MTYPE_PIM_RP, rp_info);
+ return PIM_RP_PFXLIST_IN_USE;
+ }
+
+ /*
+ * Free any existing rp_info entries for this RP
+ */
+ for (ALL_LIST_ELEMENTS(qpim_rp_list, node, nnode,
+ tmp_rp_info)) {
+ if (rp_info->rp.rpf_addr.u.prefix4.s_addr
+ == tmp_rp_info->rp.rpf_addr.u.prefix4.s_addr) {
+ if (tmp_rp_info->plist)
+ pim_rp_del(rp, NULL,
+ tmp_rp_info->plist);
+ else
+ pim_rp_del(
+ rp,
+ prefix2str(&tmp_rp_info->group,
+ buffer, BUFSIZ),
+ NULL);
+ }
+ }
+
+ rp_info->plist = XSTRDUP(MTYPE_PIM_FILTER_NAME, plist);
+ } else {
+ str2prefix("224.0.0.0/4", &group_all);
+ rp_all = pim_rp_find_match_group(&group_all);
+
+ /*
+ * Barf if group is a non-multicast subnet
+ */
+ if (!prefix_match(&rp_all->group, &rp_info->group)) {
+ XFREE(MTYPE_PIM_RP, rp_info);
+ return PIM_GROUP_BAD_ADDRESS;
+ }
+
+ /*
+ * Remove any prefix-list rp_info entries for this RP
+ */
+ for (ALL_LIST_ELEMENTS(qpim_rp_list, node, nnode,
+ tmp_rp_info)) {
+ if (tmp_rp_info->plist
+ && rp_info->rp.rpf_addr.u.prefix4.s_addr
+ == tmp_rp_info->rp.rpf_addr.u.prefix4
+ .s_addr) {
+ pim_rp_del(rp, NULL, tmp_rp_info->plist);
+ }
+ }
+
+ /*
+ * Take over the 224.0.0.0/4 group if the rp is INADDR_NONE
+ */
+ if (prefix_same(&rp_all->group, &rp_info->group)
+ && pim_rpf_addr_is_inaddr_none(&rp_all->rp)) {
+ rp_all->rp.rpf_addr = rp_info->rp.rpf_addr;
+ XFREE(MTYPE_PIM_RP, rp_info);
+
+ /* Register addr with Zebra NHT */
+ nht_p.family = AF_INET;
+ nht_p.prefixlen = IPV4_MAX_BITLEN;
+ nht_p.u.prefix4 =
+ rp_all->rp.rpf_addr.u.prefix4; // RP address
+ if (PIM_DEBUG_PIM_TRACE) {
+ char buf[PREFIX2STR_BUFFER];
+ char buf1[PREFIX2STR_BUFFER];
+ prefix2str(&nht_p, buf, sizeof(buf));
+ prefix2str(&rp_all->group, buf1, sizeof(buf1));
+ zlog_debug(
+ "%s: NHT Register rp_all addr %s grp %s ",
+ __PRETTY_FUNCTION__, buf, buf1);
+ }
+ memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
+ if ((pim_find_or_track_nexthop(&nht_p, NULL, rp_all,
+ &pnc))
+ == 1) {
+ // Compute PIM RPF using Cached nexthop
+ if ((pim_ecmp_nexthop_search(
+ &pnc, &rp_all->rp.source_nexthop,
+ &nht_p, &rp_all->group, 1))
+ != 0)
+ return PIM_RP_NO_PATH;
+ } else {
+ if (pim_nexthop_lookup(
+ &rp_all->rp.source_nexthop,
+ rp_all->rp.rpf_addr.u.prefix4, 1)
+ != 0)
+ return PIM_RP_NO_PATH;
+ }
+ pim_rp_check_interfaces(rp_all);
+ pim_rp_refresh_group_to_rp_mapping();
+ return PIM_SUCCESS;
+ }
+
+ /*
+ * Return if the group is already configured for this RP
+ */
+ if (pim_rp_find_exact(rp_info->rp.rpf_addr.u.prefix4,
+ &rp_info->group)) {
+ XFREE(MTYPE_PIM_RP, rp_info);
+ return PIM_SUCCESS;
+ }
+
+ /*
+ * Barf if this group is already covered by some other RP
+ */
+ tmp_rp_info = pim_rp_find_match_group(&rp_info->group);
+
+ if (tmp_rp_info) {
+ if (tmp_rp_info->plist) {
+ XFREE(MTYPE_PIM_RP, rp_info);
+ return PIM_GROUP_PFXLIST_OVERLAP;
+ } else {
+ /*
+ * If the only RP that covers this group is an
+ * RP configured for
+ * 224.0.0.0/4 that is fine, ignore that one.
+ * For all others
+ * though we must return PIM_GROUP_OVERLAP
+ */
+ if (!prefix_same(&group_all,
+ &tmp_rp_info->group)) {
+ XFREE(MTYPE_PIM_RP, rp_info);
+ return PIM_GROUP_OVERLAP;
+ }
+ }
+ }
+ }
+
+ listnode_add_sort(qpim_rp_list, rp_info);
+
+ /* Register addr with Zebra NHT */
+ nht_p.family = AF_INET;
+ nht_p.prefixlen = IPV4_MAX_BITLEN;
+ nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
+ if (PIM_DEBUG_PIM_TRACE) {
+ char buf[PREFIX2STR_BUFFER];
+ char buf1[PREFIX2STR_BUFFER];
+ prefix2str(&nht_p, buf, sizeof(buf));
+ prefix2str(&rp_info->group, buf1, sizeof(buf1));
+ zlog_debug("%s: NHT Register RP addr %s grp %s with Zebra ",
+ __PRETTY_FUNCTION__, buf, buf1);
+ }
+
+ memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
+ if ((pim_find_or_track_nexthop(&nht_p, NULL, rp_info, &pnc)) == 1) {
+ // Compute PIM RPF using Cached nexthop
+ if (pim_ecmp_nexthop_search(&pnc, &rp_info->rp.source_nexthop,
+ &nht_p, &rp_info->group, 1)
+ != 0)
+ return PIM_RP_NO_PATH;
+ } else {
+ if (pim_nexthop_lookup(&rp_info->rp.source_nexthop,
+ rp_info->rp.rpf_addr.u.prefix4, 1)
+ != 0)
+ return PIM_RP_NO_PATH;
+ }
+
+ pim_rp_check_interfaces(rp_info);
+ pim_rp_refresh_group_to_rp_mapping();
+ return PIM_SUCCESS;
}
-int
-pim_rp_del (const char *rp, const char *group_range, const char *plist)
+int pim_rp_del(const char *rp, const char *group_range, const char *plist)
{
- struct prefix group;
- struct in_addr rp_addr;
- struct prefix g_all;
- struct rp_info *rp_info;
- struct rp_info *rp_all;
- int result;
- struct prefix nht_p;
-
- if (group_range == NULL)
- result = str2prefix ("224.0.0.0/4", &group);
- else
- result = str2prefix (group_range, &group);
-
- if (!result)
- return PIM_GROUP_BAD_ADDRESS;
-
- result = inet_pton (AF_INET, rp, &rp_addr);
- if (result <= 0)
- return PIM_RP_BAD_ADDRESS;
-
- if (plist)
- rp_info = pim_rp_find_prefix_list (rp_addr, plist);
- else
- rp_info = pim_rp_find_exact (rp_addr, &group);
-
- if (!rp_info)
- return PIM_RP_NOT_FOUND;
-
- if (rp_info->plist)
- {
- XFREE(MTYPE_PIM_FILTER_NAME, rp_info->plist);
- rp_info->plist = NULL;
- }
-
- /* Deregister addr with Zebra NHT */
- nht_p.family = AF_INET;
- nht_p.prefixlen = IPV4_MAX_BITLEN;
- nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
- if (PIM_DEBUG_PIM_TRACE)
- {
- char buf[PREFIX2STR_BUFFER];
- prefix2str (&nht_p, buf, sizeof (buf));
- zlog_debug ("%s: Deregister RP addr %s with Zebra ", __PRETTY_FUNCTION__,
- buf);
- }
- pim_delete_tracked_nexthop (&nht_p, NULL, rp_info);
-
- str2prefix ("224.0.0.0/4", &g_all);
- rp_all = pim_rp_find_match_group (&g_all);
-
- if (rp_all == rp_info)
- {
- rp_all->rp.rpf_addr.family = AF_INET;
- rp_all->rp.rpf_addr.u.prefix4.s_addr = INADDR_NONE;
- rp_all->i_am_rp = 0;
- return PIM_SUCCESS;
- }
-
- listnode_delete (qpim_rp_list, rp_info);
- pim_rp_refresh_group_to_rp_mapping ();
- return PIM_SUCCESS;
+ struct prefix group;
+ struct in_addr rp_addr;
+ struct prefix g_all;
+ struct rp_info *rp_info;
+ struct rp_info *rp_all;
+ int result;
+ struct prefix nht_p;
+
+ if (group_range == NULL)
+ result = str2prefix("224.0.0.0/4", &group);
+ else
+ result = str2prefix(group_range, &group);
+
+ if (!result)
+ return PIM_GROUP_BAD_ADDRESS;
+
+ result = inet_pton(AF_INET, rp, &rp_addr);
+ if (result <= 0)
+ return PIM_RP_BAD_ADDRESS;
+
+ if (plist)
+ rp_info = pim_rp_find_prefix_list(rp_addr, plist);
+ else
+ rp_info = pim_rp_find_exact(rp_addr, &group);
+
+ if (!rp_info)
+ return PIM_RP_NOT_FOUND;
+
+ if (rp_info->plist) {
+ XFREE(MTYPE_PIM_FILTER_NAME, rp_info->plist);
+ rp_info->plist = NULL;
+ }
+
+ /* Deregister addr with Zebra NHT */
+ nht_p.family = AF_INET;
+ nht_p.prefixlen = IPV4_MAX_BITLEN;
+ nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
+ if (PIM_DEBUG_PIM_TRACE) {
+ char buf[PREFIX2STR_BUFFER];
+ prefix2str(&nht_p, buf, sizeof(buf));
+ zlog_debug("%s: Deregister RP addr %s with Zebra ",
+ __PRETTY_FUNCTION__, buf);
+ }
+ pim_delete_tracked_nexthop(&nht_p, NULL, rp_info);
+
+ str2prefix("224.0.0.0/4", &g_all);
+ rp_all = pim_rp_find_match_group(&g_all);
+
+ if (rp_all == rp_info) {
+ rp_all->rp.rpf_addr.family = AF_INET;
+ rp_all->rp.rpf_addr.u.prefix4.s_addr = INADDR_NONE;
+ rp_all->i_am_rp = 0;
+ return PIM_SUCCESS;
+ }
+
+ listnode_delete(qpim_rp_list, rp_info);
+ pim_rp_refresh_group_to_rp_mapping();
+ return PIM_SUCCESS;
}
-int
-pim_rp_setup (void)
+int pim_rp_setup(void)
{
- struct listnode *node;
- struct rp_info *rp_info;
- int ret = 0;
- struct prefix nht_p;
- struct pim_nexthop_cache pnc;
-
- for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
- {
- if (rp_info->rp.rpf_addr.u.prefix4.s_addr == INADDR_NONE)
- continue;
-
- nht_p.family = AF_INET;
- nht_p.prefixlen = IPV4_MAX_BITLEN;
- nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
- memset (&pnc, 0, sizeof (struct pim_nexthop_cache));
- if ((pim_find_or_track_nexthop (&nht_p, NULL, rp_info, &pnc)) == 1)
- {
- //Compute PIM RPF using Cached nexthop
- if ((pim_ecmp_nexthop_search (&pnc, &rp_info->rp.source_nexthop,
- &nht_p, &rp_info->group, 1)) != 0)
- ret++;
- }
- else
- {
- if (PIM_DEBUG_ZEBRA)
- {
- char buf[PREFIX2STR_BUFFER];
- prefix2str (&nht_p, buf, sizeof (buf));
- zlog_debug ("%s: NHT Local Nexthop not found for RP %s ",
- __PRETTY_FUNCTION__, buf);
- }
- if (pim_nexthop_lookup (&rp_info->rp.source_nexthop, rp_info->rp.rpf_addr.u.prefix4, 1) != 0)
- {
- if (PIM_DEBUG_PIM_TRACE)
- zlog_debug ("Unable to lookup nexthop for rp specified");
- ret++;
- }
- }
- }
-
- if (ret)
- return 0;
-
- return 1;
+ struct listnode *node;
+ struct rp_info *rp_info;
+ int ret = 0;
+ struct prefix nht_p;
+ struct pim_nexthop_cache pnc;
+
+ for (ALL_LIST_ELEMENTS_RO(qpim_rp_list, node, rp_info)) {
+ if (rp_info->rp.rpf_addr.u.prefix4.s_addr == INADDR_NONE)
+ continue;
+
+ nht_p.family = AF_INET;
+ nht_p.prefixlen = IPV4_MAX_BITLEN;
+ nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
+ memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
+ if ((pim_find_or_track_nexthop(&nht_p, NULL, rp_info, &pnc))
+ == 1) {
+ // Compute PIM RPF using Cached nexthop
+ if ((pim_ecmp_nexthop_search(
+ &pnc, &rp_info->rp.source_nexthop, &nht_p,
+ &rp_info->group, 1))
+ != 0)
+ ret++;
+ } else {
+ if (PIM_DEBUG_ZEBRA) {
+ char buf[PREFIX2STR_BUFFER];
+ prefix2str(&nht_p, buf, sizeof(buf));
+ zlog_debug(
+ "%s: NHT Local Nexthop not found for RP %s ",
+ __PRETTY_FUNCTION__, buf);
+ }
+ if (pim_nexthop_lookup(&rp_info->rp.source_nexthop,
+ rp_info->rp.rpf_addr.u.prefix4,
+ 1)
+ != 0) {
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug(
+ "Unable to lookup nexthop for rp specified");
+ ret++;
+ }
+ }
+ }
+
+ if (ret)
+ return 0;
+
+ return 1;
}
/*
* Checks to see if we should elect ourself the actual RP when new if
* addresses are added against an interface.
*/
-void
-pim_rp_check_on_if_add(struct pim_interface *pim_ifp)
+void pim_rp_check_on_if_add(struct pim_interface *pim_ifp)
{
- struct listnode *node;
- struct rp_info *rp_info;
- bool i_am_rp_changed = false;
-
- if (qpim_rp_list == NULL)
- return;
-
- for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info)) {
- if (pim_rpf_addr_is_inaddr_none (&rp_info->rp))
- continue;
-
- /* if i_am_rp is already set nothing to be done (adding new addresses
- * is not going to make a difference). */
- if (rp_info->i_am_rp) {
- continue;
- }
-
- if (pim_rp_check_interface_addrs(rp_info, pim_ifp)) {
- i_am_rp_changed = true;
- rp_info->i_am_rp = 1;
- if (PIM_DEBUG_ZEBRA) {
- char rp[PREFIX_STRLEN];
- pim_addr_dump("<rp?>", &rp_info->rp.rpf_addr, rp, sizeof(rp));
- zlog_debug("%s: %s: i am rp", __func__, rp);
- }
- }
- }
-
- if (i_am_rp_changed) {
- pim_msdp_i_am_rp_changed();
- }
+ struct listnode *node;
+ struct rp_info *rp_info;
+ bool i_am_rp_changed = false;
+
+ if (qpim_rp_list == NULL)
+ return;
+
+ for (ALL_LIST_ELEMENTS_RO(qpim_rp_list, node, rp_info)) {
+ if (pim_rpf_addr_is_inaddr_none(&rp_info->rp))
+ continue;
+
+ /* if i_am_rp is already set nothing to be done (adding new
+ * addresses
+ * is not going to make a difference). */
+ if (rp_info->i_am_rp) {
+ continue;
+ }
+
+ if (pim_rp_check_interface_addrs(rp_info, pim_ifp)) {
+ i_am_rp_changed = true;
+ rp_info->i_am_rp = 1;
+ if (PIM_DEBUG_ZEBRA) {
+ char rp[PREFIX_STRLEN];
+ pim_addr_dump("<rp?>", &rp_info->rp.rpf_addr,
+ rp, sizeof(rp));
+ zlog_debug("%s: %s: i am rp", __func__, rp);
+ }
+ }
+ }
+
+ if (i_am_rp_changed) {
+ pim_msdp_i_am_rp_changed();
+ }
}
/* up-optimized re-evaluation of "i_am_rp". this is used when ifaddresses
* are removed. Removing numbers is an uncommon event in an active network
* so I have made no attempt to optimize it. */
-void
-pim_i_am_rp_re_evaluate(void)
+void pim_i_am_rp_re_evaluate(void)
{
- struct listnode *node;
- struct rp_info *rp_info;
- bool i_am_rp_changed = false;
- int old_i_am_rp;
-
- if (qpim_rp_list == NULL)
- return;
-
- for (ALL_LIST_ELEMENTS_RO(qpim_rp_list, node, rp_info)) {
- if (pim_rpf_addr_is_inaddr_none(&rp_info->rp))
- continue;
-
- old_i_am_rp = rp_info->i_am_rp;
- pim_rp_check_interfaces(rp_info);
-
- if (old_i_am_rp != rp_info->i_am_rp) {
- i_am_rp_changed = true;
- if (PIM_DEBUG_ZEBRA) {
- char rp[PREFIX_STRLEN];
- pim_addr_dump("<rp?>", &rp_info->rp.rpf_addr, rp, sizeof(rp));
- if (rp_info->i_am_rp) {
- zlog_debug("%s: %s: i am rp", __func__, rp);
- } else {
- zlog_debug("%s: %s: i am no longer rp", __func__, rp);
- }
- }
- }
- }
-
- if (i_am_rp_changed) {
- pim_msdp_i_am_rp_changed();
- }
+ struct listnode *node;
+ struct rp_info *rp_info;
+ bool i_am_rp_changed = false;
+ int old_i_am_rp;
+
+ if (qpim_rp_list == NULL)
+ return;
+
+ for (ALL_LIST_ELEMENTS_RO(qpim_rp_list, node, rp_info)) {
+ if (pim_rpf_addr_is_inaddr_none(&rp_info->rp))
+ continue;
+
+ old_i_am_rp = rp_info->i_am_rp;
+ pim_rp_check_interfaces(rp_info);
+
+ if (old_i_am_rp != rp_info->i_am_rp) {
+ i_am_rp_changed = true;
+ if (PIM_DEBUG_ZEBRA) {
+ char rp[PREFIX_STRLEN];
+ pim_addr_dump("<rp?>", &rp_info->rp.rpf_addr,
+ rp, sizeof(rp));
+ if (rp_info->i_am_rp) {
+ zlog_debug("%s: %s: i am rp", __func__,
+ rp);
+ } else {
+ zlog_debug("%s: %s: i am no longer rp",
+ __func__, rp);
+ }
+ }
+ }
+ }
+
+ if (i_am_rp_changed) {
+ pim_msdp_i_am_rp_changed();
+ }
}
/*
@@ -691,23 +675,22 @@ pim_i_am_rp_re_evaluate(void)
*
* Since we only have static RP, all groups are part of this RP
*/
-int
-pim_rp_i_am_rp (struct in_addr group)
+int pim_rp_i_am_rp(struct in_addr group)
{
- struct prefix g;
- struct rp_info *rp_info;
+ struct prefix g;
+ struct rp_info *rp_info;
- memset (&g, 0, sizeof (g));
- g.family = AF_INET;
- g.prefixlen = 32;
- g.u.prefix4 = group;
+ memset(&g, 0, sizeof(g));
+ g.family = AF_INET;
+ g.prefixlen = 32;
+ g.u.prefix4 = group;
- rp_info = pim_rp_find_match_group (&g);
+ rp_info = pim_rp_find_match_group(&g);
- if (rp_info)
- return rp_info->i_am_rp;
+ if (rp_info)
+ return rp_info->i_am_rp;
- return 0;
+ return 0;
}
/*
@@ -715,62 +698,60 @@ pim_rp_i_am_rp (struct in_addr group)
*
* Return the RP that the Group belongs too.
*/
-struct pim_rpf *
-pim_rp_g (struct in_addr group)
+struct pim_rpf *pim_rp_g(struct in_addr group)
{
- struct prefix g;
- struct rp_info *rp_info;
-
- memset (&g, 0, sizeof (g));
- g.family = AF_INET;
- g.prefixlen = 32;
- g.u.prefix4 = group;
-
- rp_info = pim_rp_find_match_group (&g);
-
- if (rp_info)
- {
- struct prefix nht_p;
- struct pim_nexthop_cache pnc;
- /* Register addr with Zebra NHT */
- nht_p.family = AF_INET;
- nht_p.prefixlen = IPV4_MAX_BITLEN;
- nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
- if (PIM_DEBUG_PIM_TRACE)
- {
- char buf[PREFIX2STR_BUFFER];
- char buf1[PREFIX2STR_BUFFER];
- prefix2str (&nht_p, buf, sizeof (buf));
- prefix2str (&rp_info->group, buf1, sizeof (buf1));
- zlog_debug ("%s: NHT Register RP addr %s grp %s with Zebra",
- __PRETTY_FUNCTION__, buf, buf1);
- }
- memset (&pnc, 0, sizeof (struct pim_nexthop_cache));
- if ((pim_find_or_track_nexthop (&nht_p, NULL, rp_info, &pnc)) == 1)
- {
- //Compute PIM RPF using Cached nexthop
- pim_ecmp_nexthop_search (&pnc, &rp_info->rp.source_nexthop,
- &nht_p, &rp_info->group, 1);
- }
- else
- {
- if (PIM_DEBUG_ZEBRA)
- {
- char buf[PREFIX2STR_BUFFER];
- char buf1[PREFIX2STR_BUFFER];
- prefix2str (&nht_p, buf, sizeof (buf));
- prefix2str (&g, buf1, sizeof (buf1));
- zlog_debug ("%s: Nexthop cache not found for RP %s grp %s register with Zebra",
- __PRETTY_FUNCTION__, buf, buf1);
- }
- pim_rpf_set_refresh_time ();
- pim_nexthop_lookup (&rp_info->rp.source_nexthop, rp_info->rp.rpf_addr.u.prefix4, 1);
- }
- return (&rp_info->rp);
- }
-
- // About to Go Down
- return NULL;
+ struct prefix g;
+ struct rp_info *rp_info;
+
+ memset(&g, 0, sizeof(g));
+ g.family = AF_INET;
+ g.prefixlen = 32;
+ g.u.prefix4 = group;
+
+ rp_info = pim_rp_find_match_group(&g);
+
+ if (rp_info) {
+ struct prefix nht_p;
+ struct pim_nexthop_cache pnc;
+ /* Register addr with Zebra NHT */
+ nht_p.family = AF_INET;
+ nht_p.prefixlen = IPV4_MAX_BITLEN;
+ nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
+ if (PIM_DEBUG_PIM_TRACE) {
+ char buf[PREFIX2STR_BUFFER];
+ char buf1[PREFIX2STR_BUFFER];
+ prefix2str(&nht_p, buf, sizeof(buf));
+ prefix2str(&rp_info->group, buf1, sizeof(buf1));
+ zlog_debug(
+ "%s: NHT Register RP addr %s grp %s with Zebra",
+ __PRETTY_FUNCTION__, buf, buf1);
+ }
+ memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
+ if ((pim_find_or_track_nexthop(&nht_p, NULL, rp_info, &pnc))
+ == 1) {
+ // Compute PIM RPF using Cached nexthop
+ pim_ecmp_nexthop_search(&pnc,
+ &rp_info->rp.source_nexthop,
+ &nht_p, &rp_info->group, 1);
+ } else {
+ if (PIM_DEBUG_ZEBRA) {
+ char buf[PREFIX2STR_BUFFER];
+ char buf1[PREFIX2STR_BUFFER];
+ prefix2str(&nht_p, buf, sizeof(buf));
+ prefix2str(&g, buf1, sizeof(buf1));
+ zlog_debug(
+ "%s: Nexthop cache not found for RP %s grp %s register with Zebra",
+ __PRETTY_FUNCTION__, buf, buf1);
+ }
+ pim_rpf_set_refresh_time();
+ pim_nexthop_lookup(&rp_info->rp.source_nexthop,
+ rp_info->rp.rpf_addr.u.prefix4, 1);
+ }
+ return (&rp_info->rp);
+ }
+
+ // About to Go Down
+ return NULL;
}
/*
@@ -781,222 +762,253 @@ pim_rp_g (struct in_addr group)
* then return failure.
*
*/
-int
-pim_rp_set_upstream_addr (struct in_addr *up, struct in_addr source, struct in_addr group)
+int pim_rp_set_upstream_addr(struct in_addr *up, struct in_addr source,
+ struct in_addr group)
{
- struct rp_info *rp_info;
- struct prefix g;
+ struct rp_info *rp_info;
+ struct prefix g;
- memset (&g, 0, sizeof (g));
- g.family = AF_INET;
- g.prefixlen = 32;
- g.u.prefix4 = group;
+ memset(&g, 0, sizeof(g));
+ g.family = AF_INET;
+ g.prefixlen = 32;
+ g.u.prefix4 = group;
- rp_info = pim_rp_find_match_group (&g);
+ rp_info = pim_rp_find_match_group(&g);
- if ((pim_rpf_addr_is_inaddr_none (&rp_info->rp)) && (source.s_addr == INADDR_ANY))
- {
- if (PIM_DEBUG_PIM_TRACE)
- zlog_debug("%s: Received a (*,G) with no RP configured", __PRETTY_FUNCTION__);
- return 0;
- }
+ if ((pim_rpf_addr_is_inaddr_none(&rp_info->rp))
+ && (source.s_addr == INADDR_ANY)) {
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug("%s: Received a (*,G) with no RP configured",
+ __PRETTY_FUNCTION__);
+ return 0;
+ }
- *up = (source.s_addr == INADDR_ANY) ? rp_info->rp.rpf_addr.u.prefix4 : source;
+ *up = (source.s_addr == INADDR_ANY) ? rp_info->rp.rpf_addr.u.prefix4
+ : source;
- return 1;
+ return 1;
}
-int
-pim_rp_config_write (struct vty *vty)
+int pim_rp_config_write(struct vty *vty)
{
- struct listnode *node;
- struct rp_info *rp_info;
- char rp_buffer[32];
- char group_buffer[32];
- int count = 0;
-
- for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
- {
- if (pim_rpf_addr_is_inaddr_none (&rp_info->rp))
- continue;
-
- if (rp_info->plist)
- vty_out (vty, "ip pim rp %s prefix-list %s\n",
- inet_ntop(AF_INET, &rp_info->rp.rpf_addr.u.prefix4, rp_buffer, 32),
- rp_info->plist);
- else
- vty_out (vty, "ip pim rp %s %s\n",
- inet_ntop(AF_INET, &rp_info->rp.rpf_addr.u.prefix4, rp_buffer, 32),
- prefix2str(&rp_info->group, group_buffer, 32));
- count++;
- }
-
- return count;
+ struct listnode *node;
+ struct rp_info *rp_info;
+ char rp_buffer[32];
+ char group_buffer[32];
+ int count = 0;
+
+ for (ALL_LIST_ELEMENTS_RO(qpim_rp_list, node, rp_info)) {
+ if (pim_rpf_addr_is_inaddr_none(&rp_info->rp))
+ continue;
+
+ if (rp_info->plist)
+ vty_out(vty, "ip pim rp %s prefix-list %s\n",
+ inet_ntop(AF_INET,
+ &rp_info->rp.rpf_addr.u.prefix4,
+ rp_buffer, 32),
+ rp_info->plist);
+ else
+ vty_out(vty, "ip pim rp %s %s\n",
+ inet_ntop(AF_INET,
+ &rp_info->rp.rpf_addr.u.prefix4,
+ rp_buffer, 32),
+ prefix2str(&rp_info->group, group_buffer, 32));
+ count++;
+ }
+
+ return count;
}
-int
-pim_rp_check_is_my_ip_address (struct in_addr group, struct in_addr dest_addr)
+int pim_rp_check_is_my_ip_address(struct in_addr group,
+ struct in_addr dest_addr)
{
- struct rp_info *rp_info;
- struct prefix g;
-
- memset (&g, 0, sizeof (g));
- g.family = AF_INET;
- g.prefixlen = 32;
- g.u.prefix4 = group;
-
- rp_info = pim_rp_find_match_group (&g);
- /*
- * See if we can short-cut some?
- * This might not make sense if we ever leave a static RP
- * type of configuration.
- * Note - Premature optimization might bite our patooeys' here.
- */
- if (I_am_RP(group))
- {
- if (dest_addr.s_addr == rp_info->rp.rpf_addr.u.prefix4.s_addr)
- return 1;
- }
-
- if (if_lookup_exact_address (&dest_addr, AF_INET, VRF_DEFAULT))
- return 1;
-
- return 0;
+ struct rp_info *rp_info;
+ struct prefix g;
+
+ memset(&g, 0, sizeof(g));
+ g.family = AF_INET;
+ g.prefixlen = 32;
+ g.u.prefix4 = group;
+
+ rp_info = pim_rp_find_match_group(&g);
+ /*
+ * See if we can short-cut some?
+ * This might not make sense if we ever leave a static RP
+ * type of configuration.
+ * Note - Premature optimization might bite our patooeys' here.
+ */
+ if (I_am_RP(group)) {
+ if (dest_addr.s_addr == rp_info->rp.rpf_addr.u.prefix4.s_addr)
+ return 1;
+ }
+
+ if (if_lookup_exact_address(&dest_addr, AF_INET, VRF_DEFAULT))
+ return 1;
+
+ return 0;
}
-void
-pim_rp_show_information (struct vty *vty, u_char uj)
+void pim_rp_show_information(struct vty *vty, u_char uj)
{
- struct rp_info *rp_info;
- struct rp_info *prev_rp_info = NULL;
- struct listnode *node;
-
- json_object *json = NULL;
- json_object *json_rp_rows = NULL;
- json_object *json_row = NULL;
-
- if (uj)
- json = json_object_new_object();
- else
- vty_out (vty,
- "RP address group/prefix-list OIF I am RP\n");
-
- for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
- {
- if (!pim_rpf_addr_is_inaddr_none (&rp_info->rp))
- {
- char buf[48];
-
- if (uj)
- {
- /*
- * If we have moved on to a new RP then add the entry for the previous RP
- */
- if (prev_rp_info &&
- prev_rp_info->rp.rpf_addr.u.prefix4.s_addr != rp_info->rp.rpf_addr.u.prefix4.s_addr)
- {
- json_object_object_add(json, inet_ntoa (prev_rp_info->rp.rpf_addr.u.prefix4), json_rp_rows);
- json_rp_rows = NULL;
- }
-
- if (!json_rp_rows)
- json_rp_rows = json_object_new_array();
-
- json_row = json_object_new_object();
- if (rp_info->rp.source_nexthop.interface)
- json_object_string_add(json_row, "outboundInterface", rp_info->rp.source_nexthop.interface->name);
-
- if (rp_info->i_am_rp)
- json_object_boolean_true_add(json_row, "iAmRP");
-
- if (rp_info->plist)
- json_object_string_add(json_row, "prefixList", rp_info->plist);
- else
- json_object_string_add(json_row, "group", prefix2str(&rp_info->group, buf, 48));
-
- json_object_array_add(json_rp_rows, json_row);
- }
- else
- {
- vty_out (vty, "%-15s ", inet_ntoa (rp_info->rp.rpf_addr.u.prefix4));
-
- if (rp_info->plist)
- vty_out (vty, "%-18s ", rp_info->plist);
- else
- vty_out (vty, "%-18s ", prefix2str(&rp_info->group, buf, 48));
-
- if (rp_info->rp.source_nexthop.interface)
- vty_out (vty, "%-10s ", rp_info->rp.source_nexthop.interface->name);
- else
- vty_out (vty, "%-10s ", "(Unknown)");
-
- if (rp_info->i_am_rp)
- vty_out (vty, "yes\n");
- else
- vty_out (vty, "no\n");
- }
-
- prev_rp_info = rp_info;
- }
- }
-
- if (uj) {
- if (prev_rp_info && json_rp_rows)
- json_object_object_add(json, inet_ntoa (prev_rp_info->rp.rpf_addr.u.prefix4), json_rp_rows);
-
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
+ struct rp_info *rp_info;
+ struct rp_info *prev_rp_info = NULL;
+ struct listnode *node;
+
+ json_object *json = NULL;
+ json_object *json_rp_rows = NULL;
+ json_object *json_row = NULL;
+
+ if (uj)
+ json = json_object_new_object();
+ else
+ vty_out(vty,
+ "RP address group/prefix-list OIF I am RP\n");
+
+ for (ALL_LIST_ELEMENTS_RO(qpim_rp_list, node, rp_info)) {
+ if (!pim_rpf_addr_is_inaddr_none(&rp_info->rp)) {
+ char buf[48];
+
+ if (uj) {
+ /*
+ * If we have moved on to a new RP then add the
+ * entry for the previous RP
+ */
+ if (prev_rp_info
+ && prev_rp_info->rp.rpf_addr.u.prefix4
+ .s_addr
+ != rp_info->rp.rpf_addr.u.prefix4
+ .s_addr) {
+ json_object_object_add(
+ json,
+ inet_ntoa(prev_rp_info->rp
+ .rpf_addr.u
+ .prefix4),
+ json_rp_rows);
+ json_rp_rows = NULL;
+ }
+
+ if (!json_rp_rows)
+ json_rp_rows = json_object_new_array();
+
+ json_row = json_object_new_object();
+ if (rp_info->rp.source_nexthop.interface)
+ json_object_string_add(
+ json_row, "outboundInterface",
+ rp_info->rp.source_nexthop
+ .interface->name);
+
+ if (rp_info->i_am_rp)
+ json_object_boolean_true_add(json_row,
+ "iAmRP");
+
+ if (rp_info->plist)
+ json_object_string_add(json_row,
+ "prefixList",
+ rp_info->plist);
+ else
+ json_object_string_add(
+ json_row, "group",
+ prefix2str(&rp_info->group, buf,
+ 48));
+
+ json_object_array_add(json_rp_rows, json_row);
+ } else {
+ vty_out(vty, "%-15s ",
+ inet_ntoa(rp_info->rp.rpf_addr.u
+ .prefix4));
+
+ if (rp_info->plist)
+ vty_out(vty, "%-18s ", rp_info->plist);
+ else
+ vty_out(vty, "%-18s ",
+ prefix2str(&rp_info->group, buf,
+ 48));
+
+ if (rp_info->rp.source_nexthop.interface)
+ vty_out(vty, "%-10s ",
+ rp_info->rp.source_nexthop
+ .interface->name);
+ else
+ vty_out(vty, "%-10s ", "(Unknown)");
+
+ if (rp_info->i_am_rp)
+ vty_out(vty, "yes\n");
+ else
+ vty_out(vty, "no\n");
+ }
+
+ prev_rp_info = rp_info;
+ }
+ }
+
+ if (uj) {
+ if (prev_rp_info && json_rp_rows)
+ json_object_object_add(
+ json,
+ inet_ntoa(prev_rp_info->rp.rpf_addr.u.prefix4),
+ json_rp_rows);
+
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
}
-void
-pim_resolve_rp_nh (void)
+void pim_resolve_rp_nh(void)
{
- struct listnode *node = NULL;
- struct rp_info *rp_info = NULL;
- struct nexthop *nh_node = NULL;
- struct prefix nht_p;
- struct pim_nexthop_cache pnc;
- struct pim_neighbor *nbr = NULL;
-
- for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info))
- {
- if (rp_info->rp.rpf_addr.u.prefix4.s_addr == INADDR_NONE)
- continue;
-
- nht_p.family = AF_INET;
- nht_p.prefixlen = IPV4_MAX_BITLEN;
- nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
- memset (&pnc, 0, sizeof (struct pim_nexthop_cache));
- if ((pim_find_or_track_nexthop (&nht_p, NULL, rp_info, &pnc)) == 1)
- {
- for (nh_node = pnc.nexthop; nh_node; nh_node = nh_node->next)
- {
- if (nh_node->gate.ipv4.s_addr == 0)
- {
- nbr = pim_neighbor_find_if (if_lookup_by_index
- (nh_node->ifindex, VRF_DEFAULT));
- if (nbr)
- {
- nh_node->gate.ipv4 = nbr->source_addr;
- if (PIM_DEBUG_TRACE)
- {
- char str[PREFIX_STRLEN];
- char str1[INET_ADDRSTRLEN];
- struct interface *ifp1 = if_lookup_by_index(nh_node->ifindex,
- VRF_DEFAULT);
- pim_inet4_dump ("<nht_nbr?>", nbr->source_addr,
- str1, sizeof (str1));
- pim_addr_dump ("<nht_addr?>", &nht_p, str,
- sizeof (str));
- zlog_debug ("%s: addr %s new nexthop addr %s interface %s",
- __PRETTY_FUNCTION__, str, str1,
- ifp1->name);
- }
- }
- }
- }
- }
- }
+ struct listnode *node = NULL;
+ struct rp_info *rp_info = NULL;
+ struct nexthop *nh_node = NULL;
+ struct prefix nht_p;
+ struct pim_nexthop_cache pnc;
+ struct pim_neighbor *nbr = NULL;
+
+ for (ALL_LIST_ELEMENTS_RO(qpim_rp_list, node, rp_info)) {
+ if (rp_info->rp.rpf_addr.u.prefix4.s_addr == INADDR_NONE)
+ continue;
+
+ nht_p.family = AF_INET;
+ nht_p.prefixlen = IPV4_MAX_BITLEN;
+ nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
+ memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
+ if ((pim_find_or_track_nexthop(&nht_p, NULL, rp_info, &pnc))
+ == 1) {
+ for (nh_node = pnc.nexthop; nh_node;
+ nh_node = nh_node->next) {
+ if (nh_node->gate.ipv4.s_addr == 0) {
+ nbr = pim_neighbor_find_if(
+ if_lookup_by_index(
+ nh_node->ifindex,
+ VRF_DEFAULT));
+ if (nbr) {
+ nh_node->gate.ipv4 =
+ nbr->source_addr;
+ if (PIM_DEBUG_TRACE) {
+ char str[PREFIX_STRLEN];
+ char str1
+ [INET_ADDRSTRLEN];
+ struct interface *ifp1 =
+ if_lookup_by_index(
+ nh_node->ifindex,
+ VRF_DEFAULT);
+ pim_inet4_dump(
+ "<nht_nbr?>",
+ nbr->source_addr,
+ str1,
+ sizeof(str1));
+ pim_addr_dump(
+ "<nht_addr?>",
+ &nht_p, str,
+ sizeof(str));
+ zlog_debug(
+ "%s: addr %s new nexthop addr %s interface %s",
+ __PRETTY_FUNCTION__,
+ str, str1,
+ ifp1->name);
+ }
+ }
+ }
+ }
+ }
+ }
}
diff --git a/pimd/pim_rp.h b/pimd/pim_rp.h
index 319fe573c..7a7c26593 100644
--- a/pimd/pim_rp.h
+++ b/pimd/pim_rp.h
@@ -27,39 +27,40 @@
#include "pim_iface.h"
#include "pim_rpf.h"
-struct rp_info
-{
- struct prefix group;
- struct pim_rpf rp;
- int i_am_rp;
- char *plist;
+struct rp_info {
+ struct prefix group;
+ struct pim_rpf rp;
+ int i_am_rp;
+ char *plist;
};
-void pim_rp_init (void);
-void pim_rp_free (void);
+void pim_rp_init(void);
+void pim_rp_free(void);
-int pim_rp_new (const char *rp, const char *group, const char *plist);
-int pim_rp_del (const char *rp, const char *group, const char *plist);
-void pim_rp_prefix_list_update (struct prefix_list *plist);
+int pim_rp_new(const char *rp, const char *group, const char *plist);
+int pim_rp_del(const char *rp, const char *group, const char *plist);
+void pim_rp_prefix_list_update(struct prefix_list *plist);
-int pim_rp_config_write (struct vty *vty);
+int pim_rp_config_write(struct vty *vty);
-int pim_rp_setup (void);
+int pim_rp_setup(void);
-int pim_rp_i_am_rp (struct in_addr group);
+int pim_rp_i_am_rp(struct in_addr group);
void pim_rp_check_on_if_add(struct pim_interface *pim_ifp);
void pim_i_am_rp_re_evaluate(void);
-int pim_rp_check_is_my_ip_address (struct in_addr group, struct in_addr dest_addr);
+int pim_rp_check_is_my_ip_address(struct in_addr group,
+ struct in_addr dest_addr);
-int pim_rp_set_upstream_addr (struct in_addr *up, struct in_addr source, struct in_addr group);
+int pim_rp_set_upstream_addr(struct in_addr *up, struct in_addr source,
+ struct in_addr group);
-struct pim_rpf *pim_rp_g (struct in_addr group);
+struct pim_rpf *pim_rp_g(struct in_addr group);
#define I_am_RP(G) pim_rp_i_am_rp ((G))
#define RP(G) pim_rp_g ((G))
-void pim_rp_show_information (struct vty *vty, u_char uj);
-void pim_resolve_rp_nh (void);
-int pim_rp_list_cmp (void *v1, void *v2);
+void pim_rp_show_information(struct vty *vty, u_char uj);
+void pim_resolve_rp_nh(void);
+int pim_rp_list_cmp(void *v1, void *v2);
#endif
diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c
index c5adf423c..4d0652c27 100644
--- a/pimd/pim_rpf.c
+++ b/pimd/pim_rpf.c
@@ -38,285 +38,281 @@
static long long last_route_change_time = -1;
long long nexthop_lookups_avoided = 0;
-static struct in_addr pim_rpf_find_rpf_addr (struct pim_upstream *up);
+static struct in_addr pim_rpf_find_rpf_addr(struct pim_upstream *up);
-void
-pim_rpf_set_refresh_time (void)
+void pim_rpf_set_refresh_time(void)
{
- last_route_change_time = pim_time_monotonic_usec();
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: New last route change time: %lld",
- __PRETTY_FUNCTION__, last_route_change_time);
+ last_route_change_time = pim_time_monotonic_usec();
+ if (PIM_DEBUG_TRACE)
+ zlog_debug("%s: New last route change time: %lld",
+ __PRETTY_FUNCTION__, last_route_change_time);
}
-int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr, int neighbor_needed)
+int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr,
+ int neighbor_needed)
{
- struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM];
- struct pim_neighbor *nbr = NULL;
- int num_ifindex;
- struct interface *ifp = NULL;
- ifindex_t first_ifindex = 0;
- int found = 0;
- int i = 0;
-
- if ((nexthop->last_lookup.s_addr == addr.s_addr) &&
- (nexthop->last_lookup_time > last_route_change_time))
- {
- if (PIM_DEBUG_TRACE)
- {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- char nexthop_str[PREFIX_STRLEN];
- pim_addr_dump("<nexthop?>", &nexthop->mrib_nexthop_addr,
- nexthop_str, sizeof(nexthop_str));
- zlog_debug ("%s: Using last lookup for %s at %lld, %lld addr%s",
- __PRETTY_FUNCTION__,
- addr_str,
- nexthop->last_lookup_time,
- last_route_change_time, nexthop_str);
+ struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM];
+ struct pim_neighbor *nbr = NULL;
+ int num_ifindex;
+ struct interface *ifp = NULL;
+ ifindex_t first_ifindex = 0;
+ int found = 0;
+ int i = 0;
+
+ if ((nexthop->last_lookup.s_addr == addr.s_addr)
+ && (nexthop->last_lookup_time > last_route_change_time)) {
+ if (PIM_DEBUG_TRACE) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str,
+ sizeof(addr_str));
+ char nexthop_str[PREFIX_STRLEN];
+ pim_addr_dump("<nexthop?>", &nexthop->mrib_nexthop_addr,
+ nexthop_str, sizeof(nexthop_str));
+ zlog_debug(
+ "%s: Using last lookup for %s at %lld, %lld addr%s",
+ __PRETTY_FUNCTION__, addr_str,
+ nexthop->last_lookup_time,
+ last_route_change_time, nexthop_str);
+ }
+ nexthop_lookups_avoided++;
+ return 0;
+ } else {
+ if (PIM_DEBUG_TRACE) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str,
+ sizeof(addr_str));
+ zlog_debug(
+ "%s: Looking up: %s, last lookup time: %lld, %lld",
+ __PRETTY_FUNCTION__, addr_str,
+ nexthop->last_lookup_time,
+ last_route_change_time);
+ }
}
- nexthop_lookups_avoided++;
- return 0;
- }
- else
- {
- if (PIM_DEBUG_TRACE)
- {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_debug ("%s: Looking up: %s, last lookup time: %lld, %lld",
- __PRETTY_FUNCTION__,
- addr_str,
- nexthop->last_lookup_time,
- last_route_change_time);
+
+ memset(nexthop_tab, 0,
+ sizeof(struct pim_zlookup_nexthop) * MULTIPATH_NUM);
+ num_ifindex = zclient_lookup_nexthop(nexthop_tab, MULTIPATH_NUM, addr,
+ PIM_NEXTHOP_LOOKUP_MAX);
+ if (num_ifindex < 1) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+ zlog_warn(
+ "%s %s: could not find nexthop ifindex for address %s",
+ __FILE__, __PRETTY_FUNCTION__, addr_str);
+ return -1;
+ }
+
+ while (!found && (i < num_ifindex)) {
+ first_ifindex = nexthop_tab[i].ifindex;
+
+ ifp = if_lookup_by_index(first_ifindex, VRF_DEFAULT);
+ if (!ifp) {
+ if (PIM_DEBUG_ZEBRA) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str,
+ sizeof(addr_str));
+ zlog_debug(
+ "%s %s: could not find interface for ifindex %d (address %s)",
+ __FILE__, __PRETTY_FUNCTION__,
+ first_ifindex, addr_str);
+ }
+ i++;
+ continue;
+ }
+
+ if (!ifp->info) {
+ if (PIM_DEBUG_ZEBRA) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str,
+ sizeof(addr_str));
+ zlog_debug(
+ "%s: multicast not enabled on input interface %s (ifindex=%d, RPF for source %s)",
+ __PRETTY_FUNCTION__, ifp->name,
+ first_ifindex, addr_str);
+ }
+ i++;
+ } else if (neighbor_needed
+ && !pim_if_connected_to_source(ifp, addr)) {
+ nbr = pim_neighbor_find(
+ ifp, nexthop_tab[i].nexthop_addr.u.prefix4);
+ if (PIM_DEBUG_PIM_TRACE_DETAIL)
+ zlog_debug("ifp name: %s, pim nbr: %p",
+ ifp->name, nbr);
+ if (!nbr && !if_is_loopback(ifp))
+ i++;
+ else
+ found = 1;
+ } else
+ found = 1;
}
- }
-
- memset (nexthop_tab, 0, sizeof (struct pim_zlookup_nexthop) * MULTIPATH_NUM);
- num_ifindex = zclient_lookup_nexthop(nexthop_tab,
- MULTIPATH_NUM,
- addr, PIM_NEXTHOP_LOOKUP_MAX);
- if (num_ifindex < 1) {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_warn("%s %s: could not find nexthop ifindex for address %s",
- __FILE__, __PRETTY_FUNCTION__,
- addr_str);
- return -1;
- }
-
- while (!found && (i < num_ifindex))
- {
- first_ifindex = nexthop_tab[i].ifindex;
-
- ifp = if_lookup_by_index(first_ifindex, VRF_DEFAULT);
- if (!ifp)
- {
- if (PIM_DEBUG_ZEBRA)
- {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_debug("%s %s: could not find interface for ifindex %d (address %s)",
- __FILE__, __PRETTY_FUNCTION__,
- first_ifindex, addr_str);
- }
- i++;
- continue;
- }
-
- if (!ifp->info)
- {
- if (PIM_DEBUG_ZEBRA)
- {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_debug("%s: multicast not enabled on input interface %s (ifindex=%d, RPF for source %s)",
- __PRETTY_FUNCTION__,
- ifp->name, first_ifindex, addr_str);
- }
- i++;
- }
- else if (neighbor_needed && !pim_if_connected_to_source (ifp, addr))
- {
- nbr = pim_neighbor_find (ifp, nexthop_tab[i].nexthop_addr.u.prefix4);
- if (PIM_DEBUG_PIM_TRACE_DETAIL)
- zlog_debug ("ifp name: %s, pim nbr: %p", ifp->name, nbr);
- if (!nbr && !if_is_loopback (ifp))
- i++;
- else
- found = 1;
- }
- else
- found = 1;
- }
-
- if (found)
- {
- if (PIM_DEBUG_ZEBRA) {
- char nexthop_str[PREFIX_STRLEN];
- char addr_str[INET_ADDRSTRLEN];
- pim_addr_dump("<nexthop?>", &nexthop_tab[i].nexthop_addr, nexthop_str, sizeof(nexthop_str));
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_debug("%s %s: found nexthop %s for address %s: interface %s ifindex=%d metric=%d pref=%d",
- __FILE__, __PRETTY_FUNCTION__,
- nexthop_str, addr_str,
- ifp->name, first_ifindex,
- nexthop_tab[i].route_metric,
- nexthop_tab[i].protocol_distance);
- }
- /* update nextop data */
- nexthop->interface = ifp;
- nexthop->mrib_nexthop_addr = nexthop_tab[i].nexthop_addr;
- nexthop->mrib_metric_preference = nexthop_tab[i].protocol_distance;
- nexthop->mrib_route_metric = nexthop_tab[i].route_metric;
- nexthop->last_lookup = addr;
- nexthop->last_lookup_time = pim_time_monotonic_usec();
- nexthop->nbr = nbr;
- return 0;
- }
- else
- return -1;
+
+ if (found) {
+ if (PIM_DEBUG_ZEBRA) {
+ char nexthop_str[PREFIX_STRLEN];
+ char addr_str[INET_ADDRSTRLEN];
+ pim_addr_dump("<nexthop?>",
+ &nexthop_tab[i].nexthop_addr, nexthop_str,
+ sizeof(nexthop_str));
+ pim_inet4_dump("<addr?>", addr, addr_str,
+ sizeof(addr_str));
+ zlog_debug(
+ "%s %s: found nexthop %s for address %s: interface %s ifindex=%d metric=%d pref=%d",
+ __FILE__, __PRETTY_FUNCTION__, nexthop_str,
+ addr_str, ifp->name, first_ifindex,
+ nexthop_tab[i].route_metric,
+ nexthop_tab[i].protocol_distance);
+ }
+ /* update nextop data */
+ nexthop->interface = ifp;
+ nexthop->mrib_nexthop_addr = nexthop_tab[i].nexthop_addr;
+ nexthop->mrib_metric_preference =
+ nexthop_tab[i].protocol_distance;
+ nexthop->mrib_route_metric = nexthop_tab[i].route_metric;
+ nexthop->last_lookup = addr;
+ nexthop->last_lookup_time = pim_time_monotonic_usec();
+ nexthop->nbr = nbr;
+ return 0;
+ } else
+ return -1;
}
static int nexthop_mismatch(const struct pim_nexthop *nh1,
const struct pim_nexthop *nh2)
{
- return (nh1->interface != nh2->interface) ||
- (nh1->mrib_nexthop_addr.u.prefix4.s_addr != nh2->mrib_nexthop_addr.u.prefix4.s_addr) ||
- (nh1->mrib_metric_preference != nh2->mrib_metric_preference) ||
- (nh1->mrib_route_metric != nh2->mrib_route_metric);
+ return (nh1->interface != nh2->interface)
+ || (nh1->mrib_nexthop_addr.u.prefix4.s_addr
+ != nh2->mrib_nexthop_addr.u.prefix4.s_addr)
+ || (nh1->mrib_metric_preference != nh2->mrib_metric_preference)
+ || (nh1->mrib_route_metric != nh2->mrib_route_metric);
}
-enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct pim_rpf *old, uint8_t is_new)
+enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct pim_rpf *old,
+ uint8_t is_new)
{
- struct pim_rpf *rpf = &up->rpf;
- struct pim_rpf saved;
- struct prefix nht_p;
- struct pim_nexthop_cache pnc;
- int ret = 0;
- struct prefix src, grp;
-
- saved.source_nexthop = rpf->source_nexthop;
- saved.rpf_addr = rpf->rpf_addr;
-
- if (is_new && PIM_DEBUG_ZEBRA)
- {
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump ("<source?>", up->upstream_addr, source_str,
- sizeof (source_str));
- zlog_debug ("%s: NHT Register upstream %s addr %s with Zebra.",
- __PRETTY_FUNCTION__, up->sg_str, source_str);
- }
- /* Register addr with Zebra NHT */
- nht_p.family = AF_INET;
- nht_p.prefixlen = IPV4_MAX_BITLEN;
- nht_p.u.prefix4.s_addr = up->upstream_addr.s_addr;
-
- src.family = AF_INET;
- src.prefixlen = IPV4_MAX_BITLEN;
- src.u.prefix4 = up->upstream_addr; //RP or Src address
- grp.family = AF_INET;
- grp.prefixlen = IPV4_MAX_BITLEN;
- grp.u.prefix4 = up->sg.grp;
- memset (&pnc, 0, sizeof (struct pim_nexthop_cache));
- if ((ret = pim_find_or_track_nexthop (&nht_p, up, NULL, &pnc)) == 1)
- {
- if (pnc.nexthop_num)
- {
- //Compute PIM RPF using Cached nexthop
- if (pim_ecmp_nexthop_search (&pnc, &up->rpf.source_nexthop,
- &src, &grp,
- !PIM_UPSTREAM_FLAG_TEST_FHR (up->flags) &&
- !PIM_UPSTREAM_FLAG_TEST_SRC_IGMP (up->flags)))
-
- {
- return PIM_RPF_FAILURE;
- }
- }
- }
- else
- {
- if (pim_ecmp_nexthop_lookup (&rpf->source_nexthop,
- up->upstream_addr, &src, &grp,
- !PIM_UPSTREAM_FLAG_TEST_FHR (up->flags) &&
- !PIM_UPSTREAM_FLAG_TEST_SRC_IGMP (up->flags)))
- {
- return PIM_RPF_FAILURE;
- }
- }
-
- rpf->rpf_addr.family = AF_INET;
- rpf->rpf_addr.u.prefix4 = pim_rpf_find_rpf_addr(up);
- if (pim_rpf_addr_is_inaddr_any(rpf) && PIM_DEBUG_ZEBRA)
- {
- /* RPF'(S,G) not found */
- zlog_debug("%s %s: RPF'%s not found: won't send join upstream",
- __FILE__, __PRETTY_FUNCTION__,
- up->sg_str);
- /* warning only */
- }
-
- /* detect change in pim_nexthop */
- if (nexthop_mismatch(&rpf->source_nexthop, &saved.source_nexthop)) {
-
- if (PIM_DEBUG_ZEBRA) {
- char nhaddr_str[PREFIX_STRLEN];
- pim_addr_dump("<addr?>", &rpf->source_nexthop.mrib_nexthop_addr, nhaddr_str, sizeof(nhaddr_str));
- zlog_debug("%s %s: (S,G)=%s source nexthop now is: interface=%s address=%s pref=%d metric=%d",
+ struct pim_rpf *rpf = &up->rpf;
+ struct pim_rpf saved;
+ struct prefix nht_p;
+ struct pim_nexthop_cache pnc;
+ int ret = 0;
+ struct prefix src, grp;
+
+ saved.source_nexthop = rpf->source_nexthop;
+ saved.rpf_addr = rpf->rpf_addr;
+
+ if (is_new && PIM_DEBUG_ZEBRA) {
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<source?>", up->upstream_addr, source_str,
+ sizeof(source_str));
+ zlog_debug("%s: NHT Register upstream %s addr %s with Zebra.",
+ __PRETTY_FUNCTION__, up->sg_str, source_str);
+ }
+ /* Register addr with Zebra NHT */
+ nht_p.family = AF_INET;
+ nht_p.prefixlen = IPV4_MAX_BITLEN;
+ nht_p.u.prefix4.s_addr = up->upstream_addr.s_addr;
+
+ src.family = AF_INET;
+ src.prefixlen = IPV4_MAX_BITLEN;
+ src.u.prefix4 = up->upstream_addr; // RP or Src address
+ grp.family = AF_INET;
+ grp.prefixlen = IPV4_MAX_BITLEN;
+ grp.u.prefix4 = up->sg.grp;
+ memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
+ if ((ret = pim_find_or_track_nexthop(&nht_p, up, NULL, &pnc)) == 1) {
+ if (pnc.nexthop_num) {
+ // Compute PIM RPF using Cached nexthop
+ if (pim_ecmp_nexthop_search(
+ &pnc, &up->rpf.source_nexthop, &src, &grp,
+ !PIM_UPSTREAM_FLAG_TEST_FHR(up->flags)
+ && !PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(
+ up->flags)))
+
+ {
+ return PIM_RPF_FAILURE;
+ }
+ }
+ } else {
+ if (pim_ecmp_nexthop_lookup(
+ &rpf->source_nexthop, up->upstream_addr, &src, &grp,
+ !PIM_UPSTREAM_FLAG_TEST_FHR(up->flags)
+ && !PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(
+ up->flags))) {
+ return PIM_RPF_FAILURE;
+ }
+ }
+
+ rpf->rpf_addr.family = AF_INET;
+ rpf->rpf_addr.u.prefix4 = pim_rpf_find_rpf_addr(up);
+ if (pim_rpf_addr_is_inaddr_any(rpf) && PIM_DEBUG_ZEBRA) {
+ /* RPF'(S,G) not found */
+ zlog_debug("%s %s: RPF'%s not found: won't send join upstream",
+ __FILE__, __PRETTY_FUNCTION__, up->sg_str);
+ /* warning only */
+ }
+
+ /* detect change in pim_nexthop */
+ if (nexthop_mismatch(&rpf->source_nexthop, &saved.source_nexthop)) {
+
+ if (PIM_DEBUG_ZEBRA) {
+ char nhaddr_str[PREFIX_STRLEN];
+ pim_addr_dump("<addr?>",
+ &rpf->source_nexthop.mrib_nexthop_addr,
+ nhaddr_str, sizeof(nhaddr_str));
+ zlog_debug("%s %s: (S,G)=%s source nexthop now is: interface=%s address=%s pref=%d metric=%d",
__FILE__, __PRETTY_FUNCTION__,
up->sg_str,
rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>",
nhaddr_str,
rpf->source_nexthop.mrib_metric_preference,
rpf->source_nexthop.mrib_route_metric);
- }
+ }
- pim_upstream_update_join_desired(up);
- pim_upstream_update_could_assert(up);
- pim_upstream_update_my_assert_metric(up);
- }
+ pim_upstream_update_join_desired(up);
+ pim_upstream_update_could_assert(up);
+ pim_upstream_update_my_assert_metric(up);
+ }
- /* detect change in RPF_interface(S) */
- if (saved.source_nexthop.interface != rpf->source_nexthop.interface) {
+ /* detect change in RPF_interface(S) */
+ if (saved.source_nexthop.interface != rpf->source_nexthop.interface) {
- if (PIM_DEBUG_ZEBRA) {
- zlog_debug("%s %s: (S,G)=%s RPF_interface(S) changed from %s to %s",
+ if (PIM_DEBUG_ZEBRA) {
+ zlog_debug("%s %s: (S,G)=%s RPF_interface(S) changed from %s to %s",
__FILE__, __PRETTY_FUNCTION__,
up->sg_str,
saved.source_nexthop.interface ? saved.source_nexthop.interface->name : "<oldif?>",
rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<newif?>");
- /* warning only */
- }
-
- pim_upstream_rpf_interface_changed(up, saved.source_nexthop.interface);
- }
-
- /* detect change in RPF'(S,G) */
- if (saved.rpf_addr.u.prefix4.s_addr != rpf->rpf_addr.u.prefix4.s_addr ||
- saved.source_nexthop.interface != rpf->source_nexthop.interface)
- {
-
- /* return old rpf to caller ? */
- if (old)
- {
- old->source_nexthop = saved.source_nexthop;
- old->rpf_addr = saved.rpf_addr;
- }
- return PIM_RPF_CHANGED;
- }
-
- return PIM_RPF_OK;
+ /* warning only */
+ }
+
+ pim_upstream_rpf_interface_changed(
+ up, saved.source_nexthop.interface);
+ }
+
+ /* detect change in RPF'(S,G) */
+ if (saved.rpf_addr.u.prefix4.s_addr != rpf->rpf_addr.u.prefix4.s_addr
+ || saved.source_nexthop
+ .interface != rpf->source_nexthop.interface) {
+
+ /* return old rpf to caller ? */
+ if (old) {
+ old->source_nexthop = saved.source_nexthop;
+ old->rpf_addr = saved.rpf_addr;
+ }
+ return PIM_RPF_CHANGED;
+ }
+
+ return PIM_RPF_OK;
}
/*
RFC 4601: 4.1.6. State Summarization Macros
neighbor RPF'(S,G) {
- if ( I_Am_Assert_Loser(S, G, RPF_interface(S) )) {
- return AssertWinner(S, G, RPF_interface(S) )
- } else {
- return NBR( RPF_interface(S), MRIB.next_hop( S ) )
- }
+ if ( I_Am_Assert_Loser(S, G, RPF_interface(S) )) {
+ return AssertWinner(S, G, RPF_interface(S) )
+ } else {
+ return NBR( RPF_interface(S), MRIB.next_hop( S ) )
+ }
}
RPF'(*,G) and RPF'(S,G) indicate the neighbor from which data
@@ -325,84 +321,78 @@ enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct pim_rpf *old,
*/
static struct in_addr pim_rpf_find_rpf_addr(struct pim_upstream *up)
{
- struct pim_ifchannel *rpf_ch;
- struct pim_neighbor *neigh;
- struct in_addr rpf_addr;
-
- if (!up->rpf.source_nexthop.interface) {
- zlog_warn("%s: missing RPF interface for upstream (S,G)=%s",
- __PRETTY_FUNCTION__,
- up->sg_str);
-
- rpf_addr.s_addr = PIM_NET_INADDR_ANY;
- return rpf_addr;
- }
-
- rpf_ch = pim_ifchannel_find(up->rpf.source_nexthop.interface,
- &up->sg);
- if (rpf_ch) {
- if (rpf_ch->ifassert_state == PIM_IFASSERT_I_AM_LOSER) {
- return rpf_ch->ifassert_winner;
- }
- }
-
- /* return NBR( RPF_interface(S), MRIB.next_hop( S ) ) */
-
- neigh = pim_if_find_neighbor(up->rpf.source_nexthop.interface,
- up->rpf.source_nexthop.mrib_nexthop_addr.u.prefix4);
- if (neigh)
- rpf_addr = neigh->source_addr;
- else
- rpf_addr.s_addr = PIM_NET_INADDR_ANY;
-
- return rpf_addr;
+ struct pim_ifchannel *rpf_ch;
+ struct pim_neighbor *neigh;
+ struct in_addr rpf_addr;
+
+ if (!up->rpf.source_nexthop.interface) {
+ zlog_warn("%s: missing RPF interface for upstream (S,G)=%s",
+ __PRETTY_FUNCTION__, up->sg_str);
+
+ rpf_addr.s_addr = PIM_NET_INADDR_ANY;
+ return rpf_addr;
+ }
+
+ rpf_ch = pim_ifchannel_find(up->rpf.source_nexthop.interface, &up->sg);
+ if (rpf_ch) {
+ if (rpf_ch->ifassert_state == PIM_IFASSERT_I_AM_LOSER) {
+ return rpf_ch->ifassert_winner;
+ }
+ }
+
+ /* return NBR( RPF_interface(S), MRIB.next_hop( S ) ) */
+
+ neigh = pim_if_find_neighbor(
+ up->rpf.source_nexthop.interface,
+ up->rpf.source_nexthop.mrib_nexthop_addr.u.prefix4);
+ if (neigh)
+ rpf_addr = neigh->source_addr;
+ else
+ rpf_addr.s_addr = PIM_NET_INADDR_ANY;
+
+ return rpf_addr;
}
-int
-pim_rpf_addr_is_inaddr_none (struct pim_rpf *rpf)
+int pim_rpf_addr_is_inaddr_none(struct pim_rpf *rpf)
{
- switch (rpf->rpf_addr.family)
- {
- case AF_INET:
- return rpf->rpf_addr.u.prefix4.s_addr == INADDR_NONE;
- break;
- case AF_INET6:
- zlog_warn ("%s: v6 Unimplmeneted", __PRETTY_FUNCTION__);
- return 1;
- break;
- default:
- return 0;
- break;
- }
-
- return 0;
+ switch (rpf->rpf_addr.family) {
+ case AF_INET:
+ return rpf->rpf_addr.u.prefix4.s_addr == INADDR_NONE;
+ break;
+ case AF_INET6:
+ zlog_warn("%s: v6 Unimplmeneted", __PRETTY_FUNCTION__);
+ return 1;
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ return 0;
}
-int
-pim_rpf_addr_is_inaddr_any (struct pim_rpf *rpf)
+int pim_rpf_addr_is_inaddr_any(struct pim_rpf *rpf)
{
- switch (rpf->rpf_addr.family)
- {
- case AF_INET:
- return rpf->rpf_addr.u.prefix4.s_addr == INADDR_ANY;
- break;
- case AF_INET6:
- zlog_warn ("%s: v6 Unimplmented", __PRETTY_FUNCTION__);
- return 1;
- break;
- default:
- return 0;
- break;
- }
-
- return 0;
+ switch (rpf->rpf_addr.family) {
+ case AF_INET:
+ return rpf->rpf_addr.u.prefix4.s_addr == INADDR_ANY;
+ break;
+ case AF_INET6:
+ zlog_warn("%s: v6 Unimplmented", __PRETTY_FUNCTION__);
+ return 1;
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ return 0;
}
-int
-pim_rpf_is_same (struct pim_rpf *rpf1, struct pim_rpf *rpf2)
+int pim_rpf_is_same(struct pim_rpf *rpf1, struct pim_rpf *rpf2)
{
- if (rpf1->source_nexthop.interface == rpf2->source_nexthop.interface)
- return 1;
+ if (rpf1->source_nexthop.interface == rpf2->source_nexthop.interface)
+ return 1;
- return 0;
+ return 0;
}
diff --git a/pimd/pim_rpf.h b/pimd/pim_rpf.h
index bb7ee365b..083314356 100644
--- a/pimd/pim_rpf.h
+++ b/pimd/pim_rpf.h
@@ -38,36 +38,34 @@
units applicable to the unicast routing protocol used.
*/
struct pim_nexthop {
- struct in_addr last_lookup;
- long long last_lookup_time;
- struct interface *interface; /* RPF_interface(S) */
- struct prefix mrib_nexthop_addr; /* MRIB.next_hop(S) */
- uint32_t mrib_metric_preference; /* MRIB.pref(S) */
- uint32_t mrib_route_metric; /* MRIB.metric(S) */
- struct pim_neighbor *nbr;
+ struct in_addr last_lookup;
+ long long last_lookup_time;
+ struct interface *interface; /* RPF_interface(S) */
+ struct prefix mrib_nexthop_addr; /* MRIB.next_hop(S) */
+ uint32_t mrib_metric_preference; /* MRIB.pref(S) */
+ uint32_t mrib_route_metric; /* MRIB.metric(S) */
+ struct pim_neighbor *nbr;
};
struct pim_rpf {
- struct pim_nexthop source_nexthop;
- struct prefix rpf_addr; /* RPF'(S,G) */
+ struct pim_nexthop source_nexthop;
+ struct prefix rpf_addr; /* RPF'(S,G) */
};
-enum pim_rpf_result {
- PIM_RPF_OK = 0,
- PIM_RPF_CHANGED,
- PIM_RPF_FAILURE
-};
+enum pim_rpf_result { PIM_RPF_OK = 0, PIM_RPF_CHANGED, PIM_RPF_FAILURE };
struct pim_upstream;
extern long long nexthop_lookups_avoided;
-int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr, int neighbor_needed);
-enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct pim_rpf *old, uint8_t is_new);
+int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr,
+ int neighbor_needed);
+enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct pim_rpf *old,
+ uint8_t is_new);
-int pim_rpf_addr_is_inaddr_none (struct pim_rpf *rpf);
-int pim_rpf_addr_is_inaddr_any (struct pim_rpf *rpf);
+int pim_rpf_addr_is_inaddr_none(struct pim_rpf *rpf);
+int pim_rpf_addr_is_inaddr_any(struct pim_rpf *rpf);
-int pim_rpf_is_same (struct pim_rpf *rpf1, struct pim_rpf *rpf2);
-void pim_rpf_set_refresh_time (void);
+int pim_rpf_is_same(struct pim_rpf *rpf1, struct pim_rpf *rpf2);
+void pim_rpf_set_refresh_time(void);
#endif /* PIM_RPF_H */
diff --git a/pimd/pim_signals.c b/pimd/pim_signals.c
index ef492d0d8..0e9b09bf8 100644
--- a/pimd/pim_signals.c
+++ b/pimd/pim_signals.c
@@ -35,44 +35,43 @@
static void pim_sighup()
{
- zlog_info ("SIGHUP received, ignoring");
+ zlog_info("SIGHUP received, ignoring");
}
static void pim_sigint()
{
- zlog_notice("Terminating on signal SIGINT");
- pim_terminate();
- exit(1);
+ zlog_notice("Terminating on signal SIGINT");
+ pim_terminate();
+ exit(1);
}
static void pim_sigterm()
{
- zlog_notice("Terminating on signal SIGTERM");
- pim_terminate();
- exit(1);
+ zlog_notice("Terminating on signal SIGTERM");
+ pim_terminate();
+ exit(1);
}
static void pim_sigusr1()
{
- zlog_rotate();
+ zlog_rotate();
}
-struct quagga_signal_t pimd_signals[] =
-{
- {
- .signal = SIGHUP,
- .handler = &pim_sighup,
- },
- {
- .signal = SIGUSR1,
- .handler = &pim_sigusr1,
- },
- {
- .signal = SIGINT,
- .handler = &pim_sigint,
- },
- {
- .signal = SIGTERM,
- .handler = &pim_sigterm,
- },
+struct quagga_signal_t pimd_signals[] = {
+ {
+ .signal = SIGHUP,
+ .handler = &pim_sighup,
+ },
+ {
+ .signal = SIGUSR1,
+ .handler = &pim_sigusr1,
+ },
+ {
+ .signal = SIGINT,
+ .handler = &pim_sigint,
+ },
+ {
+ .signal = SIGTERM,
+ .handler = &pim_sigterm,
+ },
};
diff --git a/pimd/pim_sock.c b/pimd/pim_sock.c
index ba70cf2e1..a4d3d7e4b 100644
--- a/pimd/pim_sock.c
+++ b/pimd/pim_sock.c
@@ -42,292 +42,305 @@
/* GLOBAL VARS */
-int
-pim_socket_raw (int protocol)
+int pim_socket_raw(int protocol)
{
- int fd;
+ int fd;
- if ( pimd_privs.change (ZPRIVS_RAISE) )
- zlog_err ("pim_sockek_raw: could not raise privs, %s",
- safe_strerror (errno) );
+ if (pimd_privs.change(ZPRIVS_RAISE))
+ zlog_err("pim_sockek_raw: could not raise privs, %s",
+ safe_strerror(errno));
- fd = socket(AF_INET, SOCK_RAW, protocol);
+ fd = socket(AF_INET, SOCK_RAW, protocol);
- if ( pimd_privs.change (ZPRIVS_LOWER) )
- zlog_err ("pim_socket_raw: could not lower privs, %s",
- safe_strerror (errno) );
+ if (pimd_privs.change(ZPRIVS_LOWER))
+ zlog_err("pim_socket_raw: could not lower privs, %s",
+ safe_strerror(errno));
- if (fd < 0) {
- zlog_warn("Could not create raw socket: errno=%d: %s",
- errno, safe_strerror(errno));
- return PIM_SOCK_ERR_SOCKET;
- }
-
- return fd;
+ if (fd < 0) {
+ zlog_warn("Could not create raw socket: errno=%d: %s", errno,
+ safe_strerror(errno));
+ return PIM_SOCK_ERR_SOCKET;
+ }
+
+ return fd;
}
-int
-pim_socket_ip_hdr (int fd)
+int pim_socket_ip_hdr(int fd)
{
- const int on = 1;
- int ret;
+ const int on = 1;
+ int ret;
- if (pimd_privs.change (ZPRIVS_RAISE))
- zlog_err ("%s: could not raise privs, %s",
- __PRETTY_FUNCTION__, safe_strerror (errno));
+ if (pimd_privs.change(ZPRIVS_RAISE))
+ zlog_err("%s: could not raise privs, %s", __PRETTY_FUNCTION__,
+ safe_strerror(errno));
- ret = setsockopt (fd, IPPROTO_IP, IP_HDRINCL, &on, sizeof (on));
+ ret = setsockopt(fd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on));
- if (pimd_privs.change (ZPRIVS_LOWER))
- zlog_err ("%s: could not lower privs, %s",
- __PRETTY_FUNCTION__, safe_strerror (errno));
+ if (pimd_privs.change(ZPRIVS_LOWER))
+ zlog_err("%s: could not lower privs, %s", __PRETTY_FUNCTION__,
+ safe_strerror(errno));
- return ret;
+ return ret;
}
/*
* Given a socket and a interface,
* Bind that socket to that interface
*/
-int
-pim_socket_bind (int fd, struct interface *ifp)
+int pim_socket_bind(int fd, struct interface *ifp)
{
- int ret = 0;
+ int ret = 0;
#ifdef SO_BINDTODEVICE
- if (pimd_privs.change (ZPRIVS_RAISE))
- zlog_err ("%s: could not raise privs, %s",
- __PRETTY_FUNCTION__, safe_strerror (errno));
+ if (pimd_privs.change(ZPRIVS_RAISE))
+ zlog_err("%s: could not raise privs, %s", __PRETTY_FUNCTION__,
+ safe_strerror(errno));
- ret = setsockopt (fd, SOL_SOCKET,
- SO_BINDTODEVICE, ifp->name, strlen (ifp->name));
+ ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifp->name,
+ strlen(ifp->name));
- if (pimd_privs.change (ZPRIVS_LOWER))
- zlog_err ("%s: could not lower privs, %s",
- __PRETTY_FUNCTION__, safe_strerror (errno));
+ if (pimd_privs.change(ZPRIVS_LOWER))
+ zlog_err("%s: could not lower privs, %s", __PRETTY_FUNCTION__,
+ safe_strerror(errno));
#endif
- return ret;
+ return ret;
}
-int pim_socket_mcast(int protocol, struct in_addr ifaddr, struct interface *ifp, u_char loop)
+int pim_socket_mcast(int protocol, struct in_addr ifaddr, struct interface *ifp,
+ u_char loop)
{
- int rcvbuf = 1024 * 1024 * 8;
+ int rcvbuf = 1024 * 1024 * 8;
#ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX
- struct ip_mreqn mreq;
+ struct ip_mreqn mreq;
#else
- struct ip_mreq mreq;
+ struct ip_mreq mreq;
#endif
- int fd;
+ int fd;
- fd = pim_socket_raw(protocol);
- if (fd < 0) {
- zlog_warn("Could not create multicast socket: errno=%d: %s",
- errno, safe_strerror(errno));
- return PIM_SOCK_ERR_SOCKET;
- }
+ fd = pim_socket_raw(protocol);
+ if (fd < 0) {
+ zlog_warn("Could not create multicast socket: errno=%d: %s",
+ errno, safe_strerror(errno));
+ return PIM_SOCK_ERR_SOCKET;
+ }
#ifdef SO_BINDTODEVICE
- if (protocol == IPPROTO_PIM)
- {
- int ret;
-
- ret = pim_socket_bind (fd, ifp);
- if (ret)
- {
- close (fd);
- zlog_warn("Could not set fd: %d for interface: %s to device",
- fd, ifp->name);
- return PIM_SOCK_ERR_BIND;
+ if (protocol == IPPROTO_PIM) {
+ int ret;
+
+ ret = pim_socket_bind(fd, ifp);
+ if (ret) {
+ close(fd);
+ zlog_warn(
+ "Could not set fd: %d for interface: %s to device",
+ fd, ifp->name);
+ return PIM_SOCK_ERR_BIND;
+ }
}
- }
#else
- /* XXX: use IP_PKTINFO / IP_RECVIF to emulate behaviour? Or change to
- * only use 1 socket for all interfaces? */
+/* XXX: use IP_PKTINFO / IP_RECVIF to emulate behaviour? Or change to
+ * only use 1 socket for all interfaces? */
#endif
- /* Needed to obtain destination address from recvmsg() */
- {
+ /* Needed to obtain destination address from recvmsg() */
+ {
#if defined(HAVE_IP_PKTINFO)
- /* Linux and Solaris IP_PKTINFO */
- int opt = 1;
- if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt))) {
- zlog_warn("Could not set IP_PKTINFO on socket fd=%d: errno=%d: %s",
- fd, errno, safe_strerror(errno));
- }
+ /* Linux and Solaris IP_PKTINFO */
+ int opt = 1;
+ if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt))) {
+ zlog_warn(
+ "Could not set IP_PKTINFO on socket fd=%d: errno=%d: %s",
+ fd, errno, safe_strerror(errno));
+ }
#elif defined(HAVE_IP_RECVDSTADDR)
- /* BSD IP_RECVDSTADDR */
- int opt = 1;
- if (setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt))) {
- zlog_warn("Could not set IP_RECVDSTADDR on socket fd=%d: errno=%d: %s",
- fd, errno, safe_strerror(errno));
- }
+ /* BSD IP_RECVDSTADDR */
+ int opt = 1;
+ if (setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt,
+ sizeof(opt))) {
+ zlog_warn(
+ "Could not set IP_RECVDSTADDR on socket fd=%d: errno=%d: %s",
+ fd, errno, safe_strerror(errno));
+ }
#else
- zlog_err("%s %s: Missing IP_PKTINFO and IP_RECVDSTADDR: unable to get dst addr from recvmsg()",
- __FILE__, __PRETTY_FUNCTION__);
- close(fd);
- return PIM_SOCK_ERR_DSTADDR;
+ zlog_err(
+ "%s %s: Missing IP_PKTINFO and IP_RECVDSTADDR: unable to get dst addr from recvmsg()",
+ __FILE__, __PRETTY_FUNCTION__);
+ close(fd);
+ return PIM_SOCK_ERR_DSTADDR;
#endif
- }
-
-
- /* Set router alert (RFC 2113) for all IGMP messages (RFC 3376 4. Message Formats)*/
- if (protocol == IPPROTO_IGMP) {
- uint8_t ra[4];
- ra[0] = 148;
- ra[1] = 4;
- ra[2] = 0;
- ra[3] = 0;
- if (setsockopt(fd, IPPROTO_IP, IP_OPTIONS, ra, 4)) {
- zlog_warn("Could not set Router Alert Option on socket fd=%d: errno=%d: %s",
- fd, errno, safe_strerror(errno));
- close(fd);
- return PIM_SOCK_ERR_RA;
- }
- }
-
- {
- int reuse = 1;
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
- (void *) &reuse, sizeof(reuse))) {
- zlog_warn("Could not set Reuse Address Option on socket fd=%d: errno=%d: %s",
- fd, errno, safe_strerror(errno));
- close(fd);
- return PIM_SOCK_ERR_REUSE;
- }
- }
-
- {
- const int MTTL = 1;
- int ttl = MTTL;
- if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL,
- (void *) &ttl, sizeof(ttl))) {
- zlog_warn("Could not set multicast TTL=%d on socket fd=%d: errno=%d: %s",
- MTTL, fd, errno, safe_strerror(errno));
- close(fd);
- return PIM_SOCK_ERR_TTL;
- }
- }
-
- if (setsockopt_ipv4_multicast_loop (fd, loop)) {
- zlog_warn("Could not %s Multicast Loopback Option on socket fd=%d: errno=%d: %s",
- loop ? "enable" : "disable",
- fd, errno, safe_strerror(errno));
- close(fd);
- return PIM_SOCK_ERR_LOOP;
- }
-
- memset (&mreq, 0, sizeof (mreq));
+ }
+
+
+ /* Set router alert (RFC 2113) for all IGMP messages (RFC 3376 4.
+ * Message Formats)*/
+ if (protocol == IPPROTO_IGMP) {
+ uint8_t ra[4];
+ ra[0] = 148;
+ ra[1] = 4;
+ ra[2] = 0;
+ ra[3] = 0;
+ if (setsockopt(fd, IPPROTO_IP, IP_OPTIONS, ra, 4)) {
+ zlog_warn(
+ "Could not set Router Alert Option on socket fd=%d: errno=%d: %s",
+ fd, errno, safe_strerror(errno));
+ close(fd);
+ return PIM_SOCK_ERR_RA;
+ }
+ }
+
+ {
+ int reuse = 1;
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&reuse,
+ sizeof(reuse))) {
+ zlog_warn(
+ "Could not set Reuse Address Option on socket fd=%d: errno=%d: %s",
+ fd, errno, safe_strerror(errno));
+ close(fd);
+ return PIM_SOCK_ERR_REUSE;
+ }
+ }
+
+ {
+ const int MTTL = 1;
+ int ttl = MTTL;
+ if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&ttl,
+ sizeof(ttl))) {
+ zlog_warn(
+ "Could not set multicast TTL=%d on socket fd=%d: errno=%d: %s",
+ MTTL, fd, errno, safe_strerror(errno));
+ close(fd);
+ return PIM_SOCK_ERR_TTL;
+ }
+ }
+
+ if (setsockopt_ipv4_multicast_loop(fd, loop)) {
+ zlog_warn(
+ "Could not %s Multicast Loopback Option on socket fd=%d: errno=%d: %s",
+ loop ? "enable" : "disable", fd, errno,
+ safe_strerror(errno));
+ close(fd);
+ return PIM_SOCK_ERR_LOOP;
+ }
+
+ memset(&mreq, 0, sizeof(mreq));
#ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX
- mreq.imr_ifindex = ifp->ifindex;
+ mreq.imr_ifindex = ifp->ifindex;
#else
- /*
- * I am not sure what to do here yet for *BSD
- */
- //mreq.imr_interface = ifindex;
+/*
+ * I am not sure what to do here yet for *BSD
+ */
+// mreq.imr_interface = ifindex;
#endif
- if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
- (void *) &mreq, sizeof(mreq))) {
- zlog_warn("Could not set Outgoing Interface Option on socket fd=%d: errno=%d: %s",
- fd, errno, safe_strerror(errno));
- close(fd);
- return PIM_SOCK_ERR_IFACE;
- }
-
- if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)))
- zlog_warn("%s: Failure to set buffer size to %d",
- __PRETTY_FUNCTION__, rcvbuf);
-
- {
- long flags;
-
- flags = fcntl(fd, F_GETFL, 0);
- if (flags < 0) {
- zlog_warn("Could not get fcntl(F_GETFL,O_NONBLOCK) on socket fd=%d: errno=%d: %s",
- fd, errno, safe_strerror(errno));
- close(fd);
- return PIM_SOCK_ERR_NONBLOCK_GETFL;
- }
-
- if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) {
- zlog_warn("Could not set fcntl(F_SETFL,O_NONBLOCK) on socket fd=%d: errno=%d: %s",
- fd, errno, safe_strerror(errno));
- close(fd);
- return PIM_SOCK_ERR_NONBLOCK_SETFL;
- }
- }
-
- return fd;
+ if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (void *)&mreq,
+ sizeof(mreq))) {
+ zlog_warn(
+ "Could not set Outgoing Interface Option on socket fd=%d: errno=%d: %s",
+ fd, errno, safe_strerror(errno));
+ close(fd);
+ return PIM_SOCK_ERR_IFACE;
+ }
+
+ if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)))
+ zlog_warn("%s: Failure to set buffer size to %d",
+ __PRETTY_FUNCTION__, rcvbuf);
+
+ {
+ long flags;
+
+ flags = fcntl(fd, F_GETFL, 0);
+ if (flags < 0) {
+ zlog_warn(
+ "Could not get fcntl(F_GETFL,O_NONBLOCK) on socket fd=%d: errno=%d: %s",
+ fd, errno, safe_strerror(errno));
+ close(fd);
+ return PIM_SOCK_ERR_NONBLOCK_GETFL;
+ }
+
+ if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) {
+ zlog_warn(
+ "Could not set fcntl(F_SETFL,O_NONBLOCK) on socket fd=%d: errno=%d: %s",
+ fd, errno, safe_strerror(errno));
+ close(fd);
+ return PIM_SOCK_ERR_NONBLOCK_SETFL;
+ }
+ }
+
+ return fd;
}
-int pim_socket_join(int fd, struct in_addr group,
- struct in_addr ifaddr, ifindex_t ifindex)
+int pim_socket_join(int fd, struct in_addr group, struct in_addr ifaddr,
+ ifindex_t ifindex)
{
- int ret;
+ int ret;
#ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX
- struct ip_mreqn opt;
+ struct ip_mreqn opt;
#else
- struct ip_mreq opt;
+ struct ip_mreq opt;
#endif
- opt.imr_multiaddr = group;
+ opt.imr_multiaddr = group;
#ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX
- opt.imr_address = ifaddr;
- opt.imr_ifindex = ifindex;
+ opt.imr_address = ifaddr;
+ opt.imr_ifindex = ifindex;
#else
- opt.imr_interface = ifaddr;
+ opt.imr_interface = ifaddr;
#endif
- ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &opt, sizeof(opt));
- if (ret) {
- char group_str[INET_ADDRSTRLEN];
- char ifaddr_str[INET_ADDRSTRLEN];
- if (!inet_ntop(AF_INET, &group, group_str , sizeof(group_str)))
- sprintf(group_str, "<group?>");
- if (!inet_ntop(AF_INET, &ifaddr, ifaddr_str , sizeof(ifaddr_str)))
- sprintf(ifaddr_str, "<ifaddr?>");
-
- zlog_err("Failure socket joining fd=%d group %s on interface address %s: errno=%d: %s",
- fd, group_str, ifaddr_str, errno, safe_strerror(errno));
- return ret;
- }
-
- if (PIM_DEBUG_TRACE) {
- char group_str[INET_ADDRSTRLEN];
- char ifaddr_str[INET_ADDRSTRLEN];
- if (!inet_ntop(AF_INET, &group, group_str , sizeof(group_str)))
- sprintf(group_str, "<group?>");
- if (!inet_ntop(AF_INET, &ifaddr, ifaddr_str , sizeof(ifaddr_str)))
- sprintf(ifaddr_str, "<ifaddr?>");
-
- zlog_debug("Socket fd=%d joined group %s on interface address %s",
- fd, group_str, ifaddr_str);
- }
-
- return ret;
+ ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &opt, sizeof(opt));
+ if (ret) {
+ char group_str[INET_ADDRSTRLEN];
+ char ifaddr_str[INET_ADDRSTRLEN];
+ if (!inet_ntop(AF_INET, &group, group_str, sizeof(group_str)))
+ sprintf(group_str, "<group?>");
+ if (!inet_ntop(AF_INET, &ifaddr, ifaddr_str,
+ sizeof(ifaddr_str)))
+ sprintf(ifaddr_str, "<ifaddr?>");
+
+ zlog_err(
+ "Failure socket joining fd=%d group %s on interface address %s: errno=%d: %s",
+ fd, group_str, ifaddr_str, errno, safe_strerror(errno));
+ return ret;
+ }
+
+ if (PIM_DEBUG_TRACE) {
+ char group_str[INET_ADDRSTRLEN];
+ char ifaddr_str[INET_ADDRSTRLEN];
+ if (!inet_ntop(AF_INET, &group, group_str, sizeof(group_str)))
+ sprintf(group_str, "<group?>");
+ if (!inet_ntop(AF_INET, &ifaddr, ifaddr_str,
+ sizeof(ifaddr_str)))
+ sprintf(ifaddr_str, "<ifaddr?>");
+
+ zlog_debug(
+ "Socket fd=%d joined group %s on interface address %s",
+ fd, group_str, ifaddr_str);
+ }
+
+ return ret;
}
-int pim_socket_join_source(int fd, ifindex_t ifindex,
- struct in_addr group_addr,
- struct in_addr source_addr,
- const char *ifname)
+int pim_socket_join_source(int fd, ifindex_t ifindex, struct in_addr group_addr,
+ struct in_addr source_addr, const char *ifname)
{
- if (pim_igmp_join_source(fd, ifindex, group_addr, source_addr)) {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
- pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- zlog_warn("%s: setsockopt(fd=%d) failure for IGMP group %s source %s ifindex %d on interface %s: errno=%d: %s",
- __PRETTY_FUNCTION__,
- fd, group_str, source_str, ifindex, ifname,
- errno, safe_strerror(errno));
- return -1;
- }
-
- return 0;
+ if (pim_igmp_join_source(fd, ifindex, group_addr, source_addr)) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<grp?>", group_addr, group_str,
+ sizeof(group_str));
+ pim_inet4_dump("<src?>", source_addr, source_str,
+ sizeof(source_str));
+ zlog_warn(
+ "%s: setsockopt(fd=%d) failure for IGMP group %s source %s ifindex %d on interface %s: errno=%d: %s",
+ __PRETTY_FUNCTION__, fd, group_str, source_str, ifindex,
+ ifname, errno, safe_strerror(errno));
+ return -1;
+ }
+
+ return 0;
}
int pim_socket_recvfromto(int fd, uint8_t *buf, size_t len,
@@ -335,117 +348,121 @@ int pim_socket_recvfromto(int fd, uint8_t *buf, size_t len,
struct sockaddr_in *to, socklen_t *tolen,
ifindex_t *ifindex)
{
- struct msghdr msgh;
- struct cmsghdr *cmsg;
- struct iovec iov;
- char cbuf[1000];
- int err;
-
- /*
- * IP_PKTINFO / IP_RECVDSTADDR don't yield sin_port.
- * Use getsockname() to get sin_port.
- */
- if (to) {
- struct sockaddr_in si;
- socklen_t si_len = sizeof(si);
-
- memset (&si, 0, sizeof (si));
- to->sin_family = AF_INET;
-
- pim_socket_getsockname(fd, (struct sockaddr *) &si, &si_len);
-
- to->sin_port = si.sin_port;
- to->sin_addr = si.sin_addr;
-
- if (tolen)
- *tolen = sizeof(si);
- }
-
- memset(&msgh, 0, sizeof(struct msghdr));
- iov.iov_base = buf;
- iov.iov_len = len;
- msgh.msg_control = cbuf;
- msgh.msg_controllen = sizeof(cbuf);
- msgh.msg_name = from;
- msgh.msg_namelen = fromlen ? *fromlen : 0;
- msgh.msg_iov = &iov;
- msgh.msg_iovlen = 1;
- msgh.msg_flags = 0;
-
- err = recvmsg(fd, &msgh, 0);
- if (err < 0)
- return err;
-
- if (fromlen)
- *fromlen = msgh.msg_namelen;
-
- for (cmsg = CMSG_FIRSTHDR(&msgh);
- cmsg != NULL;
- cmsg = CMSG_NXTHDR(&msgh,cmsg)) {
+ struct msghdr msgh;
+ struct cmsghdr *cmsg;
+ struct iovec iov;
+ char cbuf[1000];
+ int err;
+
+ /*
+ * IP_PKTINFO / IP_RECVDSTADDR don't yield sin_port.
+ * Use getsockname() to get sin_port.
+ */
+ if (to) {
+ struct sockaddr_in si;
+ socklen_t si_len = sizeof(si);
+
+ memset(&si, 0, sizeof(si));
+ to->sin_family = AF_INET;
+
+ pim_socket_getsockname(fd, (struct sockaddr *)&si, &si_len);
+
+ to->sin_port = si.sin_port;
+ to->sin_addr = si.sin_addr;
+
+ if (tolen)
+ *tolen = sizeof(si);
+ }
+
+ memset(&msgh, 0, sizeof(struct msghdr));
+ iov.iov_base = buf;
+ iov.iov_len = len;
+ msgh.msg_control = cbuf;
+ msgh.msg_controllen = sizeof(cbuf);
+ msgh.msg_name = from;
+ msgh.msg_namelen = fromlen ? *fromlen : 0;
+ msgh.msg_iov = &iov;
+ msgh.msg_iovlen = 1;
+ msgh.msg_flags = 0;
+
+ err = recvmsg(fd, &msgh, 0);
+ if (err < 0)
+ return err;
+
+ if (fromlen)
+ *fromlen = msgh.msg_namelen;
+
+ for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
#ifdef HAVE_IP_PKTINFO
- if ((cmsg->cmsg_level == IPPROTO_IP) && (cmsg->cmsg_type == IP_PKTINFO)) {
- struct in_pktinfo *i = (struct in_pktinfo *) CMSG_DATA(cmsg);
- if (to)
- ((struct sockaddr_in *) to)->sin_addr = i->ipi_addr;
- if (tolen)
- *tolen = sizeof(struct sockaddr_in);
- if (ifindex)
- *ifindex = i->ipi_ifindex;
-
- break;
- }
+ if ((cmsg->cmsg_level == IPPROTO_IP)
+ && (cmsg->cmsg_type == IP_PKTINFO)) {
+ struct in_pktinfo *i =
+ (struct in_pktinfo *)CMSG_DATA(cmsg);
+ if (to)
+ ((struct sockaddr_in *)to)->sin_addr =
+ i->ipi_addr;
+ if (tolen)
+ *tolen = sizeof(struct sockaddr_in);
+ if (ifindex)
+ *ifindex = i->ipi_ifindex;
+
+ break;
+ }
#endif
#ifdef HAVE_IP_RECVDSTADDR
- if ((cmsg->cmsg_level == IPPROTO_IP) && (cmsg->cmsg_type == IP_RECVDSTADDR)) {
- struct in_addr *i = (struct in_addr *) CMSG_DATA(cmsg);
- if (to)
- ((struct sockaddr_in *) to)->sin_addr = *i;
- if (tolen)
- *tolen = sizeof(struct sockaddr_in);
-
- break;
- }
+ if ((cmsg->cmsg_level == IPPROTO_IP)
+ && (cmsg->cmsg_type == IP_RECVDSTADDR)) {
+ struct in_addr *i = (struct in_addr *)CMSG_DATA(cmsg);
+ if (to)
+ ((struct sockaddr_in *)to)->sin_addr = *i;
+ if (tolen)
+ *tolen = sizeof(struct sockaddr_in);
+
+ break;
+ }
#endif
#if defined(HAVE_IP_RECVIF) && defined(CMSG_IFINDEX)
- if (cmsg->cmsg_type == IP_RECVIF)
- if (ifindex)
- *ifindex = CMSG_IFINDEX(cmsg);
+ if (cmsg->cmsg_type == IP_RECVIF)
+ if (ifindex)
+ *ifindex = CMSG_IFINDEX(cmsg);
#endif
- } /* for (cmsg) */
+ } /* for (cmsg) */
- return err; /* len */
+ return err; /* len */
}
int pim_socket_mcastloop_get(int fd)
{
- int loop;
- socklen_t loop_len = sizeof(loop);
-
- if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
- &loop, &loop_len)) {
- int e = errno;
- zlog_warn("Could not get Multicast Loopback Option on socket fd=%d: errno=%d: %s",
- fd, errno, safe_strerror(errno));
- errno = e;
- return PIM_SOCK_ERR_LOOP;
- }
-
- return loop;
+ int loop;
+ socklen_t loop_len = sizeof(loop);
+
+ if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, &loop_len)) {
+ int e = errno;
+ zlog_warn(
+ "Could not get Multicast Loopback Option on socket fd=%d: errno=%d: %s",
+ fd, errno, safe_strerror(errno));
+ errno = e;
+ return PIM_SOCK_ERR_LOOP;
+ }
+
+ return loop;
}
int pim_socket_getsockname(int fd, struct sockaddr *name, socklen_t *namelen)
{
- if (getsockname(fd, name, namelen)) {
- int e = errno;
- zlog_warn("Could not get Socket Name for socket fd=%d: errno=%d: %s",
- fd, errno, safe_strerror(errno));
- errno = e;
- return PIM_SOCK_ERR_NAME;
- }
-
- return PIM_SOCK_ERR_NONE;
+ if (getsockname(fd, name, namelen)) {
+ int e = errno;
+ zlog_warn(
+ "Could not get Socket Name for socket fd=%d: errno=%d: %s",
+ fd, errno, safe_strerror(errno));
+ errno = e;
+ return PIM_SOCK_ERR_NAME;
+ }
+
+ return PIM_SOCK_ERR_NONE;
}
diff --git a/pimd/pim_sock.h b/pimd/pim_sock.h
index 9fb64677c..aa46cd620 100644
--- a/pimd/pim_sock.h
+++ b/pimd/pim_sock.h
@@ -35,16 +35,15 @@
#define PIM_SOCK_ERR_NAME (-10) /* Socket name (getsockname) */
#define PIM_SOCK_ERR_BIND (-11) /* Can't bind to interface */
-int pim_socket_bind (int fd, struct interface *ifp);
-int pim_socket_ip_hdr (int fd);
+int pim_socket_bind(int fd, struct interface *ifp);
+int pim_socket_ip_hdr(int fd);
int pim_socket_raw(int protocol);
-int pim_socket_mcast(int protocol, struct in_addr ifaddr, struct interface *ifp, u_char loop);
-int pim_socket_join(int fd, struct in_addr group,
- struct in_addr ifaddr, ifindex_t ifindex);
-int pim_socket_join_source(int fd, ifindex_t ifindex,
- struct in_addr group_addr,
- struct in_addr source_addr,
- const char *ifname);
+int pim_socket_mcast(int protocol, struct in_addr ifaddr, struct interface *ifp,
+ u_char loop);
+int pim_socket_join(int fd, struct in_addr group, struct in_addr ifaddr,
+ ifindex_t ifindex);
+int pim_socket_join_source(int fd, ifindex_t ifindex, struct in_addr group_addr,
+ struct in_addr source_addr, const char *ifname);
int pim_socket_recvfromto(int fd, uint8_t *buf, size_t len,
struct sockaddr_in *from, socklen_t *fromlen,
struct sockaddr_in *to, socklen_t *tolen,
diff --git a/pimd/pim_ssm.c b/pimd/pim_ssm.c
index d4f88ec2c..3046e9429 100644
--- a/pimd/pim_ssm.c
+++ b/pimd/pim_ssm.c
@@ -29,129 +29,119 @@
#include "pim_ssm.h"
#include "pim_zebra.h"
-static void
-pim_ssm_range_reevaluate (void)
+static void pim_ssm_range_reevaluate(void)
{
- /* 1. Setup register state for (S,G) entries if G has changed from SSM to
- * ASM.
- * 2. check existing (*,G) IGMP registrations to see if they are
- * still ASM. if they are now SSM delete them.
- * 3. Allow channel setup for IGMP (*,G) members if G is now ASM
- * 4. I could tear down all (*,G), (S,G,rpt) states. But that is an
- * unnecessary sladge hammer and may not be particularly useful as it is
- * likely the SPT switchover has already happened for flows along such RPTs.
- * As for the RPT states it seems that the best thing to do is let them age
- * out gracefully. As long as the FHR and LHR do the right thing RPTs will
- * disappear in time for SSM groups.
- */
- pim_upstream_register_reevaluate ();
- igmp_source_forward_reevaluate_all ();
+ /* 1. Setup register state for (S,G) entries if G has changed from SSM
+ * to
+ * ASM.
+ * 2. check existing (*,G) IGMP registrations to see if they are
+ * still ASM. if they are now SSM delete them.
+ * 3. Allow channel setup for IGMP (*,G) members if G is now ASM
+ * 4. I could tear down all (*,G), (S,G,rpt) states. But that is an
+ * unnecessary sladge hammer and may not be particularly useful as it is
+ * likely the SPT switchover has already happened for flows along such
+ * RPTs.
+ * As for the RPT states it seems that the best thing to do is let them
+ * age
+ * out gracefully. As long as the FHR and LHR do the right thing RPTs
+ * will
+ * disappear in time for SSM groups.
+ */
+ pim_upstream_register_reevaluate();
+ igmp_source_forward_reevaluate_all();
}
-void
-pim_ssm_prefix_list_update (struct prefix_list *plist)
+void pim_ssm_prefix_list_update(struct prefix_list *plist)
{
- struct pim_ssm *ssm = pimg->ssm_info;
+ struct pim_ssm *ssm = pimg->ssm_info;
- if (!ssm->plist_name || strcmp (ssm->plist_name, prefix_list_name (plist)))
- {
- /* not ours */
- return;
- }
+ if (!ssm->plist_name
+ || strcmp(ssm->plist_name, prefix_list_name(plist))) {
+ /* not ours */
+ return;
+ }
- pim_ssm_range_reevaluate ();
+ pim_ssm_range_reevaluate();
}
-static int
-pim_is_grp_standard_ssm (struct prefix *group)
+static int pim_is_grp_standard_ssm(struct prefix *group)
{
- static int first = 1;
- static struct prefix group_ssm;
+ static int first = 1;
+ static struct prefix group_ssm;
- if (first)
- {
- str2prefix (PIM_SSM_STANDARD_RANGE, &group_ssm);
- first = 0;
- }
+ if (first) {
+ str2prefix(PIM_SSM_STANDARD_RANGE, &group_ssm);
+ first = 0;
+ }
- return prefix_match (&group_ssm, group);
+ return prefix_match(&group_ssm, group);
}
-int
-pim_is_grp_ssm (struct in_addr group_addr)
+int pim_is_grp_ssm(struct in_addr group_addr)
{
- struct pim_ssm *ssm;
- struct prefix group;
- struct prefix_list *plist;
-
- memset (&group, 0, sizeof (group));
- group.family = AF_INET;
- group.u.prefix4 = group_addr;
- group.prefixlen = 32;
-
- ssm = pimg->ssm_info;
- if (!ssm->plist_name)
- {
- return pim_is_grp_standard_ssm (&group);
- }
-
- plist = prefix_list_lookup (AFI_IP, ssm->plist_name);
- if (!plist)
- return 0;
-
- return (prefix_list_apply (plist, &group) == PREFIX_PERMIT);
+ struct pim_ssm *ssm;
+ struct prefix group;
+ struct prefix_list *plist;
+
+ memset(&group, 0, sizeof(group));
+ group.family = AF_INET;
+ group.u.prefix4 = group_addr;
+ group.prefixlen = 32;
+
+ ssm = pimg->ssm_info;
+ if (!ssm->plist_name) {
+ return pim_is_grp_standard_ssm(&group);
+ }
+
+ plist = prefix_list_lookup(AFI_IP, ssm->plist_name);
+ if (!plist)
+ return 0;
+
+ return (prefix_list_apply(plist, &group) == PREFIX_PERMIT);
}
-int
-pim_ssm_range_set (vrf_id_t vrf_id, const char *plist_name)
+int pim_ssm_range_set(vrf_id_t vrf_id, const char *plist_name)
{
- struct pim_ssm *ssm;
- int change = 0;
-
- if (vrf_id != VRF_DEFAULT)
- return PIM_SSM_ERR_NO_VRF;
-
- ssm = pimg->ssm_info;
- if (plist_name)
- {
- if (ssm->plist_name)
- {
- if (!strcmp (ssm->plist_name, plist_name))
- return PIM_SSM_ERR_DUP;
- XFREE (MTYPE_PIM_FILTER_NAME, ssm->plist_name);
- }
- ssm->plist_name = XSTRDUP (MTYPE_PIM_FILTER_NAME, plist_name);
- change = 1;
- }
- else
- {
- if (ssm->plist_name)
- {
- change = 1;
- XFREE (MTYPE_PIM_FILTER_NAME, ssm->plist_name);
- }
- }
-
- if (change)
- pim_ssm_range_reevaluate ();
-
- return PIM_SSM_ERR_NONE;
+ struct pim_ssm *ssm;
+ int change = 0;
+
+ if (vrf_id != VRF_DEFAULT)
+ return PIM_SSM_ERR_NO_VRF;
+
+ ssm = pimg->ssm_info;
+ if (plist_name) {
+ if (ssm->plist_name) {
+ if (!strcmp(ssm->plist_name, plist_name))
+ return PIM_SSM_ERR_DUP;
+ XFREE(MTYPE_PIM_FILTER_NAME, ssm->plist_name);
+ }
+ ssm->plist_name = XSTRDUP(MTYPE_PIM_FILTER_NAME, plist_name);
+ change = 1;
+ } else {
+ if (ssm->plist_name) {
+ change = 1;
+ XFREE(MTYPE_PIM_FILTER_NAME, ssm->plist_name);
+ }
+ }
+
+ if (change)
+ pim_ssm_range_reevaluate();
+
+ return PIM_SSM_ERR_NONE;
}
-void *
-pim_ssm_init (vrf_id_t vrf_id)
+void *pim_ssm_init(vrf_id_t vrf_id)
{
- struct pim_ssm *ssm;
+ struct pim_ssm *ssm;
- ssm = XCALLOC (MTYPE_PIM_SSM_INFO, sizeof (*ssm));
- ssm->vrf_id = vrf_id;
+ ssm = XCALLOC(MTYPE_PIM_SSM_INFO, sizeof(*ssm));
+ ssm->vrf_id = vrf_id;
- return ssm;
+ return ssm;
}
-void
-pim_ssm_terminate (struct pim_ssm *ssm)
+void pim_ssm_terminate(struct pim_ssm *ssm)
{
- if (ssm && ssm->plist_name)
- XFREE (MTYPE_PIM_FILTER_NAME, ssm->plist_name);
+ if (ssm && ssm->plist_name)
+ XFREE(MTYPE_PIM_FILTER_NAME, ssm->plist_name);
}
diff --git a/pimd/pim_ssm.h b/pimd/pim_ssm.h
index fe337be8f..9e89d0c80 100644
--- a/pimd/pim_ssm.h
+++ b/pimd/pim_ssm.h
@@ -22,22 +22,20 @@
#define PIM_SSM_STANDARD_RANGE "232.0.0.0/8"
/* SSM error codes */
-enum pim_ssm_err
-{
- PIM_SSM_ERR_NONE = 0,
- PIM_SSM_ERR_NO_VRF = -1,
- PIM_SSM_ERR_DUP = -2,
+enum pim_ssm_err {
+ PIM_SSM_ERR_NONE = 0,
+ PIM_SSM_ERR_NO_VRF = -1,
+ PIM_SSM_ERR_DUP = -2,
};
-struct pim_ssm
-{
- vrf_id_t vrf_id;
- char *plist_name; /* prefix list of group ranges */
+struct pim_ssm {
+ vrf_id_t vrf_id;
+ char *plist_name; /* prefix list of group ranges */
};
-void pim_ssm_prefix_list_update (struct prefix_list *plist);
-int pim_is_grp_ssm (struct in_addr group_addr);
-int pim_ssm_range_set (vrf_id_t vrf_id, const char *plist_name);
-void *pim_ssm_init (vrf_id_t vrf_id);
-void pim_ssm_terminate (struct pim_ssm *ssm);
+void pim_ssm_prefix_list_update(struct prefix_list *plist);
+int pim_is_grp_ssm(struct in_addr group_addr);
+int pim_ssm_range_set(vrf_id_t vrf_id, const char *plist_name);
+void *pim_ssm_init(vrf_id_t vrf_id);
+void pim_ssm_terminate(struct pim_ssm *ssm);
#endif
diff --git a/pimd/pim_ssmpingd.c b/pimd/pim_ssmpingd.c
index dd92ff1b2..406183db8 100644
--- a/pimd/pim_ssmpingd.c
+++ b/pimd/pim_ssmpingd.c
@@ -30,402 +30,423 @@
#include "pim_time.h"
#include "pim_sock.h"
-static const char * const PIM_SSMPINGD_REPLY_GROUP = "232.43.211.234";
+static const char *const PIM_SSMPINGD_REPLY_GROUP = "232.43.211.234";
-enum {
- PIM_SSMPINGD_REQUEST = 'Q',
- PIM_SSMPINGD_REPLY = 'A'
-};
+enum { PIM_SSMPINGD_REQUEST = 'Q', PIM_SSMPINGD_REPLY = 'A' };
static void ssmpingd_read_on(struct ssmpingd_sock *ss);
void pim_ssmpingd_init()
{
- int result;
+ int result;
- zassert(!qpim_ssmpingd_list);
+ zassert(!qpim_ssmpingd_list);
- result = inet_pton(AF_INET, PIM_SSMPINGD_REPLY_GROUP, &qpim_ssmpingd_group_addr);
-
- zassert(result > 0);
+ result = inet_pton(AF_INET, PIM_SSMPINGD_REPLY_GROUP,
+ &qpim_ssmpingd_group_addr);
+
+ zassert(result > 0);
}
void pim_ssmpingd_destroy()
{
- if (qpim_ssmpingd_list) {
- list_free(qpim_ssmpingd_list);
- qpim_ssmpingd_list = 0;
- }
+ if (qpim_ssmpingd_list) {
+ list_free(qpim_ssmpingd_list);
+ qpim_ssmpingd_list = 0;
+ }
}
static struct ssmpingd_sock *ssmpingd_find(struct in_addr source_addr)
{
- struct listnode *node;
- struct ssmpingd_sock *ss;
+ struct listnode *node;
+ struct ssmpingd_sock *ss;
- if (!qpim_ssmpingd_list)
- return 0;
+ if (!qpim_ssmpingd_list)
+ return 0;
- for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list, node, ss))
- if (source_addr.s_addr == ss->source_addr.s_addr)
- return ss;
+ for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list, node, ss))
+ if (source_addr.s_addr == ss->source_addr.s_addr)
+ return ss;
- return 0;
+ return 0;
}
static void ssmpingd_free(struct ssmpingd_sock *ss)
{
- XFREE(MTYPE_PIM_SSMPINGD, ss);
+ XFREE(MTYPE_PIM_SSMPINGD, ss);
}
static int ssmpingd_socket(struct in_addr addr, int port, int mttl)
{
- struct sockaddr_in sockaddr;
- int fd;
-
- fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (fd < 0) {
- zlog_err("%s: could not create socket: errno=%d: %s",
- __PRETTY_FUNCTION__, errno, safe_strerror(errno));
- return -1;
- }
-
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_addr = addr;
- sockaddr.sin_port = htons(port);
-
- if (bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_warn("%s: bind(fd=%d,addr=%s,port=%d,len=%zu) failure: errno=%d: %s",
- __PRETTY_FUNCTION__,
- fd, addr_str, port, sizeof(sockaddr),
- errno, safe_strerror(errno));
- close(fd);
- return -1;
- }
-
- /* Needed to obtain destination address from recvmsg() */
- {
+ struct sockaddr_in sockaddr;
+ int fd;
+
+ fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (fd < 0) {
+ zlog_err("%s: could not create socket: errno=%d: %s",
+ __PRETTY_FUNCTION__, errno, safe_strerror(errno));
+ return -1;
+ }
+
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_addr = addr;
+ sockaddr.sin_port = htons(port);
+
+ if (bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+ zlog_warn(
+ "%s: bind(fd=%d,addr=%s,port=%d,len=%zu) failure: errno=%d: %s",
+ __PRETTY_FUNCTION__, fd, addr_str, port,
+ sizeof(sockaddr), errno, safe_strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+ /* Needed to obtain destination address from recvmsg() */
+ {
#if defined(HAVE_IP_PKTINFO)
- /* Linux and Solaris IP_PKTINFO */
- int opt = 1;
- if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt))) {
- zlog_warn("%s: could not set IP_PKTINFO on socket fd=%d: errno=%d: %s",
- __PRETTY_FUNCTION__, fd, errno, safe_strerror(errno));
- }
+ /* Linux and Solaris IP_PKTINFO */
+ int opt = 1;
+ if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt))) {
+ zlog_warn(
+ "%s: could not set IP_PKTINFO on socket fd=%d: errno=%d: %s",
+ __PRETTY_FUNCTION__, fd, errno,
+ safe_strerror(errno));
+ }
#elif defined(HAVE_IP_RECVDSTADDR)
- /* BSD IP_RECVDSTADDR */
- int opt = 1;
- if (setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt))) {
- zlog_warn("%s: could not set IP_RECVDSTADDR on socket fd=%d: errno=%d: %s",
- __PRETTY_FUNCTION__, fd, errno, safe_strerror(errno));
- }
+ /* BSD IP_RECVDSTADDR */
+ int opt = 1;
+ if (setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt,
+ sizeof(opt))) {
+ zlog_warn(
+ "%s: could not set IP_RECVDSTADDR on socket fd=%d: errno=%d: %s",
+ __PRETTY_FUNCTION__, fd, errno,
+ safe_strerror(errno));
+ }
#else
- zlog_err("%s %s: missing IP_PKTINFO and IP_RECVDSTADDR: unable to get dst addr from recvmsg()",
- __FILE__, __PRETTY_FUNCTION__);
- close(fd);
- return -1;
+ zlog_err(
+ "%s %s: missing IP_PKTINFO and IP_RECVDSTADDR: unable to get dst addr from recvmsg()",
+ __FILE__, __PRETTY_FUNCTION__);
+ close(fd);
+ return -1;
#endif
- }
-
- {
- int reuse = 1;
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
- (void *) &reuse, sizeof(reuse))) {
- zlog_warn("%s: could not set Reuse Address Option on socket fd=%d: errno=%d: %s",
- __PRETTY_FUNCTION__, fd, errno, safe_strerror(errno));
- close(fd);
- return -1;
- }
- }
-
- if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL,
- (void *) &mttl, sizeof(mttl))) {
- zlog_warn("%s: could not set multicast TTL=%d on socket fd=%d: errno=%d: %s",
- __PRETTY_FUNCTION__, mttl, fd, errno, safe_strerror(errno));
- close(fd);
- return -1;
- }
-
- if (setsockopt_ipv4_multicast_loop (fd, 0)) {
- zlog_warn("%s: could not disable Multicast Loopback Option on socket fd=%d: errno=%d: %s",
- __PRETTY_FUNCTION__,
- fd, errno, safe_strerror(errno));
- close(fd);
- return PIM_SOCK_ERR_LOOP;
- }
-
- if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
- (void *) &addr, sizeof(addr))) {
- zlog_warn("%s: could not set Outgoing Interface Option on socket fd=%d: errno=%d: %s",
- __PRETTY_FUNCTION__, fd, errno, safe_strerror(errno));
- close(fd);
- return -1;
- }
-
- {
- long flags;
-
- flags = fcntl(fd, F_GETFL, 0);
- if (flags < 0) {
- zlog_warn("%s: could not get fcntl(F_GETFL,O_NONBLOCK) on socket fd=%d: errno=%d: %s",
- __PRETTY_FUNCTION__, fd, errno, safe_strerror(errno));
- close(fd);
- return -1;
- }
-
- if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) {
- zlog_warn("%s: could not set fcntl(F_SETFL,O_NONBLOCK) on socket fd=%d: errno=%d: %s",
- __PRETTY_FUNCTION__, fd, errno, safe_strerror(errno));
- close(fd);
- return -1;
- }
- }
-
- return fd;
+ }
+
+ {
+ int reuse = 1;
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&reuse,
+ sizeof(reuse))) {
+ zlog_warn(
+ "%s: could not set Reuse Address Option on socket fd=%d: errno=%d: %s",
+ __PRETTY_FUNCTION__, fd, errno,
+ safe_strerror(errno));
+ close(fd);
+ return -1;
+ }
+ }
+
+ if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&mttl,
+ sizeof(mttl))) {
+ zlog_warn(
+ "%s: could not set multicast TTL=%d on socket fd=%d: errno=%d: %s",
+ __PRETTY_FUNCTION__, mttl, fd, errno,
+ safe_strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+ if (setsockopt_ipv4_multicast_loop(fd, 0)) {
+ zlog_warn(
+ "%s: could not disable Multicast Loopback Option on socket fd=%d: errno=%d: %s",
+ __PRETTY_FUNCTION__, fd, errno, safe_strerror(errno));
+ close(fd);
+ return PIM_SOCK_ERR_LOOP;
+ }
+
+ if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (void *)&addr,
+ sizeof(addr))) {
+ zlog_warn(
+ "%s: could not set Outgoing Interface Option on socket fd=%d: errno=%d: %s",
+ __PRETTY_FUNCTION__, fd, errno, safe_strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+ {
+ long flags;
+
+ flags = fcntl(fd, F_GETFL, 0);
+ if (flags < 0) {
+ zlog_warn(
+ "%s: could not get fcntl(F_GETFL,O_NONBLOCK) on socket fd=%d: errno=%d: %s",
+ __PRETTY_FUNCTION__, fd, errno,
+ safe_strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+ if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) {
+ zlog_warn(
+ "%s: could not set fcntl(F_SETFL,O_NONBLOCK) on socket fd=%d: errno=%d: %s",
+ __PRETTY_FUNCTION__, fd, errno,
+ safe_strerror(errno));
+ close(fd);
+ return -1;
+ }
+ }
+
+ return fd;
}
static void ssmpingd_delete(struct ssmpingd_sock *ss)
{
- zassert(ss);
- zassert(qpim_ssmpingd_list);
-
- THREAD_OFF(ss->t_sock_read);
-
- if (close(ss->sock_fd)) {
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str));
- zlog_warn("%s: failure closing ssmpingd sock_fd=%d for source %s: errno=%d: %s",
- __PRETTY_FUNCTION__,
- ss->sock_fd, source_str, errno, safe_strerror(errno));
- /* warning only */
- }
-
- listnode_delete(qpim_ssmpingd_list, ss);
- ssmpingd_free(ss);
+ zassert(ss);
+ zassert(qpim_ssmpingd_list);
+
+ THREAD_OFF(ss->t_sock_read);
+
+ if (close(ss->sock_fd)) {
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", ss->source_addr, source_str,
+ sizeof(source_str));
+ zlog_warn(
+ "%s: failure closing ssmpingd sock_fd=%d for source %s: errno=%d: %s",
+ __PRETTY_FUNCTION__, ss->sock_fd, source_str, errno,
+ safe_strerror(errno));
+ /* warning only */
+ }
+
+ listnode_delete(qpim_ssmpingd_list, ss);
+ ssmpingd_free(ss);
}
-static void ssmpingd_sendto(struct ssmpingd_sock *ss,
- const uint8_t *buf,
- int len,
- struct sockaddr_in to)
+static void ssmpingd_sendto(struct ssmpingd_sock *ss, const uint8_t *buf,
+ int len, struct sockaddr_in to)
{
- socklen_t tolen = sizeof(to);
- int sent;
-
- sent = sendto(ss->sock_fd, buf, len, MSG_DONTWAIT,
- (struct sockaddr *)&to, tolen);
- if (sent != len) {
- char to_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<to?>", to.sin_addr, to_str, sizeof(to_str));
- if (sent < 0) {
- zlog_warn("%s: sendto() failure to %s,%d: fd=%d len=%d: errno=%d: %s",
- __PRETTY_FUNCTION__,
- to_str, ntohs(to.sin_port), ss->sock_fd, len,
- errno, safe_strerror(errno));
- }
- else {
- zlog_warn("%s: sendto() partial to %s,%d: fd=%d len=%d: sent=%d",
- __PRETTY_FUNCTION__,
- to_str, ntohs(to.sin_port), ss->sock_fd,
- len, sent);
- }
- }
+ socklen_t tolen = sizeof(to);
+ int sent;
+
+ sent = sendto(ss->sock_fd, buf, len, MSG_DONTWAIT,
+ (struct sockaddr *)&to, tolen);
+ if (sent != len) {
+ char to_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<to?>", to.sin_addr, to_str, sizeof(to_str));
+ if (sent < 0) {
+ zlog_warn(
+ "%s: sendto() failure to %s,%d: fd=%d len=%d: errno=%d: %s",
+ __PRETTY_FUNCTION__, to_str, ntohs(to.sin_port),
+ ss->sock_fd, len, errno, safe_strerror(errno));
+ } else {
+ zlog_warn(
+ "%s: sendto() partial to %s,%d: fd=%d len=%d: sent=%d",
+ __PRETTY_FUNCTION__, to_str, ntohs(to.sin_port),
+ ss->sock_fd, len, sent);
+ }
+ }
}
static int ssmpingd_read_msg(struct ssmpingd_sock *ss)
{
- struct interface *ifp;
- struct sockaddr_in from;
- struct sockaddr_in to;
- socklen_t fromlen = sizeof(from);
- socklen_t tolen = sizeof(to);
- ifindex_t ifindex = -1;
- uint8_t buf[1000];
- int len;
-
- ++ss->requests;
-
- len = pim_socket_recvfromto(ss->sock_fd, buf, sizeof(buf),
- &from, &fromlen,
- &to, &tolen,
- &ifindex);
- if (len < 0) {
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str));
- zlog_warn("%s: failure receiving ssmping for source %s on fd=%d: errno=%d: %s",
- __PRETTY_FUNCTION__, source_str, ss->sock_fd, errno, safe_strerror(errno));
- return -1;
- }
-
- ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
-
- if (buf[0] != PIM_SSMPINGD_REQUEST) {
- char source_str[INET_ADDRSTRLEN];
- char from_str[INET_ADDRSTRLEN];
- char to_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str));
- pim_inet4_dump("<from?>", from.sin_addr, from_str, sizeof(from_str));
- pim_inet4_dump("<to?>", to.sin_addr, to_str, sizeof(to_str));
- zlog_warn("%s: bad ssmping type=%d from %s,%d to %s,%d on interface %s ifindex=%d fd=%d src=%s",
- __PRETTY_FUNCTION__,
- buf[0],
- from_str, ntohs(from.sin_port),
- to_str, ntohs(to.sin_port),
- ifp ? ifp->name : "<iface?>",
- ifindex, ss->sock_fd,
- source_str);
- return 0;
- }
-
- if (PIM_DEBUG_SSMPINGD) {
- char source_str[INET_ADDRSTRLEN];
- char from_str[INET_ADDRSTRLEN];
- char to_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str));
- pim_inet4_dump("<from?>", from.sin_addr, from_str, sizeof(from_str));
- pim_inet4_dump("<to?>", to.sin_addr, to_str, sizeof(to_str));
- zlog_debug("%s: recv ssmping from %s,%d to %s,%d on interface %s ifindex=%d fd=%d src=%s",
- __PRETTY_FUNCTION__,
- from_str, ntohs(from.sin_port),
- to_str, ntohs(to.sin_port),
- ifp ? ifp->name : "<iface?>",
- ifindex, ss->sock_fd,
- source_str);
- }
-
- buf[0] = PIM_SSMPINGD_REPLY;
-
- /* unicast reply */
- ssmpingd_sendto(ss, buf, len, from);
-
- /* multicast reply */
- from.sin_addr = qpim_ssmpingd_group_addr;
- ssmpingd_sendto(ss, buf, len, from);
-
- return 0;
+ struct interface *ifp;
+ struct sockaddr_in from;
+ struct sockaddr_in to;
+ socklen_t fromlen = sizeof(from);
+ socklen_t tolen = sizeof(to);
+ ifindex_t ifindex = -1;
+ uint8_t buf[1000];
+ int len;
+
+ ++ss->requests;
+
+ len = pim_socket_recvfromto(ss->sock_fd, buf, sizeof(buf), &from,
+ &fromlen, &to, &tolen, &ifindex);
+ if (len < 0) {
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", ss->source_addr, source_str,
+ sizeof(source_str));
+ zlog_warn(
+ "%s: failure receiving ssmping for source %s on fd=%d: errno=%d: %s",
+ __PRETTY_FUNCTION__, source_str, ss->sock_fd, errno,
+ safe_strerror(errno));
+ return -1;
+ }
+
+ ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
+
+ if (buf[0] != PIM_SSMPINGD_REQUEST) {
+ char source_str[INET_ADDRSTRLEN];
+ char from_str[INET_ADDRSTRLEN];
+ char to_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", ss->source_addr, source_str,
+ sizeof(source_str));
+ pim_inet4_dump("<from?>", from.sin_addr, from_str,
+ sizeof(from_str));
+ pim_inet4_dump("<to?>", to.sin_addr, to_str, sizeof(to_str));
+ zlog_warn(
+ "%s: bad ssmping type=%d from %s,%d to %s,%d on interface %s ifindex=%d fd=%d src=%s",
+ __PRETTY_FUNCTION__, buf[0], from_str,
+ ntohs(from.sin_port), to_str, ntohs(to.sin_port),
+ ifp ? ifp->name : "<iface?>", ifindex, ss->sock_fd,
+ source_str);
+ return 0;
+ }
+
+ if (PIM_DEBUG_SSMPINGD) {
+ char source_str[INET_ADDRSTRLEN];
+ char from_str[INET_ADDRSTRLEN];
+ char to_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", ss->source_addr, source_str,
+ sizeof(source_str));
+ pim_inet4_dump("<from?>", from.sin_addr, from_str,
+ sizeof(from_str));
+ pim_inet4_dump("<to?>", to.sin_addr, to_str, sizeof(to_str));
+ zlog_debug(
+ "%s: recv ssmping from %s,%d to %s,%d on interface %s ifindex=%d fd=%d src=%s",
+ __PRETTY_FUNCTION__, from_str, ntohs(from.sin_port),
+ to_str, ntohs(to.sin_port),
+ ifp ? ifp->name : "<iface?>", ifindex, ss->sock_fd,
+ source_str);
+ }
+
+ buf[0] = PIM_SSMPINGD_REPLY;
+
+ /* unicast reply */
+ ssmpingd_sendto(ss, buf, len, from);
+
+ /* multicast reply */
+ from.sin_addr = qpim_ssmpingd_group_addr;
+ ssmpingd_sendto(ss, buf, len, from);
+
+ return 0;
}
static int ssmpingd_sock_read(struct thread *t)
{
- struct ssmpingd_sock *ss;
- int result;
+ struct ssmpingd_sock *ss;
+ int result;
- ss = THREAD_ARG(t);
+ ss = THREAD_ARG(t);
- result = ssmpingd_read_msg(ss);
+ result = ssmpingd_read_msg(ss);
- /* Keep reading */
- ssmpingd_read_on(ss);
+ /* Keep reading */
+ ssmpingd_read_on(ss);
- return result;
+ return result;
}
static void ssmpingd_read_on(struct ssmpingd_sock *ss)
{
- thread_add_read(master, ssmpingd_sock_read, ss, ss->sock_fd,
- &ss->t_sock_read);
+ thread_add_read(master, ssmpingd_sock_read, ss, ss->sock_fd,
+ &ss->t_sock_read);
}
static struct ssmpingd_sock *ssmpingd_new(struct in_addr source_addr)
{
- struct ssmpingd_sock *ss;
- int sock_fd;
-
- if (!qpim_ssmpingd_list) {
- qpim_ssmpingd_list = list_new();
- if (!qpim_ssmpingd_list) {
- zlog_err("%s %s: failure: qpim_ssmpingd_list=list_new()",
- __FILE__, __PRETTY_FUNCTION__);
- return 0;
- }
- qpim_ssmpingd_list->del = (void (*)(void *)) ssmpingd_free;
- }
-
- sock_fd = ssmpingd_socket(source_addr, /* port: */ 4321, /* mTTL: */ 64);
- if (sock_fd < 0) {
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- zlog_warn("%s: ssmpingd_socket() failure for source %s",
- __PRETTY_FUNCTION__, source_str);
- return 0;
- }
-
- ss = XCALLOC(MTYPE_PIM_SSMPINGD, sizeof(*ss));
- if (!ss) {
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- zlog_err("%s: XCALLOC(%zu) failure for ssmpingd source %s",
- __PRETTY_FUNCTION__,
- sizeof(*ss), source_str);
- close(sock_fd);
- return 0;
- }
-
- ss->sock_fd = sock_fd;
- ss->t_sock_read = NULL;
- ss->source_addr = source_addr;
- ss->creation = pim_time_monotonic_sec();
- ss->requests = 0;
-
- listnode_add(qpim_ssmpingd_list, ss);
-
- ssmpingd_read_on(ss);
-
- return ss;
+ struct ssmpingd_sock *ss;
+ int sock_fd;
+
+ if (!qpim_ssmpingd_list) {
+ qpim_ssmpingd_list = list_new();
+ if (!qpim_ssmpingd_list) {
+ zlog_err(
+ "%s %s: failure: qpim_ssmpingd_list=list_new()",
+ __FILE__, __PRETTY_FUNCTION__);
+ return 0;
+ }
+ qpim_ssmpingd_list->del = (void (*)(void *))ssmpingd_free;
+ }
+
+ sock_fd =
+ ssmpingd_socket(source_addr, /* port: */ 4321, /* mTTL: */ 64);
+ if (sock_fd < 0) {
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", source_addr, source_str,
+ sizeof(source_str));
+ zlog_warn("%s: ssmpingd_socket() failure for source %s",
+ __PRETTY_FUNCTION__, source_str);
+ return 0;
+ }
+
+ ss = XCALLOC(MTYPE_PIM_SSMPINGD, sizeof(*ss));
+ if (!ss) {
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", source_addr, source_str,
+ sizeof(source_str));
+ zlog_err("%s: XCALLOC(%zu) failure for ssmpingd source %s",
+ __PRETTY_FUNCTION__, sizeof(*ss), source_str);
+ close(sock_fd);
+ return 0;
+ }
+
+ ss->sock_fd = sock_fd;
+ ss->t_sock_read = NULL;
+ ss->source_addr = source_addr;
+ ss->creation = pim_time_monotonic_sec();
+ ss->requests = 0;
+
+ listnode_add(qpim_ssmpingd_list, ss);
+
+ ssmpingd_read_on(ss);
+
+ return ss;
}
int pim_ssmpingd_start(struct in_addr source_addr)
{
- struct ssmpingd_sock *ss;
-
- ss = ssmpingd_find(source_addr);
- if (ss) {
- /* silently ignore request to recreate entry */
- return 0;
- }
-
- {
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- zlog_info("%s: starting ssmpingd for source %s",
- __PRETTY_FUNCTION__, source_str);
- }
-
- ss = ssmpingd_new(source_addr);
- if (!ss) {
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- zlog_warn("%s: ssmpingd_new() failure for source %s",
- __PRETTY_FUNCTION__, source_str);
- return -1;
- }
-
- return 0;
+ struct ssmpingd_sock *ss;
+
+ ss = ssmpingd_find(source_addr);
+ if (ss) {
+ /* silently ignore request to recreate entry */
+ return 0;
+ }
+
+ {
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", source_addr, source_str,
+ sizeof(source_str));
+ zlog_info("%s: starting ssmpingd for source %s",
+ __PRETTY_FUNCTION__, source_str);
+ }
+
+ ss = ssmpingd_new(source_addr);
+ if (!ss) {
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", source_addr, source_str,
+ sizeof(source_str));
+ zlog_warn("%s: ssmpingd_new() failure for source %s",
+ __PRETTY_FUNCTION__, source_str);
+ return -1;
+ }
+
+ return 0;
}
int pim_ssmpingd_stop(struct in_addr source_addr)
{
- struct ssmpingd_sock *ss;
-
- ss = ssmpingd_find(source_addr);
- if (!ss) {
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- zlog_warn("%s: could not find ssmpingd for source %s",
- __PRETTY_FUNCTION__, source_str);
- return -1;
- }
-
- {
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
- zlog_info("%s: stopping ssmpingd for source %s",
- __PRETTY_FUNCTION__, source_str);
- }
-
- ssmpingd_delete(ss);
-
- return 0;
+ struct ssmpingd_sock *ss;
+
+ ss = ssmpingd_find(source_addr);
+ if (!ss) {
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", source_addr, source_str,
+ sizeof(source_str));
+ zlog_warn("%s: could not find ssmpingd for source %s",
+ __PRETTY_FUNCTION__, source_str);
+ return -1;
+ }
+
+ {
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", source_addr, source_str,
+ sizeof(source_str));
+ zlog_info("%s: stopping ssmpingd for source %s",
+ __PRETTY_FUNCTION__, source_str);
+ }
+
+ ssmpingd_delete(ss);
+
+ return 0;
}
diff --git a/pimd/pim_ssmpingd.h b/pimd/pim_ssmpingd.h
index 02aa6271c..89fb320a7 100644
--- a/pimd/pim_ssmpingd.h
+++ b/pimd/pim_ssmpingd.h
@@ -27,11 +27,11 @@
#include "pim_iface.h"
struct ssmpingd_sock {
- int sock_fd; /* socket */
- struct thread *t_sock_read; /* thread for reading socket */
- struct in_addr source_addr; /* source address */
- int64_t creation; /* timestamp of socket creation */
- int64_t requests; /* counter */
+ int sock_fd; /* socket */
+ struct thread *t_sock_read; /* thread for reading socket */
+ struct in_addr source_addr; /* source address */
+ int64_t creation; /* timestamp of socket creation */
+ int64_t requests; /* counter */
};
void pim_ssmpingd_init(void);
diff --git a/pimd/pim_static.c b/pimd/pim_static.c
index d373581fe..7c9aca47a 100644
--- a/pimd/pim_static.c
+++ b/pimd/pim_static.c
@@ -34,317 +34,337 @@
void pim_static_route_free(struct static_route *s_route)
{
- XFREE(MTYPE_PIM_STATIC_ROUTE, s_route);
+ XFREE(MTYPE_PIM_STATIC_ROUTE, s_route);
}
-static struct static_route * static_route_alloc()
+static struct static_route *static_route_alloc()
{
- struct static_route *s_route;
-
- s_route = XCALLOC(MTYPE_PIM_STATIC_ROUTE, sizeof(*s_route));
- if (!s_route) {
- zlog_err("PIM XCALLOC(%zu) failure", sizeof(*s_route));
- return 0;
- }
- return s_route;
+ struct static_route *s_route;
+
+ s_route = XCALLOC(MTYPE_PIM_STATIC_ROUTE, sizeof(*s_route));
+ if (!s_route) {
+ zlog_err("PIM XCALLOC(%zu) failure", sizeof(*s_route));
+ return 0;
+ }
+ return s_route;
}
-static struct static_route *static_route_new(unsigned int iif,
- unsigned int oif,
- struct in_addr group,
- struct in_addr source)
+static struct static_route *static_route_new(unsigned int iif, unsigned int oif,
+ struct in_addr group,
+ struct in_addr source)
{
- struct static_route * s_route;
- s_route = static_route_alloc();
- if (!s_route) {
- return 0;
- }
-
- s_route->group = group;
- s_route->source = source;
- s_route->iif = iif;
- s_route->oif_ttls[oif] = 1;
- s_route->c_oil.oil_ref_count = 1;
- s_route->c_oil.oil.mfcc_origin = source;
- s_route->c_oil.oil.mfcc_mcastgrp = group;
- s_route->c_oil.oil.mfcc_parent = iif;
- s_route->c_oil.oil.mfcc_ttls[oif] = 1;
- s_route->c_oil.oif_creation[oif] = pim_time_monotonic_sec();
-
- return s_route;
+ struct static_route *s_route;
+ s_route = static_route_alloc();
+ if (!s_route) {
+ return 0;
+ }
+
+ s_route->group = group;
+ s_route->source = source;
+ s_route->iif = iif;
+ s_route->oif_ttls[oif] = 1;
+ s_route->c_oil.oil_ref_count = 1;
+ s_route->c_oil.oil.mfcc_origin = source;
+ s_route->c_oil.oil.mfcc_mcastgrp = group;
+ s_route->c_oil.oil.mfcc_parent = iif;
+ s_route->c_oil.oil.mfcc_ttls[oif] = 1;
+ s_route->c_oil.oif_creation[oif] = pim_time_monotonic_sec();
+
+ return s_route;
}
-int pim_static_add(struct interface *iif, struct interface *oif, struct in_addr group, struct in_addr source)
+int pim_static_add(struct interface *iif, struct interface *oif,
+ struct in_addr group, struct in_addr source)
{
- struct listnode *node = NULL;
- struct static_route *s_route = NULL;
- struct static_route *original_s_route = NULL;
- struct pim_interface *pim_iif = iif ? iif->info : NULL;
- struct pim_interface *pim_oif = oif ? oif->info : NULL;
- ifindex_t iif_index = pim_iif ? pim_iif->mroute_vif_index : 0;
- ifindex_t oif_index = pim_oif ? pim_oif->mroute_vif_index : 0;
-
- if (!iif_index || !oif_index) {
- zlog_warn("%s %s: Unable to add static route: Invalid interface index(iif=%d,oif=%d)",
- __FILE__, __PRETTY_FUNCTION__,
- iif_index,
- oif_index);
- return -2;
- }
+ struct listnode *node = NULL;
+ struct static_route *s_route = NULL;
+ struct static_route *original_s_route = NULL;
+ struct pim_interface *pim_iif = iif ? iif->info : NULL;
+ struct pim_interface *pim_oif = oif ? oif->info : NULL;
+ ifindex_t iif_index = pim_iif ? pim_iif->mroute_vif_index : 0;
+ ifindex_t oif_index = pim_oif ? pim_oif->mroute_vif_index : 0;
+
+ if (!iif_index || !oif_index) {
+ zlog_warn(
+ "%s %s: Unable to add static route: Invalid interface index(iif=%d,oif=%d)",
+ __FILE__, __PRETTY_FUNCTION__, iif_index, oif_index);
+ return -2;
+ }
#ifdef PIM_ENFORCE_LOOPFREE_MFC
- if (iif_index == oif_index) {
- /* looped MFC entry */
- zlog_warn("%s %s: Unable to add static route: Looped MFC entry(iif=%d,oif=%d)",
- __FILE__, __PRETTY_FUNCTION__,
- iif_index,
- oif_index);
- return -4;
- }
+ if (iif_index == oif_index) {
+ /* looped MFC entry */
+ zlog_warn(
+ "%s %s: Unable to add static route: Looped MFC entry(iif=%d,oif=%d)",
+ __FILE__, __PRETTY_FUNCTION__, iif_index, oif_index);
+ return -4;
+ }
#endif
- for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
- if (s_route->group.s_addr == group.s_addr &&
- s_route->source.s_addr == source.s_addr) {
- if (s_route->iif == iif_index &&
- s_route->oif_ttls[oif_index]) {
- char gifaddr_str[INET_ADDRSTRLEN];
- char sifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", group, gifaddr_str, sizeof(gifaddr_str));
- pim_inet4_dump("<ifaddr?>", source, sifaddr_str, sizeof(sifaddr_str));
- zlog_warn("%s %s: Unable to add static route: Route already exists (iif=%d,oif=%d,group=%s,source=%s)",
- __FILE__, __PRETTY_FUNCTION__,
- iif_index,
- oif_index,
- gifaddr_str,
- sifaddr_str);
- return -3;
- }
-
- /* Ok, from here on out we will be making changes to the s_route structure, but if
- * for some reason we fail to commit these changes to the kernel, we want to be able
- * restore the state of the list. So copy the node data and if need be, we can copy
- * back if it fails.
- */
- original_s_route = static_route_alloc();
- if (!original_s_route) {
- return -5;
- }
- memcpy(original_s_route, s_route, sizeof(struct static_route));
-
- /* Route exists and has the same input interface, but adding a new output interface */
- if (s_route->iif == iif_index) {
- s_route->oif_ttls[oif_index] = 1;
- s_route->c_oil.oil.mfcc_ttls[oif_index] = 1;
- s_route->c_oil.oif_creation[oif_index] = pim_time_monotonic_sec();
- ++s_route->c_oil.oil_ref_count;
- } else {
- /* input interface changed */
- s_route->iif = iif_index;
- s_route->c_oil.oil.mfcc_parent = iif_index;
+ for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
+ if (s_route->group.s_addr == group.s_addr
+ && s_route->source.s_addr == source.s_addr) {
+ if (s_route->iif == iif_index
+ && s_route->oif_ttls[oif_index]) {
+ char gifaddr_str[INET_ADDRSTRLEN];
+ char sifaddr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<ifaddr?>", group, gifaddr_str,
+ sizeof(gifaddr_str));
+ pim_inet4_dump("<ifaddr?>", source, sifaddr_str,
+ sizeof(sifaddr_str));
+ zlog_warn(
+ "%s %s: Unable to add static route: Route already exists (iif=%d,oif=%d,group=%s,source=%s)",
+ __FILE__, __PRETTY_FUNCTION__,
+ iif_index, oif_index, gifaddr_str,
+ sifaddr_str);
+ return -3;
+ }
+
+ /* Ok, from here on out we will be making changes to the
+ * s_route structure, but if
+ * for some reason we fail to commit these changes to
+ * the kernel, we want to be able
+ * restore the state of the list. So copy the node data
+ * and if need be, we can copy
+ * back if it fails.
+ */
+ original_s_route = static_route_alloc();
+ if (!original_s_route) {
+ return -5;
+ }
+ memcpy(original_s_route, s_route,
+ sizeof(struct static_route));
+
+ /* Route exists and has the same input interface, but
+ * adding a new output interface */
+ if (s_route->iif == iif_index) {
+ s_route->oif_ttls[oif_index] = 1;
+ s_route->c_oil.oil.mfcc_ttls[oif_index] = 1;
+ s_route->c_oil.oif_creation[oif_index] =
+ pim_time_monotonic_sec();
+ ++s_route->c_oil.oil_ref_count;
+ } else {
+ /* input interface changed */
+ s_route->iif = iif_index;
+ s_route->c_oil.oil.mfcc_parent = iif_index;
#ifdef PIM_ENFORCE_LOOPFREE_MFC
- /* check to make sure the new input was not an old output */
- if (s_route->oif_ttls[iif_index]) {
- s_route->oif_ttls[iif_index] = 0;
- s_route->c_oil.oif_creation[iif_index] = 0;
- s_route->c_oil.oil.mfcc_ttls[iif_index] = 0;
- --s_route->c_oil.oil_ref_count;
- }
+ /* check to make sure the new input was not an
+ * old output */
+ if (s_route->oif_ttls[iif_index]) {
+ s_route->oif_ttls[iif_index] = 0;
+ s_route->c_oil.oif_creation[iif_index] =
+ 0;
+ s_route->c_oil.oil
+ .mfcc_ttls[iif_index] = 0;
+ --s_route->c_oil.oil_ref_count;
+ }
#endif
- /* now add the new output, if it is new */
- if (!s_route->oif_ttls[oif_index]) {
- s_route->oif_ttls[oif_index] = 1;
- s_route->c_oil.oif_creation[oif_index] = pim_time_monotonic_sec();
- s_route->c_oil.oil.mfcc_ttls[oif_index] = 1;
- ++s_route->c_oil.oil_ref_count;
- }
- }
-
- break;
- }
- }
-
- /* If node is null then we reached the end of the list without finding a match */
- if (!node) {
- s_route = static_route_new(iif_index, oif_index, group, source);
- listnode_add(qpim_static_route_list, s_route);
- }
-
- if (pim_mroute_add(&s_route->c_oil, __PRETTY_FUNCTION__))
- {
- char gifaddr_str[INET_ADDRSTRLEN];
- char sifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", group, gifaddr_str, sizeof(gifaddr_str));
- pim_inet4_dump("<ifaddr?>", source, sifaddr_str, sizeof(sifaddr_str));
- zlog_warn("%s %s: Unable to add static route(iif=%d,oif=%d,group=%s,source=%s)",
- __FILE__, __PRETTY_FUNCTION__,
- iif_index,
- oif_index,
- gifaddr_str,
- sifaddr_str);
-
- /* Need to put s_route back to the way it was */
- if (original_s_route) {
- memcpy(s_route, original_s_route, sizeof(struct static_route));
- } else {
- /* we never stored off a copy, so it must have been a fresh new route */
- listnode_delete(qpim_static_route_list, s_route);
- pim_static_route_free(s_route);
- }
-
- if (original_s_route) {
- pim_static_route_free(original_s_route);
- }
-
- return -1;
- }
-
- /* Make sure we free the memory for the route copy if used */
- if (original_s_route) {
- pim_static_route_free(original_s_route);
- }
-
- if (PIM_DEBUG_STATIC) {
- char gifaddr_str[INET_ADDRSTRLEN];
- char sifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", group, gifaddr_str, sizeof(gifaddr_str));
- pim_inet4_dump("<ifaddr?>", source, sifaddr_str, sizeof(sifaddr_str));
- zlog_debug("%s: Static route added(iif=%d,oif=%d,group=%s,source=%s)",
- __PRETTY_FUNCTION__,
- iif_index,
- oif_index,
- gifaddr_str,
- sifaddr_str);
- }
-
- return 0;
+ /* now add the new output, if it is new */
+ if (!s_route->oif_ttls[oif_index]) {
+ s_route->oif_ttls[oif_index] = 1;
+ s_route->c_oil.oif_creation[oif_index] =
+ pim_time_monotonic_sec();
+ s_route->c_oil.oil
+ .mfcc_ttls[oif_index] = 1;
+ ++s_route->c_oil.oil_ref_count;
+ }
+ }
+
+ break;
+ }
+ }
+
+ /* If node is null then we reached the end of the list without finding a
+ * match */
+ if (!node) {
+ s_route = static_route_new(iif_index, oif_index, group, source);
+ listnode_add(qpim_static_route_list, s_route);
+ }
+
+ if (pim_mroute_add(&s_route->c_oil, __PRETTY_FUNCTION__)) {
+ char gifaddr_str[INET_ADDRSTRLEN];
+ char sifaddr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<ifaddr?>", group, gifaddr_str,
+ sizeof(gifaddr_str));
+ pim_inet4_dump("<ifaddr?>", source, sifaddr_str,
+ sizeof(sifaddr_str));
+ zlog_warn(
+ "%s %s: Unable to add static route(iif=%d,oif=%d,group=%s,source=%s)",
+ __FILE__, __PRETTY_FUNCTION__, iif_index, oif_index,
+ gifaddr_str, sifaddr_str);
+
+ /* Need to put s_route back to the way it was */
+ if (original_s_route) {
+ memcpy(s_route, original_s_route,
+ sizeof(struct static_route));
+ } else {
+ /* we never stored off a copy, so it must have been a
+ * fresh new route */
+ listnode_delete(qpim_static_route_list, s_route);
+ pim_static_route_free(s_route);
+ }
+
+ if (original_s_route) {
+ pim_static_route_free(original_s_route);
+ }
+
+ return -1;
+ }
+
+ /* Make sure we free the memory for the route copy if used */
+ if (original_s_route) {
+ pim_static_route_free(original_s_route);
+ }
+
+ if (PIM_DEBUG_STATIC) {
+ char gifaddr_str[INET_ADDRSTRLEN];
+ char sifaddr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<ifaddr?>", group, gifaddr_str,
+ sizeof(gifaddr_str));
+ pim_inet4_dump("<ifaddr?>", source, sifaddr_str,
+ sizeof(sifaddr_str));
+ zlog_debug(
+ "%s: Static route added(iif=%d,oif=%d,group=%s,source=%s)",
+ __PRETTY_FUNCTION__, iif_index, oif_index, gifaddr_str,
+ sifaddr_str);
+ }
+
+ return 0;
}
-int pim_static_del(struct interface *iif, struct interface *oif, struct in_addr group, struct in_addr source)
+int pim_static_del(struct interface *iif, struct interface *oif,
+ struct in_addr group, struct in_addr source)
{
- struct listnode *node = NULL;
- struct listnode *nextnode = NULL;
- struct static_route *s_route = NULL;
- struct pim_interface *pim_iif = iif ? iif->info : 0;
- struct pim_interface *pim_oif = oif ? oif->info : 0;
- ifindex_t iif_index = pim_iif ? pim_iif->mroute_vif_index : 0;
- ifindex_t oif_index = pim_oif ? pim_oif->mroute_vif_index : 0;
-
- if (!iif_index || !oif_index) {
- zlog_warn("%s %s: Unable to remove static route: Invalid interface index(iif=%d,oif=%d)",
- __FILE__, __PRETTY_FUNCTION__,
- iif_index,
- oif_index);
- return -2;
- }
-
- for (ALL_LIST_ELEMENTS(qpim_static_route_list, node, nextnode, s_route)) {
- if (s_route->iif == iif_index &&
- s_route->group.s_addr == group.s_addr &&
- s_route->source.s_addr == source.s_addr &&
- s_route->oif_ttls[oif_index]) {
- s_route->oif_ttls[oif_index] = 0;
- s_route->c_oil.oil.mfcc_ttls[oif_index] = 0;
- --s_route->c_oil.oil_ref_count;
-
- /* If there are no more outputs then delete the whole route, otherwise set the route with the new outputs */
- if (s_route->c_oil.oil_ref_count <= 0 ?
- pim_mroute_del(&s_route->c_oil, __PRETTY_FUNCTION__) : pim_mroute_add(&s_route->c_oil, __PRETTY_FUNCTION__)) {
- char gifaddr_str[INET_ADDRSTRLEN];
- char sifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", group, gifaddr_str, sizeof(gifaddr_str));
- pim_inet4_dump("<ifaddr?>", source, sifaddr_str, sizeof(sifaddr_str));
- zlog_warn("%s %s: Unable to remove static route(iif=%d,oif=%d,group=%s,source=%s)",
- __FILE__, __PRETTY_FUNCTION__,
- iif_index,
- oif_index,
- gifaddr_str,
- sifaddr_str);
-
- s_route->oif_ttls[oif_index] = 1;
- s_route->c_oil.oil.mfcc_ttls[oif_index] = 1;
- ++s_route->c_oil.oil_ref_count;
-
- return -1;
- }
-
- s_route->c_oil.oif_creation[oif_index] = 0;
-
- if (s_route->c_oil.oil_ref_count <= 0) {
- listnode_delete(qpim_static_route_list, s_route);
- pim_static_route_free(s_route);
- }
-
- if (PIM_DEBUG_STATIC) {
- char gifaddr_str[INET_ADDRSTRLEN];
- char sifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", group, gifaddr_str, sizeof(gifaddr_str));
- pim_inet4_dump("<ifaddr?>", source, sifaddr_str, sizeof(sifaddr_str));
- zlog_debug("%s: Static route removed(iif=%d,oif=%d,group=%s,source=%s)",
- __PRETTY_FUNCTION__,
- iif_index,
- oif_index,
- gifaddr_str,
- sifaddr_str);
- }
-
- break;
- }
- }
-
- if (!node) {
- char gifaddr_str[INET_ADDRSTRLEN];
- char sifaddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<ifaddr?>", group, gifaddr_str, sizeof(gifaddr_str));
- pim_inet4_dump("<ifaddr?>", source, sifaddr_str, sizeof(sifaddr_str));
- zlog_warn("%s %s: Unable to remove static route: Route does not exist(iif=%d,oif=%d,group=%s,source=%s)",
- __FILE__, __PRETTY_FUNCTION__,
- iif_index,
- oif_index,
- gifaddr_str,
- sifaddr_str);
- return -3;
- }
-
- return 0;
+ struct listnode *node = NULL;
+ struct listnode *nextnode = NULL;
+ struct static_route *s_route = NULL;
+ struct pim_interface *pim_iif = iif ? iif->info : 0;
+ struct pim_interface *pim_oif = oif ? oif->info : 0;
+ ifindex_t iif_index = pim_iif ? pim_iif->mroute_vif_index : 0;
+ ifindex_t oif_index = pim_oif ? pim_oif->mroute_vif_index : 0;
+
+ if (!iif_index || !oif_index) {
+ zlog_warn(
+ "%s %s: Unable to remove static route: Invalid interface index(iif=%d,oif=%d)",
+ __FILE__, __PRETTY_FUNCTION__, iif_index, oif_index);
+ return -2;
+ }
+
+ for (ALL_LIST_ELEMENTS(qpim_static_route_list, node, nextnode,
+ s_route)) {
+ if (s_route->iif == iif_index
+ && s_route->group.s_addr == group.s_addr
+ && s_route->source.s_addr == source.s_addr
+ && s_route->oif_ttls[oif_index]) {
+ s_route->oif_ttls[oif_index] = 0;
+ s_route->c_oil.oil.mfcc_ttls[oif_index] = 0;
+ --s_route->c_oil.oil_ref_count;
+
+ /* If there are no more outputs then delete the whole
+ * route, otherwise set the route with the new outputs
+ */
+ if (s_route->c_oil.oil_ref_count <= 0
+ ? pim_mroute_del(&s_route->c_oil,
+ __PRETTY_FUNCTION__)
+ : pim_mroute_add(&s_route->c_oil,
+ __PRETTY_FUNCTION__)) {
+ char gifaddr_str[INET_ADDRSTRLEN];
+ char sifaddr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<ifaddr?>", group, gifaddr_str,
+ sizeof(gifaddr_str));
+ pim_inet4_dump("<ifaddr?>", source, sifaddr_str,
+ sizeof(sifaddr_str));
+ zlog_warn(
+ "%s %s: Unable to remove static route(iif=%d,oif=%d,group=%s,source=%s)",
+ __FILE__, __PRETTY_FUNCTION__,
+ iif_index, oif_index, gifaddr_str,
+ sifaddr_str);
+
+ s_route->oif_ttls[oif_index] = 1;
+ s_route->c_oil.oil.mfcc_ttls[oif_index] = 1;
+ ++s_route->c_oil.oil_ref_count;
+
+ return -1;
+ }
+
+ s_route->c_oil.oif_creation[oif_index] = 0;
+
+ if (s_route->c_oil.oil_ref_count <= 0) {
+ listnode_delete(qpim_static_route_list,
+ s_route);
+ pim_static_route_free(s_route);
+ }
+
+ if (PIM_DEBUG_STATIC) {
+ char gifaddr_str[INET_ADDRSTRLEN];
+ char sifaddr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<ifaddr?>", group, gifaddr_str,
+ sizeof(gifaddr_str));
+ pim_inet4_dump("<ifaddr?>", source, sifaddr_str,
+ sizeof(sifaddr_str));
+ zlog_debug(
+ "%s: Static route removed(iif=%d,oif=%d,group=%s,source=%s)",
+ __PRETTY_FUNCTION__, iif_index,
+ oif_index, gifaddr_str, sifaddr_str);
+ }
+
+ break;
+ }
+ }
+
+ if (!node) {
+ char gifaddr_str[INET_ADDRSTRLEN];
+ char sifaddr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<ifaddr?>", group, gifaddr_str,
+ sizeof(gifaddr_str));
+ pim_inet4_dump("<ifaddr?>", source, sifaddr_str,
+ sizeof(sifaddr_str));
+ zlog_warn(
+ "%s %s: Unable to remove static route: Route does not exist(iif=%d,oif=%d,group=%s,source=%s)",
+ __FILE__, __PRETTY_FUNCTION__, iif_index, oif_index,
+ gifaddr_str, sifaddr_str);
+ return -3;
+ }
+
+ return 0;
}
-int
-pim_static_write_mroute (struct vty *vty, struct interface *ifp)
+int pim_static_write_mroute(struct vty *vty, struct interface *ifp)
{
- struct pim_interface *pim_ifp = ifp->info;
- struct listnode *node;
- struct static_route *sroute;
- int count = 0;
- char sbuf[INET_ADDRSTRLEN];
- char gbuf[INET_ADDRSTRLEN];
-
- if (!pim_ifp)
- return 0;
-
- for (ALL_LIST_ELEMENTS_RO (qpim_static_route_list, node, sroute))
- {
- pim_inet4_dump ("<ifaddr?>", sroute->group, gbuf, sizeof (gbuf));
- pim_inet4_dump ("<ifaddr?>", sroute->source, sbuf, sizeof (sbuf));
- if (sroute->iif == pim_ifp->mroute_vif_index)
- {
- int i;
- for (i = 0; i < MAXVIFS; i++)
- if (sroute->oif_ttls[i])
- {
- struct interface *oifp = pim_if_find_by_vif_index (i);
- if (sroute->source.s_addr == 0)
- vty_out (vty, " ip mroute %s %s\n", oifp->name, gbuf);
- else
- vty_out (vty, " ip mroute %s %s %s\n", oifp->name, gbuf,
- sbuf);
- count ++;
- }
- }
- }
-
- return count;
+ struct pim_interface *pim_ifp = ifp->info;
+ struct listnode *node;
+ struct static_route *sroute;
+ int count = 0;
+ char sbuf[INET_ADDRSTRLEN];
+ char gbuf[INET_ADDRSTRLEN];
+
+ if (!pim_ifp)
+ return 0;
+
+ for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, sroute)) {
+ pim_inet4_dump("<ifaddr?>", sroute->group, gbuf, sizeof(gbuf));
+ pim_inet4_dump("<ifaddr?>", sroute->source, sbuf, sizeof(sbuf));
+ if (sroute->iif == pim_ifp->mroute_vif_index) {
+ int i;
+ for (i = 0; i < MAXVIFS; i++)
+ if (sroute->oif_ttls[i]) {
+ struct interface *oifp =
+ pim_if_find_by_vif_index(i);
+ if (sroute->source.s_addr == 0)
+ vty_out(vty,
+ " ip mroute %s %s\n",
+ oifp->name, gbuf);
+ else
+ vty_out(vty,
+ " ip mroute %s %s %s\n",
+ oifp->name, gbuf, sbuf);
+ count++;
+ }
+ }
+ }
+
+ return count;
}
diff --git a/pimd/pim_static.h b/pimd/pim_static.h
index 4b5ef7921..1114f4b67 100644
--- a/pimd/pim_static.h
+++ b/pimd/pim_static.h
@@ -25,19 +25,21 @@
#include "if.h"
struct static_route {
- /* Each static route is unique by these pair of addresses */
- struct in_addr group;
- struct in_addr source;
+ /* Each static route is unique by these pair of addresses */
+ struct in_addr group;
+ struct in_addr source;
- struct channel_oil c_oil;
- ifindex_t iif;
- unsigned char oif_ttls[MAXVIFS];
+ struct channel_oil c_oil;
+ ifindex_t iif;
+ unsigned char oif_ttls[MAXVIFS];
};
void pim_static_route_free(struct static_route *s_route);
-int pim_static_add(struct interface *iif, struct interface *oif, struct in_addr group, struct in_addr source);
-int pim_static_del(struct interface *iif, struct interface *oif, struct in_addr group, struct in_addr source);
-int pim_static_write_mroute (struct vty *vty, struct interface *ifp);
+int pim_static_add(struct interface *iif, struct interface *oif,
+ struct in_addr group, struct in_addr source);
+int pim_static_del(struct interface *iif, struct interface *oif,
+ struct in_addr group, struct in_addr source);
+int pim_static_write_mroute(struct vty *vty, struct interface *ifp);
#endif /* PIM_STATIC_H_ */
diff --git a/pimd/pim_str.c b/pimd/pim_str.c
index d1219a868..fa1a6e624 100644
--- a/pimd/pim_str.c
+++ b/pimd/pim_str.c
@@ -27,62 +27,62 @@
#include "pim_str.h"
-void pim_addr_dump (const char *onfail, struct prefix *p, char *buf, int buf_size)
+void pim_addr_dump(const char *onfail, struct prefix *p, char *buf,
+ int buf_size)
{
- int save_errno = errno;
+ int save_errno = errno;
- if (!inet_ntop(p->family, &p->u.prefix, buf, buf_size)) {
- zlog_warn("pim_addr_dump: inet_ntop(buf_size=%d): errno=%d: %s",
- buf_size, errno, safe_strerror(errno));
- if (onfail)
- snprintf(buf, buf_size, "%s", onfail);
- }
+ if (!inet_ntop(p->family, &p->u.prefix, buf, buf_size)) {
+ zlog_warn("pim_addr_dump: inet_ntop(buf_size=%d): errno=%d: %s",
+ buf_size, errno, safe_strerror(errno));
+ if (onfail)
+ snprintf(buf, buf_size, "%s", onfail);
+ }
- errno = save_errno;
+ errno = save_errno;
}
-void pim_inet4_dump(const char *onfail, struct in_addr addr, char *buf, int buf_size)
+void pim_inet4_dump(const char *onfail, struct in_addr addr, char *buf,
+ int buf_size)
{
- int save_errno = errno;
-
- if (addr.s_addr == INADDR_ANY)
- strcpy(buf, "*");
- else
- {
- if (!inet_ntop(AF_INET, &addr, buf, buf_size)) {
- zlog_warn("pim_inet4_dump: inet_ntop(AF_INET,buf_size=%d): errno=%d: %s",
- buf_size, errno, safe_strerror(errno));
- if (onfail)
- snprintf(buf, buf_size, "%s", onfail);
- }
- }
-
- errno = save_errno;
+ int save_errno = errno;
+
+ if (addr.s_addr == INADDR_ANY)
+ strcpy(buf, "*");
+ else {
+ if (!inet_ntop(AF_INET, &addr, buf, buf_size)) {
+ zlog_warn(
+ "pim_inet4_dump: inet_ntop(AF_INET,buf_size=%d): errno=%d: %s",
+ buf_size, errno, safe_strerror(errno));
+ if (onfail)
+ snprintf(buf, buf_size, "%s", onfail);
+ }
+ }
+
+ errno = save_errno;
}
-char *
-pim_str_sg_dump (const struct prefix_sg *sg)
+char *pim_str_sg_dump(const struct prefix_sg *sg)
{
- char src_str[INET_ADDRSTRLEN];
- char grp_str[INET_ADDRSTRLEN];
- static char sg_str[PIM_SG_LEN];
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
+ static char sg_str[PIM_SG_LEN];
- pim_inet4_dump ("<src?>", sg->src, src_str, sizeof(src_str));
- pim_inet4_dump ("<grp?>", sg->grp, grp_str, sizeof(grp_str));
- snprintf (sg_str, PIM_SG_LEN, "(%s,%s)", src_str, grp_str);
+ pim_inet4_dump("<src?>", sg->src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", sg->grp, grp_str, sizeof(grp_str));
+ snprintf(sg_str, PIM_SG_LEN, "(%s,%s)", src_str, grp_str);
- return sg_str;
+ return sg_str;
}
-char *
-pim_str_sg_set (const struct prefix_sg *sg, char *sg_str)
+char *pim_str_sg_set(const struct prefix_sg *sg, char *sg_str)
{
- char src_str[INET_ADDRSTRLEN];
- char grp_str[INET_ADDRSTRLEN];
+ char src_str[INET_ADDRSTRLEN];
+ char grp_str[INET_ADDRSTRLEN];
- pim_inet4_dump ("<src?>", sg->src, src_str, sizeof(src_str));
- pim_inet4_dump ("<grp?>", sg->grp, grp_str, sizeof(grp_str));
- snprintf (sg_str, PIM_SG_LEN, "(%s,%s)", src_str, grp_str);
+ pim_inet4_dump("<src?>", sg->src, src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", sg->grp, grp_str, sizeof(grp_str));
+ snprintf(sg_str, PIM_SG_LEN, "(%s,%s)", src_str, grp_str);
- return sg_str;
+ return sg_str;
}
diff --git a/pimd/pim_str.h b/pimd/pim_str.h
index 0ca517102..12a33a810 100644
--- a/pimd/pim_str.h
+++ b/pimd/pim_str.h
@@ -35,9 +35,11 @@
*/
#define PIM_SG_LEN 36
-void pim_addr_dump (const char *onfail, struct prefix *p, char *buf, int buf_size);
-void pim_inet4_dump(const char *onfail, struct in_addr addr, char *buf, int buf_size);
-char *pim_str_sg_dump (const struct prefix_sg *sg);
-char *pim_str_sg_set (const struct prefix_sg *sg, char *sg_str);
+void pim_addr_dump(const char *onfail, struct prefix *p, char *buf,
+ int buf_size);
+void pim_inet4_dump(const char *onfail, struct in_addr addr, char *buf,
+ int buf_size);
+char *pim_str_sg_dump(const struct prefix_sg *sg);
+char *pim_str_sg_set(const struct prefix_sg *sg, char *sg_str);
#endif
diff --git a/pimd/pim_time.c b/pimd/pim_time.c
index 406fec58d..6f011da43 100644
--- a/pimd/pim_time.c
+++ b/pimd/pim_time.c
@@ -30,16 +30,15 @@
static int gettime_monotonic(struct timeval *tv)
{
- int result;
+ int result;
- result = gettimeofday(tv, 0);
- if (result) {
- zlog_err("%s: gettimeofday() failure: errno=%d: %s",
- __PRETTY_FUNCTION__,
- errno, safe_strerror(errno));
- }
+ result = gettimeofday(tv, 0);
+ if (result) {
+ zlog_err("%s: gettimeofday() failure: errno=%d: %s",
+ __PRETTY_FUNCTION__, errno, safe_strerror(errno));
+ }
- return result;
+ return result;
}
/*
@@ -48,16 +47,15 @@ static int gettime_monotonic(struct timeval *tv)
*/
int64_t pim_time_monotonic_sec()
{
- struct timeval now_tv;
+ struct timeval now_tv;
- if (gettime_monotonic(&now_tv)) {
- zlog_err("%s: gettime_monotonic() failure: errno=%d: %s",
- __PRETTY_FUNCTION__,
- errno, safe_strerror(errno));
- return -1;
- }
+ if (gettime_monotonic(&now_tv)) {
+ zlog_err("%s: gettime_monotonic() failure: errno=%d: %s",
+ __PRETTY_FUNCTION__, errno, safe_strerror(errno));
+ return -1;
+ }
- return now_tv.tv_sec;
+ return now_tv.tv_sec;
}
/*
@@ -66,117 +64,111 @@ int64_t pim_time_monotonic_sec()
*/
int64_t pim_time_monotonic_dsec()
{
- struct timeval now_tv;
- int64_t now_dsec;
+ struct timeval now_tv;
+ int64_t now_dsec;
- if (gettime_monotonic(&now_tv)) {
- zlog_err("%s: gettime_monotonic() failure: errno=%d: %s",
- __PRETTY_FUNCTION__,
- errno, safe_strerror(errno));
- return -1;
- }
+ if (gettime_monotonic(&now_tv)) {
+ zlog_err("%s: gettime_monotonic() failure: errno=%d: %s",
+ __PRETTY_FUNCTION__, errno, safe_strerror(errno));
+ return -1;
+ }
- now_dsec = ((int64_t) now_tv.tv_sec) * 10 + ((int64_t) now_tv.tv_usec) / 100000;
+ now_dsec = ((int64_t)now_tv.tv_sec) * 10
+ + ((int64_t)now_tv.tv_usec) / 100000;
- return now_dsec;
+ return now_dsec;
}
-int64_t
-pim_time_monotonic_usec (void)
+int64_t pim_time_monotonic_usec(void)
{
- struct timeval now_tv;
- int64_t now_dsec;
+ struct timeval now_tv;
+ int64_t now_dsec;
- if (gettime_monotonic(&now_tv)) {
- zlog_err("%s: gettime_monotonic() failure: errno=%d: %s",
- __PRETTY_FUNCTION__,
- errno, safe_strerror(errno));
- return -1;
- }
+ if (gettime_monotonic(&now_tv)) {
+ zlog_err("%s: gettime_monotonic() failure: errno=%d: %s",
+ __PRETTY_FUNCTION__, errno, safe_strerror(errno));
+ return -1;
+ }
- now_dsec = ((int64_t) now_tv.tv_sec) * 1000000 + ((int64_t) now_tv.tv_usec);
-
- return now_dsec;
+ now_dsec =
+ ((int64_t)now_tv.tv_sec) * 1000000 + ((int64_t)now_tv.tv_usec);
+ return now_dsec;
}
int pim_time_mmss(char *buf, int buf_size, long sec)
{
- long mm;
- int wr;
+ long mm;
+ int wr;
+
+ zassert(buf_size >= 5);
- zassert(buf_size >= 5);
+ mm = sec / 60;
+ sec %= 60;
- mm = sec / 60;
- sec %= 60;
-
- wr = snprintf(buf, buf_size, "%02ld:%02ld", mm, sec);
+ wr = snprintf(buf, buf_size, "%02ld:%02ld", mm, sec);
- return wr != 8;
+ return wr != 8;
}
static int pim_time_hhmmss(char *buf, int buf_size, long sec)
{
- long hh;
- long mm;
- int wr;
+ long hh;
+ long mm;
+ int wr;
+
+ zassert(buf_size >= 8);
- zassert(buf_size >= 8);
+ hh = sec / 3600;
+ sec %= 3600;
+ mm = sec / 60;
+ sec %= 60;
- hh = sec / 3600;
- sec %= 3600;
- mm = sec / 60;
- sec %= 60;
-
- wr = snprintf(buf, buf_size, "%02ld:%02ld:%02ld", hh, mm, sec);
+ wr = snprintf(buf, buf_size, "%02ld:%02ld:%02ld", hh, mm, sec);
- return wr != 8;
+ return wr != 8;
}
void pim_time_timer_to_mmss(char *buf, int buf_size, struct thread *t_timer)
{
- if (t_timer) {
- pim_time_mmss(buf, buf_size,
- thread_timer_remain_second(t_timer));
- }
- else {
- snprintf(buf, buf_size, "--:--");
- }
+ if (t_timer) {
+ pim_time_mmss(buf, buf_size,
+ thread_timer_remain_second(t_timer));
+ } else {
+ snprintf(buf, buf_size, "--:--");
+ }
}
void pim_time_timer_to_hhmmss(char *buf, int buf_size, struct thread *t_timer)
{
- if (t_timer) {
- pim_time_hhmmss(buf, buf_size,
- thread_timer_remain_second(t_timer));
- }
- else {
- snprintf(buf, buf_size, "--:--:--");
- }
+ if (t_timer) {
+ pim_time_hhmmss(buf, buf_size,
+ thread_timer_remain_second(t_timer));
+ } else {
+ snprintf(buf, buf_size, "--:--:--");
+ }
}
void pim_time_uptime(char *buf, int buf_size, int64_t uptime_sec)
{
- zassert(buf_size >= 8);
+ zassert(buf_size >= 8);
- pim_time_hhmmss(buf, buf_size, uptime_sec);
+ pim_time_hhmmss(buf, buf_size, uptime_sec);
}
void pim_time_uptime_begin(char *buf, int buf_size, int64_t now, int64_t begin)
{
- if (begin > 0)
- pim_time_uptime(buf, buf_size, now - begin);
- else
- snprintf(buf, buf_size, "--:--:--");
+ if (begin > 0)
+ pim_time_uptime(buf, buf_size, now - begin);
+ else
+ snprintf(buf, buf_size, "--:--:--");
}
long pim_time_timer_remain_msec(struct thread *t_timer)
{
- /* FIXME: Actually fetch msec resolution from thread */
+ /* FIXME: Actually fetch msec resolution from thread */
- /* no timer thread running means timer has expired: return 0 */
+ /* no timer thread running means timer has expired: return 0 */
- return t_timer ?
- 1000 * thread_timer_remain_second(t_timer) :
- 0;
+ return t_timer ? 1000 * thread_timer_remain_second(t_timer) : 0;
}
diff --git a/pimd/pim_tlv.c b/pimd/pim_tlv.c
index 550fdde8e..6d7adf242 100644
--- a/pimd/pim_tlv.c
+++ b/pimd/pim_tlv.c
@@ -29,67 +29,61 @@
#include "pim_str.h"
#include "pim_msg.h"
-uint8_t *pim_tlv_append_uint16(uint8_t *buf,
- const uint8_t *buf_pastend,
- uint16_t option_type,
- uint16_t option_value)
+uint8_t *pim_tlv_append_uint16(uint8_t *buf, const uint8_t *buf_pastend,
+ uint16_t option_type, uint16_t option_value)
{
- uint16_t option_len = 2;
+ uint16_t option_len = 2;
- if ((buf + PIM_TLV_OPTION_SIZE(option_len)) > buf_pastend)
- return NULL;
+ if ((buf + PIM_TLV_OPTION_SIZE(option_len)) > buf_pastend)
+ return NULL;
- *(uint16_t *) buf = htons(option_type);
- buf += 2;
- *(uint16_t *) buf = htons(option_len);
- buf += 2;
- *(uint16_t *) buf = htons(option_value);
- buf += option_len;
+ *(uint16_t *)buf = htons(option_type);
+ buf += 2;
+ *(uint16_t *)buf = htons(option_len);
+ buf += 2;
+ *(uint16_t *)buf = htons(option_value);
+ buf += option_len;
- return buf;
+ return buf;
}
-uint8_t *pim_tlv_append_2uint16(uint8_t *buf,
- const uint8_t *buf_pastend,
- uint16_t option_type,
- uint16_t option_value1,
+uint8_t *pim_tlv_append_2uint16(uint8_t *buf, const uint8_t *buf_pastend,
+ uint16_t option_type, uint16_t option_value1,
uint16_t option_value2)
{
- uint16_t option_len = 4;
+ uint16_t option_len = 4;
- if ((buf + PIM_TLV_OPTION_SIZE(option_len)) > buf_pastend)
- return NULL;
+ if ((buf + PIM_TLV_OPTION_SIZE(option_len)) > buf_pastend)
+ return NULL;
- *(uint16_t *) buf = htons(option_type);
- buf += 2;
- *(uint16_t *) buf = htons(option_len);
- buf += 2;
- *(uint16_t *) buf = htons(option_value1);
- buf += 2;
- *(uint16_t *) buf = htons(option_value2);
- buf += 2;
+ *(uint16_t *)buf = htons(option_type);
+ buf += 2;
+ *(uint16_t *)buf = htons(option_len);
+ buf += 2;
+ *(uint16_t *)buf = htons(option_value1);
+ buf += 2;
+ *(uint16_t *)buf = htons(option_value2);
+ buf += 2;
- return buf;
+ return buf;
}
-uint8_t *pim_tlv_append_uint32(uint8_t *buf,
- const uint8_t *buf_pastend,
- uint16_t option_type,
- uint32_t option_value)
+uint8_t *pim_tlv_append_uint32(uint8_t *buf, const uint8_t *buf_pastend,
+ uint16_t option_type, uint32_t option_value)
{
- uint16_t option_len = 4;
+ uint16_t option_len = 4;
- if ((buf + PIM_TLV_OPTION_SIZE(option_len)) > buf_pastend)
- return NULL;
+ if ((buf + PIM_TLV_OPTION_SIZE(option_len)) > buf_pastend)
+ return NULL;
- *(uint16_t *) buf = htons(option_type);
- buf += 2;
- *(uint16_t *) buf = htons(option_len);
- buf += 2;
- pim_write_uint32(buf, option_value);
- buf += option_len;
+ *(uint16_t *)buf = htons(option_type);
+ buf += 2;
+ *(uint16_t *)buf = htons(option_len);
+ buf += 2;
+ pim_write_uint32(buf, option_value);
+ buf += option_len;
- return buf;
+ return buf;
}
#define ucast_ipv4_encoding_len (2 + sizeof(struct in_addr))
@@ -108,7 +102,8 @@ uint8_t *pim_tlv_append_uint32(uint8_t *buf,
* The PIM address family of the 'Unicast Address' field of this
* address.
*
- * Values 0-127 are as assigned by the IANA for Internet Address * Families in [7]. Values 128-250 are reserved to be assigned by
+ * Values 0-127 are as assigned by the IANA for Internet Address *
+ * Families in [7]. Values 128-250 are reserved to be assigned by
* the IANA for PIM-specific Address Families. Values 251 though
* 255 are designated for private use. As there is no assignment
* authority for this space, collisions should be expected.
@@ -122,31 +117,33 @@ uint8_t *pim_tlv_append_uint32(uint8_t *buf,
* The unicast address as represented by the given Address Family
* and Encoding Type.
*/
-int
-pim_encode_addr_ucast (uint8_t *buf, struct prefix *p)
+int pim_encode_addr_ucast(uint8_t *buf, struct prefix *p)
{
- switch (p->family)
- {
- case AF_INET:
- *(uint8_t *)buf = PIM_MSG_ADDRESS_FAMILY_IPV4; /* notice: AF_INET != PIM_MSG_ADDRESS_FAMILY_IPV4 */
- ++buf;
- *(uint8_t *)buf = 0; /* ucast IPv4 native encoding type (RFC 4601: 4.9.1) */
- ++buf;
- memcpy (buf, &p->u.prefix4, sizeof (struct in_addr));
- return ucast_ipv4_encoding_len;
- break;
- case AF_INET6:
- *(uint8_t *)buf = PIM_MSG_ADDRESS_FAMILY_IPV6;
- ++buf;
- *(uint8_t *)buf = 0;
- ++buf;
- memcpy (buf, &p->u.prefix6, sizeof (struct in6_addr));
- return ucast_ipv6_encoding_len;
- break;
- default:
- return 0;
- break;
- }
+ switch (p->family) {
+ case AF_INET:
+ *(uint8_t *)buf =
+ PIM_MSG_ADDRESS_FAMILY_IPV4; /* notice: AF_INET !=
+ PIM_MSG_ADDRESS_FAMILY_IPV4
+ */
+ ++buf;
+ *(uint8_t *)buf = 0; /* ucast IPv4 native encoding type (RFC
+ 4601: 4.9.1) */
+ ++buf;
+ memcpy(buf, &p->u.prefix4, sizeof(struct in_addr));
+ return ucast_ipv4_encoding_len;
+ break;
+ case AF_INET6:
+ *(uint8_t *)buf = PIM_MSG_ADDRESS_FAMILY_IPV6;
+ ++buf;
+ *(uint8_t *)buf = 0;
+ ++buf;
+ memcpy(buf, &p->u.prefix6, sizeof(struct in6_addr));
+ return ucast_ipv6_encoding_len;
+ break;
+ default:
+ return 0;
+ break;
+ }
}
#define group_ipv4_encoding_len (4 + sizeof (struct in_addr))
@@ -194,614 +191,604 @@ pim_encode_addr_ucast (uint8_t *buf, struct prefix *p)
* Group multicast Address
* Contains the group address.
*/
-int
-pim_encode_addr_group (uint8_t *buf, afi_t afi, int bidir, int scope, struct in_addr group)
+int pim_encode_addr_group(uint8_t *buf, afi_t afi, int bidir, int scope,
+ struct in_addr group)
{
- uint8_t flags = 0;
-
- flags |= bidir << 8;
- flags |= scope;
-
- switch (afi)
- {
- case AFI_IP:
- *(uint8_t *)buf = PIM_MSG_ADDRESS_FAMILY_IPV4;
- ++buf;
- *(uint8_t *)buf = 0;
- ++buf;
- *(uint8_t *)buf = flags;
- ++buf;
- *(uint8_t *)buf = 32;
- ++buf;
- memcpy (buf, &group, sizeof (struct in_addr));
- return group_ipv4_encoding_len;
- break;
- default:
- return 0;
- break;
- }
+ uint8_t flags = 0;
+
+ flags |= bidir << 8;
+ flags |= scope;
+
+ switch (afi) {
+ case AFI_IP:
+ *(uint8_t *)buf = PIM_MSG_ADDRESS_FAMILY_IPV4;
+ ++buf;
+ *(uint8_t *)buf = 0;
+ ++buf;
+ *(uint8_t *)buf = flags;
+ ++buf;
+ *(uint8_t *)buf = 32;
+ ++buf;
+ memcpy(buf, &group, sizeof(struct in_addr));
+ return group_ipv4_encoding_len;
+ break;
+ default:
+ return 0;
+ break;
+ }
}
-uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf,
- const uint8_t *buf_pastend,
- struct list *ifconnected,
- int family)
+uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf, const uint8_t *buf_pastend,
+ struct list *ifconnected, int family)
{
- struct listnode *node;
- uint16_t option_len = 0;
- uint8_t *curr;
- size_t uel;
-
- node = listhead(ifconnected);
-
- /* Empty address list ? */
- if (!node) {
- return buf;
- }
-
- if (family == AF_INET)
- uel = ucast_ipv4_encoding_len;
- else
- uel = ucast_ipv6_encoding_len;
-
- /* Scan secondary address list */
- curr = buf + 4; /* skip T and L */
- for (; node; node = listnextnode(node)) {
- struct connected *ifc = listgetdata(node);
- struct prefix *p = ifc->address;
- int l_encode;
-
- if (!CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY))
- continue;
-
- if ((curr + uel) > buf_pastend)
- return 0;
-
- if (p->family != family)
- continue;
-
- l_encode = pim_encode_addr_ucast (curr, p);
- curr += l_encode;
- option_len += l_encode;
- }
-
- if (PIM_DEBUG_PIM_TRACE_DETAIL) {
- zlog_debug("%s: number of encoded secondary unicast IPv4 addresses: %zu",
- __PRETTY_FUNCTION__,
- option_len / uel);
- }
-
- if (option_len < 1) {
- /* Empty secondary unicast IPv4 address list */
- return buf;
- }
-
- /*
- * Write T and L
- */
- *(uint16_t *) buf = htons(PIM_MSG_OPTION_TYPE_ADDRESS_LIST);
- *(uint16_t *) (buf + 2) = htons(option_len);
-
- return curr;
+ struct listnode *node;
+ uint16_t option_len = 0;
+ uint8_t *curr;
+ size_t uel;
+
+ node = listhead(ifconnected);
+
+ /* Empty address list ? */
+ if (!node) {
+ return buf;
+ }
+
+ if (family == AF_INET)
+ uel = ucast_ipv4_encoding_len;
+ else
+ uel = ucast_ipv6_encoding_len;
+
+ /* Scan secondary address list */
+ curr = buf + 4; /* skip T and L */
+ for (; node; node = listnextnode(node)) {
+ struct connected *ifc = listgetdata(node);
+ struct prefix *p = ifc->address;
+ int l_encode;
+
+ if (!CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY))
+ continue;
+
+ if ((curr + uel) > buf_pastend)
+ return 0;
+
+ if (p->family != family)
+ continue;
+
+ l_encode = pim_encode_addr_ucast(curr, p);
+ curr += l_encode;
+ option_len += l_encode;
+ }
+
+ if (PIM_DEBUG_PIM_TRACE_DETAIL) {
+ zlog_debug(
+ "%s: number of encoded secondary unicast IPv4 addresses: %zu",
+ __PRETTY_FUNCTION__, option_len / uel);
+ }
+
+ if (option_len < 1) {
+ /* Empty secondary unicast IPv4 address list */
+ return buf;
+ }
+
+ /*
+ * Write T and L
+ */
+ *(uint16_t *)buf = htons(PIM_MSG_OPTION_TYPE_ADDRESS_LIST);
+ *(uint16_t *)(buf + 2) = htons(option_len);
+
+ return curr;
}
static int check_tlv_length(const char *label, const char *tlv_name,
const char *ifname, struct in_addr src_addr,
int correct_len, int option_len)
{
- if (option_len != correct_len) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_warn("%s: PIM hello %s TLV with incorrect value size=%d correct=%d from %s on interface %s",
- label, tlv_name,
- option_len, correct_len,
- src_str, ifname);
- return -1;
- }
-
- return 0;
+ if (option_len != correct_len) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ zlog_warn(
+ "%s: PIM hello %s TLV with incorrect value size=%d correct=%d from %s on interface %s",
+ label, tlv_name, option_len, correct_len, src_str,
+ ifname);
+ return -1;
+ }
+
+ return 0;
}
-static void check_tlv_redefinition_uint16(const char *label, const char *tlv_name,
- const char *ifname, struct in_addr src_addr,
- pim_hello_options options,
- pim_hello_options opt_mask,
- uint16_t new, uint16_t old)
+static void check_tlv_redefinition_uint16(
+ const char *label, const char *tlv_name, const char *ifname,
+ struct in_addr src_addr, pim_hello_options options,
+ pim_hello_options opt_mask, uint16_t new, uint16_t old)
{
- if (PIM_OPTION_IS_SET(options, opt_mask)) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_warn("%s: PIM hello TLV redefined %s=%u old=%u from %s on interface %s",
- label, tlv_name,
- new, old,
- src_str, ifname);
- }
+ if (PIM_OPTION_IS_SET(options, opt_mask)) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ zlog_warn(
+ "%s: PIM hello TLV redefined %s=%u old=%u from %s on interface %s",
+ label, tlv_name, new, old, src_str, ifname);
+ }
}
-static void check_tlv_redefinition_uint32(const char *label, const char *tlv_name,
- const char *ifname, struct in_addr src_addr,
- pim_hello_options options,
- pim_hello_options opt_mask,
- uint32_t new, uint32_t old)
+static void check_tlv_redefinition_uint32(
+ const char *label, const char *tlv_name, const char *ifname,
+ struct in_addr src_addr, pim_hello_options options,
+ pim_hello_options opt_mask, uint32_t new, uint32_t old)
{
- if (PIM_OPTION_IS_SET(options, opt_mask)) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_warn("%s: PIM hello TLV redefined %s=%u old=%u from %s on interface %s",
- label, tlv_name,
- new, old,
- src_str, ifname);
- }
+ if (PIM_OPTION_IS_SET(options, opt_mask)) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ zlog_warn(
+ "%s: PIM hello TLV redefined %s=%u old=%u from %s on interface %s",
+ label, tlv_name, new, old, src_str, ifname);
+ }
}
-static void check_tlv_redefinition_uint32_hex(const char *label, const char *tlv_name,
- const char *ifname, struct in_addr src_addr,
- pim_hello_options options,
- pim_hello_options opt_mask,
- uint32_t new, uint32_t old)
+static void check_tlv_redefinition_uint32_hex(
+ const char *label, const char *tlv_name, const char *ifname,
+ struct in_addr src_addr, pim_hello_options options,
+ pim_hello_options opt_mask, uint32_t new, uint32_t old)
{
- if (PIM_OPTION_IS_SET(options, opt_mask)) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_warn("%s: PIM hello TLV redefined %s=%08x old=%08x from %s on interface %s",
- label, tlv_name,
- new, old,
- src_str, ifname);
- }
+ if (PIM_OPTION_IS_SET(options, opt_mask)) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ zlog_warn(
+ "%s: PIM hello TLV redefined %s=%08x old=%08x from %s on interface %s",
+ label, tlv_name, new, old, src_str, ifname);
+ }
}
int pim_tlv_parse_holdtime(const char *ifname, struct in_addr src_addr,
pim_hello_options *hello_options,
- uint16_t *hello_option_holdtime,
- uint16_t option_len,
- const uint8_t *tlv_curr)
+ uint16_t *hello_option_holdtime, uint16_t option_len,
+ const uint8_t *tlv_curr)
{
- const char *label = "holdtime";
-
- if (check_tlv_length(__PRETTY_FUNCTION__, label,
- ifname, src_addr,
- sizeof(uint16_t), option_len)) {
- return -1;
- }
-
- check_tlv_redefinition_uint16(__PRETTY_FUNCTION__, label,
- ifname, src_addr,
- *hello_options, PIM_OPTION_MASK_HOLDTIME,
- PIM_TLV_GET_HOLDTIME(tlv_curr),
- *hello_option_holdtime);
-
- PIM_OPTION_SET(*hello_options, PIM_OPTION_MASK_HOLDTIME);
-
- *hello_option_holdtime = PIM_TLV_GET_HOLDTIME(tlv_curr);
-
- return 0;
+ const char *label = "holdtime";
+
+ if (check_tlv_length(__PRETTY_FUNCTION__, label, ifname, src_addr,
+ sizeof(uint16_t), option_len)) {
+ return -1;
+ }
+
+ check_tlv_redefinition_uint16(
+ __PRETTY_FUNCTION__, label, ifname, src_addr, *hello_options,
+ PIM_OPTION_MASK_HOLDTIME, PIM_TLV_GET_HOLDTIME(tlv_curr),
+ *hello_option_holdtime);
+
+ PIM_OPTION_SET(*hello_options, PIM_OPTION_MASK_HOLDTIME);
+
+ *hello_option_holdtime = PIM_TLV_GET_HOLDTIME(tlv_curr);
+
+ return 0;
}
int pim_tlv_parse_lan_prune_delay(const char *ifname, struct in_addr src_addr,
pim_hello_options *hello_options,
uint16_t *hello_option_propagation_delay,
uint16_t *hello_option_override_interval,
- uint16_t option_len,
- const uint8_t *tlv_curr)
+ uint16_t option_len, const uint8_t *tlv_curr)
{
- if (check_tlv_length(__PRETTY_FUNCTION__, "lan_prune_delay",
- ifname, src_addr,
- sizeof(uint32_t), option_len)) {
- return -1;
- }
-
- check_tlv_redefinition_uint16(__PRETTY_FUNCTION__, "propagation_delay",
- ifname, src_addr,
- *hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY,
- PIM_TLV_GET_PROPAGATION_DELAY(tlv_curr),
- *hello_option_propagation_delay);
-
- PIM_OPTION_SET(*hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY);
-
- *hello_option_propagation_delay = PIM_TLV_GET_PROPAGATION_DELAY(tlv_curr);
- if (PIM_TLV_GET_CAN_DISABLE_JOIN_SUPPRESSION(tlv_curr)) {
- PIM_OPTION_SET(*hello_options, PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION);
- }
- else {
- PIM_OPTION_UNSET(*hello_options, PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION);
- }
- ++tlv_curr;
- ++tlv_curr;
- *hello_option_override_interval = PIM_TLV_GET_OVERRIDE_INTERVAL(tlv_curr);
-
- return 0;
+ if (check_tlv_length(__PRETTY_FUNCTION__, "lan_prune_delay", ifname,
+ src_addr, sizeof(uint32_t), option_len)) {
+ return -1;
+ }
+
+ check_tlv_redefinition_uint16(__PRETTY_FUNCTION__, "propagation_delay",
+ ifname, src_addr, *hello_options,
+ PIM_OPTION_MASK_LAN_PRUNE_DELAY,
+ PIM_TLV_GET_PROPAGATION_DELAY(tlv_curr),
+ *hello_option_propagation_delay);
+
+ PIM_OPTION_SET(*hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY);
+
+ *hello_option_propagation_delay =
+ PIM_TLV_GET_PROPAGATION_DELAY(tlv_curr);
+ if (PIM_TLV_GET_CAN_DISABLE_JOIN_SUPPRESSION(tlv_curr)) {
+ PIM_OPTION_SET(*hello_options,
+ PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION);
+ } else {
+ PIM_OPTION_UNSET(*hello_options,
+ PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION);
+ }
+ ++tlv_curr;
+ ++tlv_curr;
+ *hello_option_override_interval =
+ PIM_TLV_GET_OVERRIDE_INTERVAL(tlv_curr);
+
+ return 0;
}
int pim_tlv_parse_dr_priority(const char *ifname, struct in_addr src_addr,
pim_hello_options *hello_options,
uint32_t *hello_option_dr_priority,
- uint16_t option_len,
- const uint8_t *tlv_curr)
+ uint16_t option_len, const uint8_t *tlv_curr)
{
- const char *label = "dr_priority";
-
- if (check_tlv_length(__PRETTY_FUNCTION__, label,
- ifname, src_addr,
- sizeof(uint32_t), option_len)) {
- return -1;
- }
-
- check_tlv_redefinition_uint32(__PRETTY_FUNCTION__, label,
- ifname, src_addr,
- *hello_options, PIM_OPTION_MASK_DR_PRIORITY,
- PIM_TLV_GET_DR_PRIORITY(tlv_curr),
- *hello_option_dr_priority);
-
- PIM_OPTION_SET(*hello_options, PIM_OPTION_MASK_DR_PRIORITY);
-
- *hello_option_dr_priority = PIM_TLV_GET_DR_PRIORITY(tlv_curr);
-
- return 0;
+ const char *label = "dr_priority";
+
+ if (check_tlv_length(__PRETTY_FUNCTION__, label, ifname, src_addr,
+ sizeof(uint32_t), option_len)) {
+ return -1;
+ }
+
+ check_tlv_redefinition_uint32(
+ __PRETTY_FUNCTION__, label, ifname, src_addr, *hello_options,
+ PIM_OPTION_MASK_DR_PRIORITY, PIM_TLV_GET_DR_PRIORITY(tlv_curr),
+ *hello_option_dr_priority);
+
+ PIM_OPTION_SET(*hello_options, PIM_OPTION_MASK_DR_PRIORITY);
+
+ *hello_option_dr_priority = PIM_TLV_GET_DR_PRIORITY(tlv_curr);
+
+ return 0;
}
int pim_tlv_parse_generation_id(const char *ifname, struct in_addr src_addr,
pim_hello_options *hello_options,
uint32_t *hello_option_generation_id,
- uint16_t option_len,
- const uint8_t *tlv_curr)
+ uint16_t option_len, const uint8_t *tlv_curr)
{
- const char *label = "generation_id";
-
- if (check_tlv_length(__PRETTY_FUNCTION__, label,
- ifname, src_addr,
- sizeof(uint32_t), option_len)) {
- return -1;
- }
-
- check_tlv_redefinition_uint32_hex(__PRETTY_FUNCTION__, label,
- ifname, src_addr,
- *hello_options, PIM_OPTION_MASK_GENERATION_ID,
- PIM_TLV_GET_GENERATION_ID(tlv_curr),
- *hello_option_generation_id);
-
- PIM_OPTION_SET(*hello_options, PIM_OPTION_MASK_GENERATION_ID);
-
- *hello_option_generation_id = PIM_TLV_GET_GENERATION_ID(tlv_curr);
-
- return 0;
+ const char *label = "generation_id";
+
+ if (check_tlv_length(__PRETTY_FUNCTION__, label, ifname, src_addr,
+ sizeof(uint32_t), option_len)) {
+ return -1;
+ }
+
+ check_tlv_redefinition_uint32_hex(__PRETTY_FUNCTION__, label, ifname,
+ src_addr, *hello_options,
+ PIM_OPTION_MASK_GENERATION_ID,
+ PIM_TLV_GET_GENERATION_ID(tlv_curr),
+ *hello_option_generation_id);
+
+ PIM_OPTION_SET(*hello_options, PIM_OPTION_MASK_GENERATION_ID);
+
+ *hello_option_generation_id = PIM_TLV_GET_GENERATION_ID(tlv_curr);
+
+ return 0;
}
-int
-pim_parse_addr_ucast (struct prefix *p,
- const uint8_t *buf,
- int buf_size)
+int pim_parse_addr_ucast(struct prefix *p, const uint8_t *buf, int buf_size)
{
- const int ucast_encoding_min_len = 3; /* 1 family + 1 type + 1 addr */
- const uint8_t *addr;
- const uint8_t *pastend;
- int family;
- int type;
-
- if (buf_size < ucast_encoding_min_len) {
- zlog_warn("%s: unicast address encoding overflow: left=%d needed=%d",
- __PRETTY_FUNCTION__,
- buf_size, ucast_encoding_min_len);
- return -1;
- }
-
- addr = buf;
- pastend = buf + buf_size;
-
- family = *addr++;
- type = *addr++;
-
- if (type) {
- zlog_warn("%s: unknown unicast address encoding type=%d",
- __PRETTY_FUNCTION__,
- type);
- return -2;
- }
-
- switch (family) {
- case PIM_MSG_ADDRESS_FAMILY_IPV4:
- if ((addr + sizeof(struct in_addr)) > pastend) {
- zlog_warn("%s: IPv4 unicast address overflow: left=%zd needed=%zu",
- __PRETTY_FUNCTION__,
- pastend - addr, sizeof(struct in_addr));
- return -3;
- }
-
- p->family = AF_INET; /* notice: AF_INET != PIM_MSG_ADDRESS_FAMILY_IPV4 */
- memcpy(&p->u.prefix4, addr, sizeof(struct in_addr));
- p->prefixlen = IPV4_MAX_PREFIXLEN;
- addr += sizeof(struct in_addr);
-
- break;
- case PIM_MSG_ADDRESS_FAMILY_IPV6:
- if ((addr + sizeof(struct in6_addr)) > pastend) {
- zlog_warn ("%s: IPv6 unicast address overflow: left=%zd needed %zu",
- __PRETTY_FUNCTION__,
- pastend - addr, sizeof(struct in6_addr));
- return -3;
- }
-
- p->family = AF_INET6;
- p->prefixlen = IPV6_MAX_PREFIXLEN;
- memcpy(&p->u.prefix6, addr, sizeof(struct in6_addr));
- addr += sizeof(struct in6_addr);
-
- break;
- default:
- {
- zlog_warn("%s: unknown unicast address encoding family=%d from",
- __PRETTY_FUNCTION__,
- family);
- return -4;
- }
- }
-
- return addr - buf;
+ const int ucast_encoding_min_len = 3; /* 1 family + 1 type + 1 addr */
+ const uint8_t *addr;
+ const uint8_t *pastend;
+ int family;
+ int type;
+
+ if (buf_size < ucast_encoding_min_len) {
+ zlog_warn(
+ "%s: unicast address encoding overflow: left=%d needed=%d",
+ __PRETTY_FUNCTION__, buf_size, ucast_encoding_min_len);
+ return -1;
+ }
+
+ addr = buf;
+ pastend = buf + buf_size;
+
+ family = *addr++;
+ type = *addr++;
+
+ if (type) {
+ zlog_warn("%s: unknown unicast address encoding type=%d",
+ __PRETTY_FUNCTION__, type);
+ return -2;
+ }
+
+ switch (family) {
+ case PIM_MSG_ADDRESS_FAMILY_IPV4:
+ if ((addr + sizeof(struct in_addr)) > pastend) {
+ zlog_warn(
+ "%s: IPv4 unicast address overflow: left=%zd needed=%zu",
+ __PRETTY_FUNCTION__, pastend - addr,
+ sizeof(struct in_addr));
+ return -3;
+ }
+
+ p->family = AF_INET; /* notice: AF_INET !=
+ PIM_MSG_ADDRESS_FAMILY_IPV4 */
+ memcpy(&p->u.prefix4, addr, sizeof(struct in_addr));
+ p->prefixlen = IPV4_MAX_PREFIXLEN;
+ addr += sizeof(struct in_addr);
+
+ break;
+ case PIM_MSG_ADDRESS_FAMILY_IPV6:
+ if ((addr + sizeof(struct in6_addr)) > pastend) {
+ zlog_warn(
+ "%s: IPv6 unicast address overflow: left=%zd needed %zu",
+ __PRETTY_FUNCTION__, pastend - addr,
+ sizeof(struct in6_addr));
+ return -3;
+ }
+
+ p->family = AF_INET6;
+ p->prefixlen = IPV6_MAX_PREFIXLEN;
+ memcpy(&p->u.prefix6, addr, sizeof(struct in6_addr));
+ addr += sizeof(struct in6_addr);
+
+ break;
+ default: {
+ zlog_warn("%s: unknown unicast address encoding family=%d from",
+ __PRETTY_FUNCTION__, family);
+ return -4;
+ }
+ }
+
+ return addr - buf;
}
-int
-pim_parse_addr_group (struct prefix_sg *sg,
- const uint8_t *buf,
- int buf_size)
+int pim_parse_addr_group(struct prefix_sg *sg, const uint8_t *buf, int buf_size)
{
- const int grp_encoding_min_len = 4; /* 1 family + 1 type + 1 reserved + 1 addr */
- const uint8_t *addr;
- const uint8_t *pastend;
- int family;
- int type;
- int mask_len;
-
- if (buf_size < grp_encoding_min_len) {
- zlog_warn("%s: group address encoding overflow: left=%d needed=%d",
- __PRETTY_FUNCTION__,
- buf_size, grp_encoding_min_len);
- return -1;
- }
-
- addr = buf;
- pastend = buf + buf_size;
-
- family = *addr++;
- type = *addr++;
- //++addr;
- ++addr; /* skip b_reserved_z fields */
- mask_len = *addr++;
-
- switch (family) {
- case PIM_MSG_ADDRESS_FAMILY_IPV4:
- if (type) {
- zlog_warn("%s: unknown group address encoding type=%d from",
- __PRETTY_FUNCTION__, type);
- return -2;
- }
-
- if ((addr + sizeof(struct in_addr)) > pastend) {
- zlog_warn("%s: IPv4 group address overflow: left=%zd needed=%zu from",
- __PRETTY_FUNCTION__,
- pastend - addr, sizeof(struct in_addr));
- return -3;
- }
-
- memcpy(&sg->grp.s_addr, addr, sizeof(struct in_addr));
-
- addr += sizeof(struct in_addr);
-
- break;
- default:
- {
- zlog_warn("%s: unknown group address encoding family=%d mask_len=%d from",
- __PRETTY_FUNCTION__, family, mask_len);
- return -4;
- }
- }
-
- return addr - buf;
+ const int grp_encoding_min_len =
+ 4; /* 1 family + 1 type + 1 reserved + 1 addr */
+ const uint8_t *addr;
+ const uint8_t *pastend;
+ int family;
+ int type;
+ int mask_len;
+
+ if (buf_size < grp_encoding_min_len) {
+ zlog_warn(
+ "%s: group address encoding overflow: left=%d needed=%d",
+ __PRETTY_FUNCTION__, buf_size, grp_encoding_min_len);
+ return -1;
+ }
+
+ addr = buf;
+ pastend = buf + buf_size;
+
+ family = *addr++;
+ type = *addr++;
+ //++addr;
+ ++addr; /* skip b_reserved_z fields */
+ mask_len = *addr++;
+
+ switch (family) {
+ case PIM_MSG_ADDRESS_FAMILY_IPV4:
+ if (type) {
+ zlog_warn(
+ "%s: unknown group address encoding type=%d from",
+ __PRETTY_FUNCTION__, type);
+ return -2;
+ }
+
+ if ((addr + sizeof(struct in_addr)) > pastend) {
+ zlog_warn(
+ "%s: IPv4 group address overflow: left=%zd needed=%zu from",
+ __PRETTY_FUNCTION__, pastend - addr,
+ sizeof(struct in_addr));
+ return -3;
+ }
+
+ memcpy(&sg->grp.s_addr, addr, sizeof(struct in_addr));
+
+ addr += sizeof(struct in_addr);
+
+ break;
+ default: {
+ zlog_warn(
+ "%s: unknown group address encoding family=%d mask_len=%d from",
+ __PRETTY_FUNCTION__, family, mask_len);
+ return -4;
+ }
+ }
+
+ return addr - buf;
}
-int
-pim_parse_addr_source(struct prefix_sg *sg,
- uint8_t *flags,
- const uint8_t *buf,
- int buf_size)
+int pim_parse_addr_source(struct prefix_sg *sg, uint8_t *flags,
+ const uint8_t *buf, int buf_size)
{
- const int src_encoding_min_len = 4; /* 1 family + 1 type + 1 reserved + 1 addr */
- const uint8_t *addr;
- const uint8_t *pastend;
- int family;
- int type;
- int mask_len;
-
- if (buf_size < src_encoding_min_len) {
- zlog_warn("%s: source address encoding overflow: left=%d needed=%d",
- __PRETTY_FUNCTION__,
- buf_size, src_encoding_min_len);
- return -1;
- }
-
- addr = buf;
- pastend = buf + buf_size;
-
- family = *addr++;
- type = *addr++;
- *flags = *addr++;
- mask_len = *addr++;
-
- if (type) {
- zlog_warn("%s: unknown source address encoding type=%d: %02x%02x%02x%02x%02x%02x%02x%02x",
- __PRETTY_FUNCTION__,
- type,
- buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
- return -2;
- }
-
- switch (family) {
- case PIM_MSG_ADDRESS_FAMILY_IPV4:
- if ((addr + sizeof(struct in_addr)) > pastend) {
- zlog_warn("%s: IPv4 source address overflow: left=%zd needed=%zu",
- __PRETTY_FUNCTION__,
- pastend - addr, sizeof(struct in_addr));
- return -3;
- }
-
- memcpy(&sg->src, addr, sizeof(struct in_addr));
-
- /*
- 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 (mask_len != 32) {
- zlog_warn("%s: IPv4 bad source address mask: %d",
- __PRETTY_FUNCTION__, mask_len);
- return -4;
- }
-
- addr += sizeof(struct in_addr);
-
- break;
- default:
- {
- zlog_warn("%s: unknown source address encoding family=%d: %02x%02x%02x%02x%02x%02x%02x%02x",
- __PRETTY_FUNCTION__,
- family,
- buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
- return -5;
- }
- }
-
- return addr - buf;
-}
+ const int src_encoding_min_len =
+ 4; /* 1 family + 1 type + 1 reserved + 1 addr */
+ const uint8_t *addr;
+ const uint8_t *pastend;
+ int family;
+ int type;
+ int mask_len;
+
+ if (buf_size < src_encoding_min_len) {
+ zlog_warn(
+ "%s: source address encoding overflow: left=%d needed=%d",
+ __PRETTY_FUNCTION__, buf_size, src_encoding_min_len);
+ return -1;
+ }
+
+ addr = buf;
+ pastend = buf + buf_size;
+
+ family = *addr++;
+ type = *addr++;
+ *flags = *addr++;
+ mask_len = *addr++;
-#define FREE_ADDR_LIST(hello_option_addr_list) \
-{ \
- if (hello_option_addr_list) { \
- list_delete(hello_option_addr_list); \
- hello_option_addr_list = 0; \
- } \
+ if (type) {
+ zlog_warn(
+ "%s: unknown source address encoding type=%d: %02x%02x%02x%02x%02x%02x%02x%02x",
+ __PRETTY_FUNCTION__, type, buf[0], buf[1], buf[2],
+ buf[3], buf[4], buf[5], buf[6], buf[7]);
+ return -2;
+ }
+
+ switch (family) {
+ case PIM_MSG_ADDRESS_FAMILY_IPV4:
+ if ((addr + sizeof(struct in_addr)) > pastend) {
+ zlog_warn(
+ "%s: IPv4 source address overflow: left=%zd needed=%zu",
+ __PRETTY_FUNCTION__, pastend - addr,
+ sizeof(struct in_addr));
+ return -3;
+ }
+
+ memcpy(&sg->src, addr, sizeof(struct in_addr));
+
+ /*
+ 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 (mask_len != 32) {
+ zlog_warn("%s: IPv4 bad source address mask: %d",
+ __PRETTY_FUNCTION__, mask_len);
+ return -4;
+ }
+
+ addr += sizeof(struct in_addr);
+
+ break;
+ default: {
+ zlog_warn(
+ "%s: unknown source address encoding family=%d: %02x%02x%02x%02x%02x%02x%02x%02x",
+ __PRETTY_FUNCTION__, family, buf[0], buf[1], buf[2],
+ buf[3], buf[4], buf[5], buf[6], buf[7]);
+ return -5;
+ }
+ }
+
+ return addr - buf;
}
+#define FREE_ADDR_LIST(hello_option_addr_list) \
+ { \
+ if (hello_option_addr_list) { \
+ list_delete(hello_option_addr_list); \
+ hello_option_addr_list = 0; \
+ } \
+ }
+
int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr,
pim_hello_options *hello_options,
struct list **hello_option_addr_list,
- uint16_t option_len,
- const uint8_t *tlv_curr)
+ uint16_t option_len, const uint8_t *tlv_curr)
{
- const uint8_t *addr;
- const uint8_t *pastend;
-
- zassert(hello_option_addr_list);
-
- /*
- Scan addr list
- */
- addr = tlv_curr;
- pastend = tlv_curr + option_len;
- while (addr < pastend) {
- struct prefix tmp;
- int addr_offset;
-
- /*
- Parse ucast addr
- */
- addr_offset = pim_parse_addr_ucast(&tmp, addr, pastend - addr);
- if (addr_offset < 1) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_warn("%s: pim_parse_addr_ucast() failure: from %s on %s",
- __PRETTY_FUNCTION__,
- src_str, ifname);
- FREE_ADDR_LIST(*hello_option_addr_list);
- return -1;
- }
- addr += addr_offset;
-
- /*
- Debug
- */
- if (PIM_DEBUG_PIM_TRACE) {
- switch (tmp.family) {
- case AF_INET:
- {
- char addr_str[INET_ADDRSTRLEN];
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<addr?>", tmp.u.prefix4, addr_str, sizeof(addr_str));
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_debug("%s: PIM hello TLV option: list_old_size=%d IPv4 address %s from %s on %s",
- __PRETTY_FUNCTION__,
- *hello_option_addr_list ?
- ((int) listcount(*hello_option_addr_list)) : -1,
- addr_str, src_str, ifname);
- }
- break;
- case AF_INET6:
- break;
- default:
- {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_debug("%s: PIM hello TLV option: list_old_size=%d UNKNOWN address family from %s on %s",
- __PRETTY_FUNCTION__,
- *hello_option_addr_list ?
- ((int) listcount(*hello_option_addr_list)) : -1,
- src_str, ifname);
- }
- }
- }
-
- /*
- Exclude neighbor's primary address if incorrectly included in
- the secondary address list
- */
- if (tmp.family == AF_INET) {
- if (tmp.u.prefix4.s_addr == src_addr.s_addr) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_warn("%s: ignoring primary address in secondary list from %s on %s",
- __PRETTY_FUNCTION__,
- src_str, ifname);
- continue;
- }
- }
-
- /*
- Allocate list if needed
- */
- if (!*hello_option_addr_list) {
- *hello_option_addr_list = list_new();
- if (!*hello_option_addr_list) {
- zlog_err("%s %s: failure: hello_option_addr_list=list_new()",
- __FILE__, __PRETTY_FUNCTION__);
- return -2;
- }
- (*hello_option_addr_list)->del = (void (*)(void *)) prefix_free;
- }
-
- /*
- Attach addr to list
- */
- {
- struct prefix *p;
- p = prefix_new();
- if (!p) {
- zlog_err("%s %s: failure: prefix_new()",
- __FILE__, __PRETTY_FUNCTION__);
- FREE_ADDR_LIST(*hello_option_addr_list);
- return -3;
- }
- prefix_copy(p, &tmp);
- listnode_add(*hello_option_addr_list, p);
- }
-
- } /* while (addr < pastend) */
-
- /*
- Mark hello option
- */
- PIM_OPTION_SET(*hello_options, PIM_OPTION_MASK_ADDRESS_LIST);
-
- return 0;
+ const uint8_t *addr;
+ const uint8_t *pastend;
+
+ zassert(hello_option_addr_list);
+
+ /*
+ Scan addr list
+ */
+ addr = tlv_curr;
+ pastend = tlv_curr + option_len;
+ while (addr < pastend) {
+ struct prefix tmp;
+ int addr_offset;
+
+ /*
+ Parse ucast addr
+ */
+ addr_offset = pim_parse_addr_ucast(&tmp, addr, pastend - addr);
+ if (addr_offset < 1) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str,
+ sizeof(src_str));
+ zlog_warn(
+ "%s: pim_parse_addr_ucast() failure: from %s on %s",
+ __PRETTY_FUNCTION__, src_str, ifname);
+ FREE_ADDR_LIST(*hello_option_addr_list);
+ return -1;
+ }
+ addr += addr_offset;
+
+ /*
+ Debug
+ */
+ if (PIM_DEBUG_PIM_TRACE) {
+ switch (tmp.family) {
+ case AF_INET: {
+ char addr_str[INET_ADDRSTRLEN];
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", tmp.u.prefix4,
+ addr_str, sizeof(addr_str));
+ pim_inet4_dump("<src?>", src_addr, src_str,
+ sizeof(src_str));
+ zlog_debug(
+ "%s: PIM hello TLV option: list_old_size=%d IPv4 address %s from %s on %s",
+ __PRETTY_FUNCTION__,
+ *hello_option_addr_list
+ ? ((int)listcount(
+ *hello_option_addr_list))
+ : -1,
+ addr_str, src_str, ifname);
+ } break;
+ case AF_INET6:
+ break;
+ default: {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str,
+ sizeof(src_str));
+ zlog_debug(
+ "%s: PIM hello TLV option: list_old_size=%d UNKNOWN address family from %s on %s",
+ __PRETTY_FUNCTION__,
+ *hello_option_addr_list
+ ? ((int)listcount(
+ *hello_option_addr_list))
+ : -1,
+ src_str, ifname);
+ }
+ }
+ }
+
+ /*
+ Exclude neighbor's primary address if incorrectly included in
+ the secondary address list
+ */
+ if (tmp.family == AF_INET) {
+ if (tmp.u.prefix4.s_addr == src_addr.s_addr) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", src_addr, src_str,
+ sizeof(src_str));
+ zlog_warn(
+ "%s: ignoring primary address in secondary list from %s on %s",
+ __PRETTY_FUNCTION__, src_str, ifname);
+ continue;
+ }
+ }
+
+ /*
+ Allocate list if needed
+ */
+ if (!*hello_option_addr_list) {
+ *hello_option_addr_list = list_new();
+ if (!*hello_option_addr_list) {
+ zlog_err(
+ "%s %s: failure: hello_option_addr_list=list_new()",
+ __FILE__, __PRETTY_FUNCTION__);
+ return -2;
+ }
+ (*hello_option_addr_list)->del =
+ (void (*)(void *))prefix_free;
+ }
+
+ /*
+ Attach addr to list
+ */
+ {
+ struct prefix *p;
+ p = prefix_new();
+ if (!p) {
+ zlog_err("%s %s: failure: prefix_new()",
+ __FILE__, __PRETTY_FUNCTION__);
+ FREE_ADDR_LIST(*hello_option_addr_list);
+ return -3;
+ }
+ prefix_copy(p, &tmp);
+ listnode_add(*hello_option_addr_list, p);
+ }
+
+ } /* while (addr < pastend) */
+
+ /*
+ Mark hello option
+ */
+ PIM_OPTION_SET(*hello_options, PIM_OPTION_MASK_ADDRESS_LIST);
+
+ return 0;
}
diff --git a/pimd/pim_tlv.h b/pimd/pim_tlv.h
index f80e1fba2..657675b31 100644
--- a/pimd/pim_tlv.h
+++ b/pimd/pim_tlv.h
@@ -64,63 +64,46 @@ typedef uint32_t pim_hello_options;
#define PIM_TLV_MIN_SIZE (PIM_TLV_TYPE_SIZE + PIM_TLV_LENGTH_SIZE)
#define PIM_TLV_OPTION_SIZE(option_len) (PIM_TLV_MIN_SIZE + (option_len))
-uint8_t *pim_tlv_append_uint16(uint8_t *buf,
- const uint8_t *buf_pastend,
- uint16_t option_type,
- uint16_t option_value);
-uint8_t *pim_tlv_append_2uint16(uint8_t *buf,
- const uint8_t *buf_pastend,
- uint16_t option_type,
- uint16_t option_value1,
+uint8_t *pim_tlv_append_uint16(uint8_t *buf, const uint8_t *buf_pastend,
+ uint16_t option_type, uint16_t option_value);
+uint8_t *pim_tlv_append_2uint16(uint8_t *buf, const uint8_t *buf_pastend,
+ uint16_t option_type, uint16_t option_value1,
uint16_t option_value2);
-uint8_t *pim_tlv_append_uint32(uint8_t *buf,
- const uint8_t *buf_pastend,
- uint16_t option_type,
- uint32_t option_value);
-uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf,
- const uint8_t *buf_pastend,
- struct list *ifconnected,
- int family);
+uint8_t *pim_tlv_append_uint32(uint8_t *buf, const uint8_t *buf_pastend,
+ uint16_t option_type, uint32_t option_value);
+uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf, const uint8_t *buf_pastend,
+ struct list *ifconnected, int family);
int pim_tlv_parse_holdtime(const char *ifname, struct in_addr src_addr,
pim_hello_options *hello_options,
- uint16_t *hello_option_holdtime,
- uint16_t option_len,
+ uint16_t *hello_option_holdtime, uint16_t option_len,
const uint8_t *tlv_curr);
int pim_tlv_parse_lan_prune_delay(const char *ifname, struct in_addr src_addr,
pim_hello_options *hello_options,
uint16_t *hello_option_propagation_delay,
uint16_t *hello_option_override_interval,
- uint16_t option_len,
- const uint8_t *tlv_curr);
+ uint16_t option_len, const uint8_t *tlv_curr);
int pim_tlv_parse_dr_priority(const char *ifname, struct in_addr src_addr,
pim_hello_options *hello_options,
uint32_t *hello_option_dr_priority,
- uint16_t option_len,
- const uint8_t *tlv_curr);
+ uint16_t option_len, const uint8_t *tlv_curr);
int pim_tlv_parse_generation_id(const char *ifname, struct in_addr src_addr,
pim_hello_options *hello_options,
uint32_t *hello_option_generation_id,
- uint16_t option_len,
- const uint8_t *tlv_curr);
+ uint16_t option_len, const uint8_t *tlv_curr);
int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr,
pim_hello_options *hello_options,
struct list **hello_option_addr_list,
- uint16_t option_len,
- const uint8_t *tlv_curr);
+ uint16_t option_len, const uint8_t *tlv_curr);
-int pim_encode_addr_ucast (uint8_t *buf, struct prefix *p);
-int pim_encode_addr_group (uint8_t *buf, afi_t afi, int bidir, int scope, struct in_addr group);
+int pim_encode_addr_ucast(uint8_t *buf, struct prefix *p);
+int pim_encode_addr_group(uint8_t *buf, afi_t afi, int bidir, int scope,
+ struct in_addr group);
-int pim_parse_addr_ucast (struct prefix *p,
- const uint8_t *buf,
- int buf_size);
-int pim_parse_addr_group (struct prefix_sg *sg,
- const uint8_t *buf,
- int buf_size);
-int pim_parse_addr_source(struct prefix_sg *sg,
- uint8_t *flags,
- const uint8_t *buf,
- int buf_size);
+int pim_parse_addr_ucast(struct prefix *p, const uint8_t *buf, int buf_size);
+int pim_parse_addr_group(struct prefix_sg *sg, const uint8_t *buf,
+ int buf_size);
+int pim_parse_addr_source(struct prefix_sg *sg, uint8_t *flags,
+ const uint8_t *buf, int buf_size);
#endif /* PIM_TLV_H */
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index 442cb02a1..0ddd04c38 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -59,35 +59,33 @@ struct list *pim_upstream_list = NULL;
struct timer_wheel *pim_upstream_sg_wheel = NULL;
static void join_timer_stop(struct pim_upstream *up);
-static void pim_upstream_update_assert_tracking_desired(struct pim_upstream *up);
+static void
+pim_upstream_update_assert_tracking_desired(struct pim_upstream *up);
/*
* A (*,G) or a (*,*) is going away
* remove the parent pointer from
* those pointing at us
*/
-static void
-pim_upstream_remove_children (struct pim_upstream *up)
+static void pim_upstream_remove_children(struct pim_upstream *up)
{
- struct pim_upstream *child;
-
- if (!up->sources)
- return;
-
- while (!list_isempty (up->sources))
- {
- child = listnode_head (up->sources);
- listnode_delete (up->sources, child);
- if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(child->flags))
- {
- PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(child->flags);
- child = pim_upstream_del(child, __PRETTY_FUNCTION__);
- }
- if (child)
- child->parent = NULL;
- }
- list_delete(up->sources);
- up->sources = NULL;
+ struct pim_upstream *child;
+
+ if (!up->sources)
+ return;
+
+ while (!list_isempty(up->sources)) {
+ child = listnode_head(up->sources);
+ listnode_delete(up->sources, child);
+ if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(child->flags)) {
+ PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(child->flags);
+ child = pim_upstream_del(child, __PRETTY_FUNCTION__);
+ }
+ if (child)
+ child->parent = NULL;
+ }
+ list_delete(up->sources);
+ up->sources = NULL;
}
/*
@@ -95,30 +93,27 @@ pim_upstream_remove_children (struct pim_upstream *up)
* Find the children that would point
* at us.
*/
-static void
-pim_upstream_find_new_children (struct pim_upstream *up)
+static void pim_upstream_find_new_children(struct pim_upstream *up)
{
- struct pim_upstream *child;
- struct listnode *ch_node;
-
- if ((up->sg.src.s_addr != INADDR_ANY) &&
- (up->sg.grp.s_addr != INADDR_ANY))
- return;
-
- if ((up->sg.src.s_addr == INADDR_ANY) &&
- (up->sg.grp.s_addr == INADDR_ANY))
- return;
-
- for (ALL_LIST_ELEMENTS_RO (pim_upstream_list, ch_node, child))
- {
- if ((up->sg.grp.s_addr != INADDR_ANY) &&
- (child->sg.grp.s_addr == up->sg.grp.s_addr) &&
- (child != up))
- {
- child->parent = up;
- listnode_add_sort (up->sources, child);
+ struct pim_upstream *child;
+ struct listnode *ch_node;
+
+ if ((up->sg.src.s_addr != INADDR_ANY)
+ && (up->sg.grp.s_addr != INADDR_ANY))
+ return;
+
+ if ((up->sg.src.s_addr == INADDR_ANY)
+ && (up->sg.grp.s_addr == INADDR_ANY))
+ return;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, ch_node, child)) {
+ if ((up->sg.grp.s_addr != INADDR_ANY)
+ && (child->sg.grp.s_addr == up->sg.grp.s_addr)
+ && (child != up)) {
+ child->parent = up;
+ listnode_add_sort(up->sources, child);
+ }
}
- }
}
/*
@@ -126,218 +121,211 @@ pim_upstream_find_new_children (struct pim_upstream *up)
* If we have a (S,G), find the (*,G)
* If we have a (*,G), find the (*,*)
*/
-static struct pim_upstream *
-pim_upstream_find_parent (struct pim_upstream *child)
+static struct pim_upstream *pim_upstream_find_parent(struct pim_upstream *child)
{
- struct prefix_sg any = child->sg;
- struct pim_upstream *up = NULL;
+ struct prefix_sg any = child->sg;
+ struct pim_upstream *up = NULL;
- // (S,G)
- if ((child->sg.src.s_addr != INADDR_ANY) &&
- (child->sg.grp.s_addr != INADDR_ANY))
- {
- any.src.s_addr = INADDR_ANY;
- up = pim_upstream_find (&any);
+ // (S,G)
+ if ((child->sg.src.s_addr != INADDR_ANY)
+ && (child->sg.grp.s_addr != INADDR_ANY)) {
+ any.src.s_addr = INADDR_ANY;
+ up = pim_upstream_find(&any);
- if (up)
- listnode_add (up->sources, child);
+ if (up)
+ listnode_add(up->sources, child);
- return up;
- }
+ return up;
+ }
- return NULL;
+ return NULL;
}
void pim_upstream_free(struct pim_upstream *up)
{
- XFREE(MTYPE_PIM_UPSTREAM, up);
- up = NULL;
+ XFREE(MTYPE_PIM_UPSTREAM, up);
+ up = NULL;
}
static void upstream_channel_oil_detach(struct pim_upstream *up)
{
- if (up->channel_oil)
- {
- /* Detaching from channel_oil, channel_oil may exist post del,
- but upstream would not keep reference of it
- */
- pim_channel_oil_del(up->channel_oil);
- up->channel_oil = NULL;
- }
+ if (up->channel_oil) {
+ /* Detaching from channel_oil, channel_oil may exist post del,
+ but upstream would not keep reference of it
+ */
+ pim_channel_oil_del(up->channel_oil);
+ up->channel_oil = NULL;
+ }
}
-struct pim_upstream *
-pim_upstream_del(struct pim_upstream *up, const char *name)
+struct pim_upstream *pim_upstream_del(struct pim_upstream *up, const char *name)
{
- bool notify_msdp = false;
- struct prefix nht_p;
-
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s(%s): Delete %s ref count: %d , flags: %d c_oil ref count %d (Pre decrement)",
- __PRETTY_FUNCTION__, name, up->sg_str, up->ref_count, up->flags,
- up->channel_oil->oil_ref_count);
-
- --up->ref_count;
-
- if (up->ref_count >= 1)
- return up;
-
- THREAD_OFF(up->t_ka_timer);
- THREAD_OFF(up->t_rs_timer);
- THREAD_OFF(up->t_msdp_reg_timer);
-
- if (up->join_state == PIM_UPSTREAM_JOINED) {
- pim_jp_agg_single_upstream_send (&up->rpf, up, 0);
-
- if (up->sg.src.s_addr == INADDR_ANY) {
- /* if a (*, G) entry in the joined state is being deleted we
- * need to notify MSDP */
- notify_msdp = true;
- }
- }
-
- join_timer_stop(up);
- pim_jp_agg_upstream_verification (up, false);
- up->rpf.source_nexthop.interface = NULL;
-
- if (up->sg.src.s_addr != INADDR_ANY) {
- wheel_remove_item (pim_upstream_sg_wheel, up);
- notify_msdp = true;
- }
-
- pim_upstream_remove_children (up);
- if (up->sources)
- list_delete (up->sources);
- up->sources = NULL;
- pim_mroute_del (up->channel_oil, __PRETTY_FUNCTION__);
- upstream_channel_oil_detach(up);
-
- list_delete (up->ifchannels);
- up->ifchannels = NULL;
-
- /*
- notice that listnode_delete() can't be moved
- into pim_upstream_free() because the later is
- called by list_delete_all_node()
- */
- if (up->parent && up->parent->sources)
- listnode_delete (up->parent->sources, up);
- up->parent = NULL;
-
- listnode_delete (pim_upstream_list, up);
- hash_release (pim_upstream_hash, up);
-
- if (notify_msdp)
- {
- pim_msdp_up_del (&up->sg);
- }
-
- /* Deregister addr with Zebra NHT */
- nht_p.family = AF_INET;
- nht_p.prefixlen = IPV4_MAX_BITLEN;
- nht_p.u.prefix4 = up->upstream_addr;
- if (PIM_DEBUG_TRACE)
- {
- char buf[PREFIX2STR_BUFFER];
- prefix2str (&nht_p, buf, sizeof (buf));
- zlog_debug ("%s: Deregister upstream %s addr %s with Zebra NHT",
- __PRETTY_FUNCTION__, up->sg_str, buf);
- }
- pim_delete_tracked_nexthop (&nht_p, up, NULL);
-
- pim_upstream_free (up);
-
- return NULL;
+ bool notify_msdp = false;
+ struct prefix nht_p;
+
+ if (PIM_DEBUG_TRACE)
+ zlog_debug(
+ "%s(%s): Delete %s ref count: %d , flags: %d c_oil ref count %d (Pre decrement)",
+ __PRETTY_FUNCTION__, name, up->sg_str, up->ref_count,
+ up->flags, up->channel_oil->oil_ref_count);
+
+ --up->ref_count;
+
+ if (up->ref_count >= 1)
+ return up;
+
+ THREAD_OFF(up->t_ka_timer);
+ THREAD_OFF(up->t_rs_timer);
+ THREAD_OFF(up->t_msdp_reg_timer);
+
+ if (up->join_state == PIM_UPSTREAM_JOINED) {
+ pim_jp_agg_single_upstream_send(&up->rpf, up, 0);
+
+ if (up->sg.src.s_addr == INADDR_ANY) {
+ /* if a (*, G) entry in the joined state is being
+ * deleted we
+ * need to notify MSDP */
+ notify_msdp = true;
+ }
+ }
+
+ join_timer_stop(up);
+ pim_jp_agg_upstream_verification(up, false);
+ up->rpf.source_nexthop.interface = NULL;
+
+ if (up->sg.src.s_addr != INADDR_ANY) {
+ wheel_remove_item(pim_upstream_sg_wheel, up);
+ notify_msdp = true;
+ }
+
+ pim_upstream_remove_children(up);
+ if (up->sources)
+ list_delete(up->sources);
+ up->sources = NULL;
+ pim_mroute_del(up->channel_oil, __PRETTY_FUNCTION__);
+ upstream_channel_oil_detach(up);
+
+ list_delete(up->ifchannels);
+ up->ifchannels = NULL;
+
+ /*
+ notice that listnode_delete() can't be moved
+ into pim_upstream_free() because the later is
+ called by list_delete_all_node()
+ */
+ if (up->parent && up->parent->sources)
+ listnode_delete(up->parent->sources, up);
+ up->parent = NULL;
+
+ listnode_delete(pim_upstream_list, up);
+ hash_release(pim_upstream_hash, up);
+
+ if (notify_msdp) {
+ pim_msdp_up_del(&up->sg);
+ }
+
+ /* Deregister addr with Zebra NHT */
+ nht_p.family = AF_INET;
+ nht_p.prefixlen = IPV4_MAX_BITLEN;
+ nht_p.u.prefix4 = up->upstream_addr;
+ if (PIM_DEBUG_TRACE) {
+ char buf[PREFIX2STR_BUFFER];
+ prefix2str(&nht_p, buf, sizeof(buf));
+ zlog_debug("%s: Deregister upstream %s addr %s with Zebra NHT",
+ __PRETTY_FUNCTION__, up->sg_str, buf);
+ }
+ pim_delete_tracked_nexthop(&nht_p, up, NULL);
+
+ pim_upstream_free(up);
+
+ return NULL;
}
-void
-pim_upstream_send_join (struct pim_upstream *up)
+void pim_upstream_send_join(struct pim_upstream *up)
{
- if (PIM_DEBUG_TRACE) {
- char rpf_str[PREFIX_STRLEN];
- pim_addr_dump("<rpf?>", &up->rpf.rpf_addr, rpf_str, sizeof(rpf_str));
- zlog_debug ("%s: RPF'%s=%s(%s) for Interface %s", __PRETTY_FUNCTION__,
- up->sg_str, rpf_str, pim_upstream_state2str (up->join_state),
- up->rpf.source_nexthop.interface->name);
- if (pim_rpf_addr_is_inaddr_any(&up->rpf)) {
- zlog_debug("%s: can't send join upstream: RPF'%s=%s",
- __PRETTY_FUNCTION__,
- up->sg_str, rpf_str);
- /* warning only */
- }
- }
-
- /* send Join(S,G) to the current upstream neighbor */
- pim_jp_agg_single_upstream_send(&up->rpf, up, 1 /* join */);
+ if (PIM_DEBUG_TRACE) {
+ char rpf_str[PREFIX_STRLEN];
+ pim_addr_dump("<rpf?>", &up->rpf.rpf_addr, rpf_str,
+ sizeof(rpf_str));
+ zlog_debug("%s: RPF'%s=%s(%s) for Interface %s",
+ __PRETTY_FUNCTION__, up->sg_str, rpf_str,
+ pim_upstream_state2str(up->join_state),
+ up->rpf.source_nexthop.interface->name);
+ if (pim_rpf_addr_is_inaddr_any(&up->rpf)) {
+ zlog_debug("%s: can't send join upstream: RPF'%s=%s",
+ __PRETTY_FUNCTION__, up->sg_str, rpf_str);
+ /* warning only */
+ }
+ }
+
+ /* send Join(S,G) to the current upstream neighbor */
+ pim_jp_agg_single_upstream_send(&up->rpf, up, 1 /* join */);
}
static int on_join_timer(struct thread *t)
{
- struct pim_upstream *up;
+ struct pim_upstream *up;
- up = THREAD_ARG(t);
+ up = THREAD_ARG(t);
- /*
- * In the case of a HFR we will not ahve anyone to send this to.
- */
- if (PIM_UPSTREAM_FLAG_TEST_FHR(up->flags))
- return 0;
+ /*
+ * In the case of a HFR we will not ahve anyone to send this to.
+ */
+ if (PIM_UPSTREAM_FLAG_TEST_FHR(up->flags))
+ return 0;
- /*
- * Don't send the join if the outgoing interface is a loopback
- * But since this might change leave the join timer running
- */
- if (up->rpf.source_nexthop.interface &&
- !if_is_loopback (up->rpf.source_nexthop.interface))
- pim_upstream_send_join (up);
+ /*
+ * Don't send the join if the outgoing interface is a loopback
+ * But since this might change leave the join timer running
+ */
+ if (up->rpf.source_nexthop
+ .interface && !if_is_loopback(up->rpf.source_nexthop.interface))
+ pim_upstream_send_join(up);
- join_timer_start(up);
+ join_timer_start(up);
- return 0;
+ return 0;
}
static void join_timer_stop(struct pim_upstream *up)
{
- struct pim_neighbor *nbr;
+ struct pim_neighbor *nbr;
- THREAD_OFF (up->t_join_timer);
+ THREAD_OFF(up->t_join_timer);
- nbr = pim_neighbor_find (up->rpf.source_nexthop.interface,
- up->rpf.rpf_addr.u.prefix4);
+ nbr = pim_neighbor_find(up->rpf.source_nexthop.interface,
+ up->rpf.rpf_addr.u.prefix4);
- if (nbr)
- pim_jp_agg_remove_group (nbr->upstream_jp_agg, up);
+ if (nbr)
+ pim_jp_agg_remove_group(nbr->upstream_jp_agg, up);
- pim_jp_agg_upstream_verification (up, false);
+ pim_jp_agg_upstream_verification(up, false);
}
-void
-join_timer_start(struct pim_upstream *up)
+void join_timer_start(struct pim_upstream *up)
{
- struct pim_neighbor *nbr = NULL;
-
- if (up->rpf.source_nexthop.interface)
- {
- nbr = pim_neighbor_find (up->rpf.source_nexthop.interface,
- up->rpf.rpf_addr.u.prefix4);
-
- if (PIM_DEBUG_PIM_EVENTS) {
- zlog_debug("%s: starting %d sec timer for upstream (S,G)=%s",
- __PRETTY_FUNCTION__,
- qpim_t_periodic,
- up->sg_str);
- }
- }
-
- if (nbr)
- pim_jp_agg_add_group (nbr->upstream_jp_agg, up, 1);
- else
- {
- THREAD_OFF (up->t_join_timer);
- thread_add_timer(master, on_join_timer, up, qpim_t_periodic,
- &up->t_join_timer);
- }
- pim_jp_agg_upstream_verification (up, true);
+ struct pim_neighbor *nbr = NULL;
+
+ if (up->rpf.source_nexthop.interface) {
+ nbr = pim_neighbor_find(up->rpf.source_nexthop.interface,
+ up->rpf.rpf_addr.u.prefix4);
+
+ if (PIM_DEBUG_PIM_EVENTS) {
+ zlog_debug(
+ "%s: starting %d sec timer for upstream (S,G)=%s",
+ __PRETTY_FUNCTION__, qpim_t_periodic,
+ up->sg_str);
+ }
+ }
+
+ if (nbr)
+ pim_jp_agg_add_group(nbr->upstream_jp_agg, up, 1);
+ else {
+ THREAD_OFF(up->t_join_timer);
+ thread_add_timer(master, on_join_timer, up, qpim_t_periodic,
+ &up->t_join_timer);
+ }
+ pim_jp_agg_upstream_verification(up, true);
}
/*
@@ -347,501 +335,488 @@ join_timer_start(struct pim_upstream *up)
* As such we need to remove from the old list and
* add to the new list.
*/
-void pim_upstream_join_timer_restart(struct pim_upstream *up, struct pim_rpf *old)
+void pim_upstream_join_timer_restart(struct pim_upstream *up,
+ struct pim_rpf *old)
{
- //THREAD_OFF(up->t_join_timer);
- join_timer_start(up);
+ // THREAD_OFF(up->t_join_timer);
+ join_timer_start(up);
}
static void pim_upstream_join_timer_restart_msec(struct pim_upstream *up,
int interval_msec)
{
- if (PIM_DEBUG_PIM_EVENTS) {
- zlog_debug("%s: restarting %d msec timer for upstream (S,G)=%s",
- __PRETTY_FUNCTION__,
- interval_msec,
- up->sg_str);
- }
-
- THREAD_OFF(up->t_join_timer);
- thread_add_timer_msec(master, on_join_timer, up, interval_msec,
- &up->t_join_timer);
+ if (PIM_DEBUG_PIM_EVENTS) {
+ zlog_debug("%s: restarting %d msec timer for upstream (S,G)=%s",
+ __PRETTY_FUNCTION__, interval_msec, up->sg_str);
+ }
+
+ THREAD_OFF(up->t_join_timer);
+ thread_add_timer_msec(master, on_join_timer, up, interval_msec,
+ &up->t_join_timer);
}
void pim_upstream_join_suppress(struct pim_upstream *up,
- struct in_addr rpf_addr,
- int holdtime)
+ struct in_addr rpf_addr, int holdtime)
{
- long t_joinsuppress_msec;
- long join_timer_remain_msec;
-
- t_joinsuppress_msec = MIN(pim_if_t_suppressed_msec(up->rpf.source_nexthop.interface),
- 1000 * holdtime);
-
- join_timer_remain_msec = pim_time_timer_remain_msec(up->t_join_timer);
-
- if (PIM_DEBUG_TRACE) {
- char rpf_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<rpf?>", rpf_addr, rpf_str, sizeof(rpf_str));
- zlog_debug("%s %s: detected Join%s to RPF'(S,G)=%s: join_timer=%ld msec t_joinsuppress=%ld msec",
- __FILE__, __PRETTY_FUNCTION__,
- up->sg_str,
- rpf_str,
- join_timer_remain_msec, t_joinsuppress_msec);
- }
-
- if (join_timer_remain_msec < t_joinsuppress_msec) {
- if (PIM_DEBUG_TRACE) {
- zlog_debug("%s %s: suppressing Join(S,G)=%s for %ld msec",
- __FILE__, __PRETTY_FUNCTION__,
- up->sg_str, t_joinsuppress_msec);
- }
-
- pim_upstream_join_timer_restart_msec(up, t_joinsuppress_msec);
- }
+ long t_joinsuppress_msec;
+ long join_timer_remain_msec;
+
+ t_joinsuppress_msec =
+ MIN(pim_if_t_suppressed_msec(up->rpf.source_nexthop.interface),
+ 1000 * holdtime);
+
+ join_timer_remain_msec = pim_time_timer_remain_msec(up->t_join_timer);
+
+ if (PIM_DEBUG_TRACE) {
+ char rpf_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<rpf?>", rpf_addr, rpf_str, sizeof(rpf_str));
+ zlog_debug(
+ "%s %s: detected Join%s to RPF'(S,G)=%s: join_timer=%ld msec t_joinsuppress=%ld msec",
+ __FILE__, __PRETTY_FUNCTION__, up->sg_str, rpf_str,
+ join_timer_remain_msec, t_joinsuppress_msec);
+ }
+
+ if (join_timer_remain_msec < t_joinsuppress_msec) {
+ if (PIM_DEBUG_TRACE) {
+ zlog_debug(
+ "%s %s: suppressing Join(S,G)=%s for %ld msec",
+ __FILE__, __PRETTY_FUNCTION__, up->sg_str,
+ t_joinsuppress_msec);
+ }
+
+ pim_upstream_join_timer_restart_msec(up, t_joinsuppress_msec);
+ }
}
void pim_upstream_join_timer_decrease_to_t_override(const char *debug_label,
- struct pim_upstream *up)
+ struct pim_upstream *up)
{
- long join_timer_remain_msec;
- int t_override_msec;
-
- join_timer_remain_msec = pim_time_timer_remain_msec(up->t_join_timer);
- t_override_msec = pim_if_t_override_msec(up->rpf.source_nexthop.interface);
-
- if (PIM_DEBUG_TRACE) {
- char rpf_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<rpf?>", up->rpf.rpf_addr.u.prefix4, rpf_str, sizeof(rpf_str));
- zlog_debug("%s: to RPF'%s=%s: join_timer=%ld msec t_override=%d msec",
- debug_label,
- up->sg_str, rpf_str,
- join_timer_remain_msec, t_override_msec);
- }
-
- if (join_timer_remain_msec > t_override_msec) {
- if (PIM_DEBUG_TRACE) {
- zlog_debug("%s: decreasing (S,G)=%s join timer to t_override=%d msec",
- debug_label,
- up->sg_str,
- t_override_msec);
- }
-
- pim_upstream_join_timer_restart_msec(up, t_override_msec);
- }
+ long join_timer_remain_msec;
+ int t_override_msec;
+
+ join_timer_remain_msec = pim_time_timer_remain_msec(up->t_join_timer);
+ t_override_msec =
+ pim_if_t_override_msec(up->rpf.source_nexthop.interface);
+
+ if (PIM_DEBUG_TRACE) {
+ char rpf_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<rpf?>", up->rpf.rpf_addr.u.prefix4, rpf_str,
+ sizeof(rpf_str));
+ zlog_debug(
+ "%s: to RPF'%s=%s: join_timer=%ld msec t_override=%d msec",
+ debug_label, up->sg_str, rpf_str,
+ join_timer_remain_msec, t_override_msec);
+ }
+
+ if (join_timer_remain_msec > t_override_msec) {
+ if (PIM_DEBUG_TRACE) {
+ zlog_debug(
+ "%s: decreasing (S,G)=%s join timer to t_override=%d msec",
+ debug_label, up->sg_str, t_override_msec);
+ }
+
+ pim_upstream_join_timer_restart_msec(up, t_override_msec);
+ }
}
static void forward_on(struct pim_upstream *up)
{
- struct listnode *chnode;
- struct listnode *chnextnode;
- struct pim_ifchannel *ch = NULL;
+ struct listnode *chnode;
+ struct listnode *chnextnode;
+ struct pim_ifchannel *ch = NULL;
- /* scan (S,G) state */
- for (ALL_LIST_ELEMENTS(up->ifchannels, chnode, chnextnode, ch)) {
- if (pim_macro_chisin_oiflist(ch))
- pim_forward_start(ch);
+ /* scan (S,G) state */
+ for (ALL_LIST_ELEMENTS(up->ifchannels, chnode, chnextnode, ch)) {
+ if (pim_macro_chisin_oiflist(ch))
+ pim_forward_start(ch);
- } /* scan iface channel list */
+ } /* scan iface channel list */
}
static void forward_off(struct pim_upstream *up)
{
- struct listnode *chnode;
- struct listnode *chnextnode;
- struct pim_ifchannel *ch;
+ struct listnode *chnode;
+ struct listnode *chnextnode;
+ struct pim_ifchannel *ch;
- /* scan per-interface (S,G) state */
- for (ALL_LIST_ELEMENTS(up->ifchannels, chnode, chnextnode, ch)) {
+ /* scan per-interface (S,G) state */
+ for (ALL_LIST_ELEMENTS(up->ifchannels, chnode, chnextnode, ch)) {
- pim_forward_stop(ch);
+ pim_forward_stop(ch);
- } /* scan iface channel list */
+ } /* scan iface channel list */
}
-static int
-pim_upstream_could_register (struct pim_upstream *up)
+static int pim_upstream_could_register(struct pim_upstream *up)
{
- struct pim_interface *pim_ifp = NULL;
-
- if (up->rpf.source_nexthop.interface)
- pim_ifp = up->rpf.source_nexthop.interface->info;
- else
- {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: up %s RPF is not present", __PRETTY_FUNCTION__, up->sg_str);
- }
+ struct pim_interface *pim_ifp = NULL;
+
+ if (up->rpf.source_nexthop.interface)
+ pim_ifp = up->rpf.source_nexthop.interface->info;
+ else {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug("%s: up %s RPF is not present",
+ __PRETTY_FUNCTION__, up->sg_str);
+ }
- if (pim_ifp && PIM_I_am_DR (pim_ifp) &&
- pim_if_connected_to_source (up->rpf.source_nexthop.interface, up->sg.src))
- return 1;
+ if (pim_ifp && PIM_I_am_DR(pim_ifp)
+ && pim_if_connected_to_source(up->rpf.source_nexthop.interface,
+ up->sg.src))
+ return 1;
- return 0;
+ return 0;
}
/* Source registration is supressed for SSM groups. When the SSM range changes
* we re-revaluate register setup for existing upstream entries */
-void
-pim_upstream_register_reevaluate (void)
+void pim_upstream_register_reevaluate(void)
{
- struct listnode *upnode;
- struct pim_upstream *up;
-
- for (ALL_LIST_ELEMENTS_RO (pim_upstream_list, upnode, up))
- {
- /* If FHR is set CouldRegister is True. Also check if the flow
- * is actually active; if it is not kat setup will trigger source
- * registration whenever the flow becomes active. */
- if (!PIM_UPSTREAM_FLAG_TEST_FHR (up->flags) || !up->t_ka_timer)
- continue;
-
- if (pim_is_grp_ssm (up->sg.grp))
- {
- /* clear the register state for SSM groups */
- if (up->reg_state != PIM_REG_NOINFO)
- {
- if (PIM_DEBUG_PIM_EVENTS)
- zlog_debug ("Clear register for %s as G is now SSM",
- up->sg_str);
- /* remove regiface from the OIL if it is there*/
- pim_channel_del_oif (up->channel_oil, pim_regiface,
- PIM_OIF_FLAG_PROTO_PIM);
- up->reg_state = PIM_REG_NOINFO;
- }
- }
- else
- {
- /* register ASM sources with the RP */
- if (up->reg_state == PIM_REG_NOINFO)
- {
- if (PIM_DEBUG_PIM_EVENTS)
- zlog_debug ("Register %s as G is now ASM", up->sg_str);
- pim_channel_add_oif (up->channel_oil, pim_regiface,
- PIM_OIF_FLAG_PROTO_PIM);
- up->reg_state = PIM_REG_JOIN;
- }
- }
- }
+ struct listnode *upnode;
+ struct pim_upstream *up;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, upnode, up)) {
+ /* If FHR is set CouldRegister is True. Also check if the flow
+ * is actually active; if it is not kat setup will trigger
+ * source
+ * registration whenever the flow becomes active. */
+ if (!PIM_UPSTREAM_FLAG_TEST_FHR(up->flags) || !up->t_ka_timer)
+ continue;
+
+ if (pim_is_grp_ssm(up->sg.grp)) {
+ /* clear the register state for SSM groups */
+ if (up->reg_state != PIM_REG_NOINFO) {
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_debug(
+ "Clear register for %s as G is now SSM",
+ up->sg_str);
+ /* remove regiface from the OIL if it is there*/
+ pim_channel_del_oif(up->channel_oil,
+ pim_regiface,
+ PIM_OIF_FLAG_PROTO_PIM);
+ up->reg_state = PIM_REG_NOINFO;
+ }
+ } else {
+ /* register ASM sources with the RP */
+ if (up->reg_state == PIM_REG_NOINFO) {
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_debug(
+ "Register %s as G is now ASM",
+ up->sg_str);
+ pim_channel_add_oif(up->channel_oil,
+ pim_regiface,
+ PIM_OIF_FLAG_PROTO_PIM);
+ up->reg_state = PIM_REG_JOIN;
+ }
+ }
+ }
}
-void
-pim_upstream_switch(struct pim_upstream *up,
- enum pim_upstream_state new_state)
+void pim_upstream_switch(struct pim_upstream *up,
+ enum pim_upstream_state new_state)
{
- enum pim_upstream_state old_state = up->join_state;
-
- if (PIM_DEBUG_PIM_EVENTS)
- {
- zlog_debug ("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s",
- __PRETTY_FUNCTION__,
- up->sg_str,
- pim_upstream_state2str (up->join_state),
- pim_upstream_state2str (new_state));
- }
-
- up->join_state = new_state;
- if (old_state != new_state)
- up->state_transition = pim_time_monotonic_sec();
-
- pim_upstream_update_assert_tracking_desired(up);
-
- if (new_state == PIM_UPSTREAM_JOINED) {
- if (old_state != PIM_UPSTREAM_JOINED)
- {
- int old_fhr = PIM_UPSTREAM_FLAG_TEST_FHR(up->flags);
- forward_on(up);
- pim_msdp_up_join_state_changed(up);
- if (pim_upstream_could_register (up))
- {
- PIM_UPSTREAM_FLAG_SET_FHR(up->flags);
- if (!old_fhr && PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags))
- {
- pim_upstream_keep_alive_timer_start (up, qpim_keep_alive_time);
- pim_register_join (up);
- }
- }
- else
- {
- pim_upstream_send_join (up);
- join_timer_start (up);
- }
- }
- else
- {
- forward_on (up);
- }
- }
- else {
-
- forward_off(up);
- if (old_state == PIM_UPSTREAM_JOINED)
- pim_msdp_up_join_state_changed(up);
-
- /* IHR, Trigger SGRpt on *,G IIF to prune S,G from RPT towards RP.
- If I am RP for G then send S,G prune to its IIF. */
- if (pim_upstream_is_sg_rpt(up) && up->parent && !I_am_RP(up->sg.grp))
- {
- if (PIM_DEBUG_PIM_TRACE_DETAIL)
- zlog_debug ("%s: *,G IIF %s S,G IIF %s ", __PRETTY_FUNCTION__,
- up->parent->rpf.source_nexthop.interface->name,
- up->rpf.source_nexthop.interface->name);
- pim_jp_agg_single_upstream_send(&up->parent->rpf, up->parent, 1 /* (W,G) Join */);
- }
- else
- pim_jp_agg_single_upstream_send(&up->rpf, up, 0 /* prune */);
- join_timer_stop(up);
- }
+ enum pim_upstream_state old_state = up->join_state;
+
+ if (PIM_DEBUG_PIM_EVENTS) {
+ zlog_debug("%s: PIM_UPSTREAM_%s: (S,G) old: %s new: %s",
+ __PRETTY_FUNCTION__, up->sg_str,
+ pim_upstream_state2str(up->join_state),
+ pim_upstream_state2str(new_state));
+ }
+
+ up->join_state = new_state;
+ if (old_state != new_state)
+ up->state_transition = pim_time_monotonic_sec();
+
+ pim_upstream_update_assert_tracking_desired(up);
+
+ if (new_state == PIM_UPSTREAM_JOINED) {
+ if (old_state != PIM_UPSTREAM_JOINED) {
+ int old_fhr = PIM_UPSTREAM_FLAG_TEST_FHR(up->flags);
+ forward_on(up);
+ pim_msdp_up_join_state_changed(up);
+ if (pim_upstream_could_register(up)) {
+ PIM_UPSTREAM_FLAG_SET_FHR(up->flags);
+ if (!old_fhr
+ && PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(
+ up->flags)) {
+ pim_upstream_keep_alive_timer_start(
+ up, qpim_keep_alive_time);
+ pim_register_join(up);
+ }
+ } else {
+ pim_upstream_send_join(up);
+ join_timer_start(up);
+ }
+ } else {
+ forward_on(up);
+ }
+ } else {
+
+ forward_off(up);
+ if (old_state == PIM_UPSTREAM_JOINED)
+ pim_msdp_up_join_state_changed(up);
+
+ /* IHR, Trigger SGRpt on *,G IIF to prune S,G from RPT towards
+ RP.
+ If I am RP for G then send S,G prune to its IIF. */
+ if (pim_upstream_is_sg_rpt(up) && up->parent
+ && !I_am_RP(up->sg.grp)) {
+ if (PIM_DEBUG_PIM_TRACE_DETAIL)
+ zlog_debug(
+ "%s: *,G IIF %s S,G IIF %s ",
+ __PRETTY_FUNCTION__,
+ up->parent->rpf.source_nexthop
+ .interface->name,
+ up->rpf.source_nexthop.interface->name);
+ pim_jp_agg_single_upstream_send(&up->parent->rpf,
+ up->parent,
+ 1 /* (W,G) Join */);
+ } else
+ pim_jp_agg_single_upstream_send(&up->rpf, up,
+ 0 /* prune */);
+ join_timer_stop(up);
+ }
}
-int
-pim_upstream_compare (void *arg1, void *arg2)
+int pim_upstream_compare(void *arg1, void *arg2)
{
- const struct pim_upstream *up1 = (const struct pim_upstream *)arg1;
- const struct pim_upstream *up2 = (const struct pim_upstream *)arg2;
+ const struct pim_upstream *up1 = (const struct pim_upstream *)arg1;
+ const struct pim_upstream *up2 = (const struct pim_upstream *)arg2;
- if (ntohl(up1->sg.grp.s_addr) < ntohl(up2->sg.grp.s_addr))
- return -1;
+ if (ntohl(up1->sg.grp.s_addr) < ntohl(up2->sg.grp.s_addr))
+ return -1;
- if (ntohl(up1->sg.grp.s_addr) > ntohl(up2->sg.grp.s_addr))
- return 1;
+ if (ntohl(up1->sg.grp.s_addr) > ntohl(up2->sg.grp.s_addr))
+ return 1;
- if (ntohl(up1->sg.src.s_addr) < ntohl(up2->sg.src.s_addr))
- return -1;
+ if (ntohl(up1->sg.src.s_addr) < ntohl(up2->sg.src.s_addr))
+ return -1;
- if (ntohl(up1->sg.src.s_addr) > ntohl(up2->sg.src.s_addr))
- return 1;
+ if (ntohl(up1->sg.src.s_addr) > ntohl(up2->sg.src.s_addr))
+ return 1;
- return 0;
+ return 0;
}
static struct pim_upstream *
-pim_upstream_new (struct prefix_sg *sg,
- struct interface *incoming,
- int flags)
+pim_upstream_new(struct prefix_sg *sg, struct interface *incoming, int flags)
{
- enum pim_rpf_result rpf_result;
- struct pim_interface *pim_ifp;
- struct pim_upstream *up;
-
- up = XCALLOC(MTYPE_PIM_UPSTREAM, sizeof(*up));
- if (!up)
- {
- zlog_err("%s: PIM XCALLOC(%zu) failure",
- __PRETTY_FUNCTION__, sizeof(*up));
- return NULL;
- }
-
- up->sg = *sg;
- pim_str_sg_set (sg, up->sg_str);
- up = hash_get (pim_upstream_hash, up, hash_alloc_intern);
- if (!pim_rp_set_upstream_addr (&up->upstream_addr, sg->src, sg->grp))
- {
- if (PIM_DEBUG_TRACE)
- zlog_debug("%s: Received a (*,G) with no RP configured", __PRETTY_FUNCTION__);
-
- hash_release (pim_upstream_hash, up);
- XFREE (MTYPE_PIM_UPSTREAM, up);
- return NULL;
- }
-
- up->parent = pim_upstream_find_parent (up);
- if (up->sg.src.s_addr == INADDR_ANY)
- {
- up->sources = list_new ();
- up->sources->cmp = pim_upstream_compare;
- }
- else
- up->sources = NULL;
-
- pim_upstream_find_new_children (up);
- up->flags = flags;
- up->ref_count = 1;
- up->t_join_timer = NULL;
- up->t_ka_timer = NULL;
- up->t_rs_timer = NULL;
- up->t_msdp_reg_timer = NULL;
- up->join_state = PIM_UPSTREAM_NOTJOINED;
- up->reg_state = PIM_REG_NOINFO;
- up->state_transition = pim_time_monotonic_sec();
- up->channel_oil = NULL;
- up->sptbit = PIM_UPSTREAM_SPTBIT_FALSE;
-
- up->rpf.source_nexthop.interface = NULL;
- up->rpf.source_nexthop.mrib_nexthop_addr.family = AF_INET;
- up->rpf.source_nexthop.mrib_nexthop_addr.u.prefix4.s_addr = PIM_NET_INADDR_ANY;
- up->rpf.source_nexthop.mrib_metric_preference = qpim_infinite_assert_metric.metric_preference;
- up->rpf.source_nexthop.mrib_route_metric = qpim_infinite_assert_metric.route_metric;
- up->rpf.rpf_addr.family = AF_INET;
- up->rpf.rpf_addr.u.prefix4.s_addr = PIM_NET_INADDR_ANY;
-
- up->ifchannels = list_new();
- up->ifchannels->cmp = (int (*)(void *, void *))pim_ifchannel_compare;
-
- if (up->sg.src.s_addr != INADDR_ANY)
- wheel_add_item (pim_upstream_sg_wheel, up);
-
- rpf_result = pim_rpf_update(up, NULL, 1);
- if (rpf_result == PIM_RPF_FAILURE) {
- struct prefix nht_p;
-
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: Attempting to create upstream(%s), Unable to RPF for source", __PRETTY_FUNCTION__,
- up->sg_str);
-
- nht_p.family = AF_INET;
- nht_p.prefixlen = IPV4_MAX_BITLEN;
- nht_p.u.prefix4 = up->upstream_addr;
- pim_delete_tracked_nexthop (&nht_p, up, NULL);
-
- if (up->parent)
- {
- listnode_delete (up->parent->sources, up);
- up->parent = NULL;
- }
-
- if (up->sg.src.s_addr != INADDR_ANY)
- wheel_remove_item (pim_upstream_sg_wheel, up);
-
- pim_upstream_remove_children (up);
- if (up->sources)
- list_delete (up->sources);
-
- hash_release (pim_upstream_hash, up);
- XFREE(MTYPE_PIM_UPSTREAM, up);
- return NULL;
- }
-
- if (up->rpf.source_nexthop.interface)
- {
- pim_ifp = up->rpf.source_nexthop.interface->info;
- if (pim_ifp)
- up->channel_oil = pim_channel_oil_add(&up->sg, pim_ifp->mroute_vif_index);
- }
- listnode_add_sort(pim_upstream_list, up);
-
- if (PIM_DEBUG_TRACE)
- {
- zlog_debug ("%s: Created Upstream %s upstream_addr %s ref count %d increment",
- __PRETTY_FUNCTION__, up->sg_str,
- inet_ntoa (up->upstream_addr), up->ref_count);
- }
-
- return up;
+ enum pim_rpf_result rpf_result;
+ struct pim_interface *pim_ifp;
+ struct pim_upstream *up;
+
+ up = XCALLOC(MTYPE_PIM_UPSTREAM, sizeof(*up));
+ if (!up) {
+ zlog_err("%s: PIM XCALLOC(%zu) failure", __PRETTY_FUNCTION__,
+ sizeof(*up));
+ return NULL;
+ }
+
+ up->sg = *sg;
+ pim_str_sg_set(sg, up->sg_str);
+ up = hash_get(pim_upstream_hash, up, hash_alloc_intern);
+ if (!pim_rp_set_upstream_addr(&up->upstream_addr, sg->src, sg->grp)) {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug("%s: Received a (*,G) with no RP configured",
+ __PRETTY_FUNCTION__);
+
+ hash_release(pim_upstream_hash, up);
+ XFREE(MTYPE_PIM_UPSTREAM, up);
+ return NULL;
+ }
+
+ up->parent = pim_upstream_find_parent(up);
+ if (up->sg.src.s_addr == INADDR_ANY) {
+ up->sources = list_new();
+ up->sources->cmp = pim_upstream_compare;
+ } else
+ up->sources = NULL;
+
+ pim_upstream_find_new_children(up);
+ up->flags = flags;
+ up->ref_count = 1;
+ up->t_join_timer = NULL;
+ up->t_ka_timer = NULL;
+ up->t_rs_timer = NULL;
+ up->t_msdp_reg_timer = NULL;
+ up->join_state = PIM_UPSTREAM_NOTJOINED;
+ up->reg_state = PIM_REG_NOINFO;
+ up->state_transition = pim_time_monotonic_sec();
+ up->channel_oil = NULL;
+ up->sptbit = PIM_UPSTREAM_SPTBIT_FALSE;
+
+ up->rpf.source_nexthop.interface = NULL;
+ up->rpf.source_nexthop.mrib_nexthop_addr.family = AF_INET;
+ up->rpf.source_nexthop.mrib_nexthop_addr.u.prefix4.s_addr =
+ PIM_NET_INADDR_ANY;
+ up->rpf.source_nexthop.mrib_metric_preference =
+ qpim_infinite_assert_metric.metric_preference;
+ up->rpf.source_nexthop.mrib_route_metric =
+ qpim_infinite_assert_metric.route_metric;
+ up->rpf.rpf_addr.family = AF_INET;
+ up->rpf.rpf_addr.u.prefix4.s_addr = PIM_NET_INADDR_ANY;
+
+ up->ifchannels = list_new();
+ up->ifchannels->cmp = (int (*)(void *, void *))pim_ifchannel_compare;
+
+ if (up->sg.src.s_addr != INADDR_ANY)
+ wheel_add_item(pim_upstream_sg_wheel, up);
+
+ rpf_result = pim_rpf_update(up, NULL, 1);
+ if (rpf_result == PIM_RPF_FAILURE) {
+ struct prefix nht_p;
+
+ if (PIM_DEBUG_TRACE)
+ zlog_debug(
+ "%s: Attempting to create upstream(%s), Unable to RPF for source",
+ __PRETTY_FUNCTION__, up->sg_str);
+
+ nht_p.family = AF_INET;
+ nht_p.prefixlen = IPV4_MAX_BITLEN;
+ nht_p.u.prefix4 = up->upstream_addr;
+ pim_delete_tracked_nexthop(&nht_p, up, NULL);
+
+ if (up->parent) {
+ listnode_delete(up->parent->sources, up);
+ up->parent = NULL;
+ }
+
+ if (up->sg.src.s_addr != INADDR_ANY)
+ wheel_remove_item(pim_upstream_sg_wheel, up);
+
+ pim_upstream_remove_children(up);
+ if (up->sources)
+ list_delete(up->sources);
+
+ hash_release(pim_upstream_hash, up);
+ XFREE(MTYPE_PIM_UPSTREAM, up);
+ return NULL;
+ }
+
+ if (up->rpf.source_nexthop.interface) {
+ pim_ifp = up->rpf.source_nexthop.interface->info;
+ if (pim_ifp)
+ up->channel_oil = pim_channel_oil_add(
+ &up->sg, pim_ifp->mroute_vif_index);
+ }
+ listnode_add_sort(pim_upstream_list, up);
+
+ if (PIM_DEBUG_TRACE) {
+ zlog_debug(
+ "%s: Created Upstream %s upstream_addr %s ref count %d increment",
+ __PRETTY_FUNCTION__, up->sg_str,
+ inet_ntoa(up->upstream_addr), up->ref_count);
+ }
+
+ return up;
}
struct pim_upstream *pim_upstream_find(struct prefix_sg *sg)
{
- struct pim_upstream lookup;
- struct pim_upstream *up = NULL;
+ struct pim_upstream lookup;
+ struct pim_upstream *up = NULL;
- lookup.sg = *sg;
- up = hash_lookup (pim_upstream_hash, &lookup);
- return up;
+ lookup.sg = *sg;
+ up = hash_lookup(pim_upstream_hash, &lookup);
+ return up;
}
-struct pim_upstream *
-pim_upstream_find_or_add(struct prefix_sg *sg,
- struct interface *incoming,
- int flags, const char *name)
+struct pim_upstream *pim_upstream_find_or_add(struct prefix_sg *sg,
+ struct interface *incoming,
+ int flags, const char *name)
{
- struct pim_upstream *up;
-
- up = pim_upstream_find(sg);
-
- if (up)
- {
- if (!(up->flags & flags))
- {
- up->flags |= flags;
- up->ref_count++;
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s(%s): upstream %s ref count %d increment",
- __PRETTY_FUNCTION__, name, up->sg_str, up->ref_count);
- }
- }
- else
- up = pim_upstream_add (sg, incoming, flags, name);
-
- return up;
+ struct pim_upstream *up;
+
+ up = pim_upstream_find(sg);
+
+ if (up) {
+ if (!(up->flags & flags)) {
+ up->flags |= flags;
+ up->ref_count++;
+ if (PIM_DEBUG_TRACE)
+ zlog_debug(
+ "%s(%s): upstream %s ref count %d increment",
+ __PRETTY_FUNCTION__, name, up->sg_str,
+ up->ref_count);
+ }
+ } else
+ up = pim_upstream_add(sg, incoming, flags, name);
+
+ return up;
}
-void
-pim_upstream_ref(struct pim_upstream *up, int flags, const char *name)
+void pim_upstream_ref(struct pim_upstream *up, int flags, const char *name)
{
- up->flags |= flags;
- ++up->ref_count;
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s(%s): upstream %s ref count %d increment",
- __PRETTY_FUNCTION__, name, up->sg_str, up->ref_count);
+ up->flags |= flags;
+ ++up->ref_count;
+ if (PIM_DEBUG_TRACE)
+ zlog_debug("%s(%s): upstream %s ref count %d increment",
+ __PRETTY_FUNCTION__, name, up->sg_str,
+ up->ref_count);
}
struct pim_upstream *pim_upstream_add(struct prefix_sg *sg,
- struct interface *incoming,
- int flags, const char *name)
+ struct interface *incoming, int flags,
+ const char *name)
{
- struct pim_upstream *up = NULL;
- int found = 0;
- up = pim_upstream_find(sg);
- if (up) {
- pim_upstream_ref(up, flags, name);
- found = 1;
- }
- else {
- up = pim_upstream_new(sg, incoming, flags);
- }
-
- if (PIM_DEBUG_TRACE)
- {
- if (up)
- {
- char buf[PREFIX2STR_BUFFER];
- prefix2str (&up->rpf.rpf_addr, buf, sizeof (buf));
- zlog_debug("%s(%s): %s, iif %s (%s) found: %d: ref_count: %d",
+ struct pim_upstream *up = NULL;
+ int found = 0;
+ up = pim_upstream_find(sg);
+ if (up) {
+ pim_upstream_ref(up, flags, name);
+ found = 1;
+ } else {
+ up = pim_upstream_new(sg, incoming, flags);
+ }
+
+ if (PIM_DEBUG_TRACE) {
+ if (up) {
+ char buf[PREFIX2STR_BUFFER];
+ prefix2str(&up->rpf.rpf_addr, buf, sizeof(buf));
+ zlog_debug("%s(%s): %s, iif %s (%s) found: %d: ref_count: %d",
__PRETTY_FUNCTION__, name,
up->sg_str, buf, up->rpf.source_nexthop.interface ?
up->rpf.source_nexthop.interface->name : "NIL" ,
found, up->ref_count);
- }
- else
- zlog_debug("%s(%s): (%s) failure to create",
- __PRETTY_FUNCTION__, name,
- pim_str_sg_dump (sg));
- }
+ } else
+ zlog_debug("%s(%s): (%s) failure to create",
+ __PRETTY_FUNCTION__, name,
+ pim_str_sg_dump(sg));
+ }
- return up;
+ return up;
}
/*
* Passed in up must be the upstream for ch. starch is NULL if no
* information
*/
-int
-pim_upstream_evaluate_join_desired_interface (struct pim_upstream *up,
- struct pim_ifchannel *ch,
- struct pim_ifchannel *starch)
+int pim_upstream_evaluate_join_desired_interface(struct pim_upstream *up,
+ struct pim_ifchannel *ch,
+ struct pim_ifchannel *starch)
{
- if (ch)
- {
- if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags))
- return 0;
-
- if (!pim_macro_ch_lost_assert(ch) && pim_macro_chisin_joins_or_include(ch))
- return 1;
- }
-
- /*
- * joins (*,G)
- */
- if (starch)
- {
- if (PIM_IF_FLAG_TEST_S_G_RPT (starch->upstream->flags))
- return 0;
-
- if (!pim_macro_ch_lost_assert (starch) && pim_macro_chisin_joins_or_include (starch))
- return 1;
- }
-
- return 0;
+ if (ch) {
+ if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags))
+ return 0;
+
+ if (!pim_macro_ch_lost_assert(ch)
+ && pim_macro_chisin_joins_or_include(ch))
+ return 1;
+ }
+
+ /*
+ * joins (*,G)
+ */
+ if (starch) {
+ if (PIM_IF_FLAG_TEST_S_G_RPT(starch->upstream->flags))
+ return 0;
+
+ if (!pim_macro_ch_lost_assert(starch)
+ && pim_macro_chisin_joins_or_include(starch))
+ return 1;
+ }
+
+ return 0;
}
/*
@@ -859,7 +834,7 @@ pim_upstream_evaluate_join_desired_interface (struct pim_upstream *up,
pim_ifp->pim_dr_addr
ch->ifassert_winner_metric
ch->ifassert_winner
- ch->local_ifmembership
+ ch->local_ifmembership
ch->ifjoin_state
ch->upstream->rpf.source_nexthop.mrib_metric_preference
ch->upstream->rpf.source_nexthop.mrib_route_metric
@@ -869,31 +844,31 @@ pim_upstream_evaluate_join_desired_interface (struct pim_upstream *up,
*/
int pim_upstream_evaluate_join_desired(struct pim_upstream *up)
{
- struct interface *ifp;
- struct listnode *node;
- struct pim_ifchannel *ch, *starch;
- struct pim_upstream *starup = up->parent;
- int ret = 0;
+ struct interface *ifp;
+ struct listnode *node;
+ struct pim_ifchannel *ch, *starch;
+ struct pim_upstream *starup = up->parent;
+ int ret = 0;
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
- {
- if (!ifp->info)
- continue;
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ if (!ifp->info)
+ continue;
- ch = pim_ifchannel_find (ifp, &up->sg);
+ ch = pim_ifchannel_find(ifp, &up->sg);
- if (starup)
- starch = pim_ifchannel_find (ifp, &starup->sg);
- else
- starch = NULL;
+ if (starup)
+ starch = pim_ifchannel_find(ifp, &starup->sg);
+ else
+ starch = NULL;
- if (!ch && !starch)
- continue;
+ if (!ch && !starch)
+ continue;
- ret += pim_upstream_evaluate_join_desired_interface (up, ch, starch);
- } /* scan iface channel list */
+ ret += pim_upstream_evaluate_join_desired_interface(up, ch,
+ starch);
+ } /* scan iface channel list */
- return ret; /* false */
+ return ret; /* false */
}
/*
@@ -901,28 +876,28 @@ int pim_upstream_evaluate_join_desired(struct pim_upstream *up)
*/
void pim_upstream_update_join_desired(struct pim_upstream *up)
{
- int was_join_desired; /* boolean */
- int is_join_desired; /* boolean */
-
- was_join_desired = PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags);
-
- is_join_desired = pim_upstream_evaluate_join_desired(up);
- if (is_join_desired)
- PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED(up->flags);
- else
- PIM_UPSTREAM_FLAG_UNSET_DR_JOIN_DESIRED(up->flags);
-
- /* switched from false to true */
- if (is_join_desired && !was_join_desired) {
- pim_upstream_switch(up, PIM_UPSTREAM_JOINED);
- return;
- }
-
- /* switched from true to false */
- if (!is_join_desired && was_join_desired) {
- pim_upstream_switch(up, PIM_UPSTREAM_NOTJOINED);
- return;
- }
+ int was_join_desired; /* boolean */
+ int is_join_desired; /* boolean */
+
+ was_join_desired = PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags);
+
+ is_join_desired = pim_upstream_evaluate_join_desired(up);
+ if (is_join_desired)
+ PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED(up->flags);
+ else
+ PIM_UPSTREAM_FLAG_UNSET_DR_JOIN_DESIRED(up->flags);
+
+ /* switched from false to true */
+ if (is_join_desired && !was_join_desired) {
+ pim_upstream_switch(up, PIM_UPSTREAM_JOINED);
+ return;
+ }
+
+ /* switched from true to false */
+ if (!is_join_desired && was_join_desired) {
+ pim_upstream_switch(up, PIM_UPSTREAM_NOTJOINED);
+ return;
+ }
}
/*
@@ -936,110 +911,110 @@ void pim_upstream_update_join_desired(struct pim_upstream *up)
*/
void pim_upstream_rpf_genid_changed(struct in_addr neigh_addr)
{
- struct listnode *up_node;
- struct listnode *up_nextnode;
- struct pim_upstream *up;
-
- /*
- * Scan all (S,G) upstreams searching for RPF'(S,G)=neigh_addr
- */
- for (ALL_LIST_ELEMENTS(pim_upstream_list, up_node, up_nextnode, up)) {
-
- if (PIM_DEBUG_TRACE) {
- char neigh_str[INET_ADDRSTRLEN];
- char rpf_addr_str[PREFIX_STRLEN];
- pim_inet4_dump("<neigh?>", neigh_addr, neigh_str, sizeof(neigh_str));
- pim_addr_dump("<rpf?>", &up->rpf.rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
- zlog_debug("%s: matching neigh=%s against upstream (S,G)=%s joined=%d rpf_addr=%s",
- __PRETTY_FUNCTION__,
- neigh_str, up->sg_str,
- up->join_state == PIM_UPSTREAM_JOINED,
- rpf_addr_str);
- }
-
- /* consider only (S,G) upstream in Joined state */
- if (up->join_state != PIM_UPSTREAM_JOINED)
- continue;
-
- /* match RPF'(S,G)=neigh_addr */
- if (up->rpf.rpf_addr.u.prefix4.s_addr != neigh_addr.s_addr)
- continue;
-
- pim_upstream_join_timer_decrease_to_t_override("RPF'(S,G) GenID change",
- up);
- }
+ struct listnode *up_node;
+ struct listnode *up_nextnode;
+ struct pim_upstream *up;
+
+ /*
+ * Scan all (S,G) upstreams searching for RPF'(S,G)=neigh_addr
+ */
+ for (ALL_LIST_ELEMENTS(pim_upstream_list, up_node, up_nextnode, up)) {
+
+ if (PIM_DEBUG_TRACE) {
+ char neigh_str[INET_ADDRSTRLEN];
+ char rpf_addr_str[PREFIX_STRLEN];
+ pim_inet4_dump("<neigh?>", neigh_addr, neigh_str,
+ sizeof(neigh_str));
+ pim_addr_dump("<rpf?>", &up->rpf.rpf_addr, rpf_addr_str,
+ sizeof(rpf_addr_str));
+ zlog_debug(
+ "%s: matching neigh=%s against upstream (S,G)=%s joined=%d rpf_addr=%s",
+ __PRETTY_FUNCTION__, neigh_str, up->sg_str,
+ up->join_state == PIM_UPSTREAM_JOINED,
+ rpf_addr_str);
+ }
+
+ /* consider only (S,G) upstream in Joined state */
+ if (up->join_state != PIM_UPSTREAM_JOINED)
+ continue;
+
+ /* match RPF'(S,G)=neigh_addr */
+ if (up->rpf.rpf_addr.u.prefix4.s_addr != neigh_addr.s_addr)
+ continue;
+
+ pim_upstream_join_timer_decrease_to_t_override(
+ "RPF'(S,G) GenID change", up);
+ }
}
void pim_upstream_rpf_interface_changed(struct pim_upstream *up,
struct interface *old_rpf_ifp)
{
- struct listnode *chnode;
- struct listnode *chnextnode;
- struct pim_ifchannel *ch;
-
- /* search all ifchannels */
- for (ALL_LIST_ELEMENTS(up->ifchannels, chnode, chnextnode, ch)) {
- if (ch->ifassert_state == PIM_IFASSERT_I_AM_LOSER) {
- if (
- /* RPF_interface(S) was NOT I */
- (old_rpf_ifp == ch->interface)
- &&
- /* RPF_interface(S) stopped being I */
- (ch->upstream->rpf.source_nexthop.interface != ch->interface)
- ) {
- assert_action_a5(ch);
- }
- } /* PIM_IFASSERT_I_AM_LOSER */
-
- pim_ifchannel_update_assert_tracking_desired(ch);
- }
+ struct listnode *chnode;
+ struct listnode *chnextnode;
+ struct pim_ifchannel *ch;
+
+ /* search all ifchannels */
+ for (ALL_LIST_ELEMENTS(up->ifchannels, chnode, chnextnode, ch)) {
+ if (ch->ifassert_state == PIM_IFASSERT_I_AM_LOSER) {
+ if (
+ /* RPF_interface(S) was NOT I */
+ (old_rpf_ifp == ch->interface) &&
+ /* RPF_interface(S) stopped being I */
+ (ch->upstream->rpf.source_nexthop
+ .interface != ch->interface)) {
+ assert_action_a5(ch);
+ }
+ } /* PIM_IFASSERT_I_AM_LOSER */
+
+ pim_ifchannel_update_assert_tracking_desired(ch);
+ }
}
void pim_upstream_update_could_assert(struct pim_upstream *up)
{
- struct listnode *chnode;
- struct listnode *chnextnode;
- struct pim_ifchannel *ch;
-
- /* scan per-interface (S,G) state */
- for (ALL_LIST_ELEMENTS(up->ifchannels, chnode, chnextnode, ch)) {
- pim_ifchannel_update_could_assert(ch);
- } /* scan iface channel list */
+ struct listnode *chnode;
+ struct listnode *chnextnode;
+ struct pim_ifchannel *ch;
+
+ /* scan per-interface (S,G) state */
+ for (ALL_LIST_ELEMENTS(up->ifchannels, chnode, chnextnode, ch)) {
+ pim_ifchannel_update_could_assert(ch);
+ } /* scan iface channel list */
}
void pim_upstream_update_my_assert_metric(struct pim_upstream *up)
{
- struct listnode *chnode;
- struct listnode *chnextnode;
- struct pim_ifchannel *ch;
+ struct listnode *chnode;
+ struct listnode *chnextnode;
+ struct pim_ifchannel *ch;
- /* scan per-interface (S,G) state */
- for (ALL_LIST_ELEMENTS(up->ifchannels, chnode, chnextnode, ch)) {
- pim_ifchannel_update_my_assert_metric(ch);
+ /* scan per-interface (S,G) state */
+ for (ALL_LIST_ELEMENTS(up->ifchannels, chnode, chnextnode, ch)) {
+ pim_ifchannel_update_my_assert_metric(ch);
- } /* scan iface channel list */
+ } /* scan iface channel list */
}
static void pim_upstream_update_assert_tracking_desired(struct pim_upstream *up)
{
- struct listnode *chnode;
- struct listnode *chnextnode;
- struct pim_interface *pim_ifp;
- struct pim_ifchannel *ch;
-
- /* scan per-interface (S,G) state */
- for (ALL_LIST_ELEMENTS(up->ifchannels, chnode, chnextnode, ch))
- {
- if (!ch->interface)
- continue;
- pim_ifp = ch->interface->info;
- if (!pim_ifp)
- continue;
-
- pim_ifchannel_update_assert_tracking_desired(ch);
-
- } /* scan iface channel list */
+ struct listnode *chnode;
+ struct listnode *chnextnode;
+ struct pim_interface *pim_ifp;
+ struct pim_ifchannel *ch;
+
+ /* scan per-interface (S,G) state */
+ for (ALL_LIST_ELEMENTS(up->ifchannels, chnode, chnextnode, ch)) {
+ if (!ch->interface)
+ continue;
+ pim_ifp = ch->interface->info;
+ if (!pim_ifp)
+ continue;
+
+ pim_ifchannel_update_assert_tracking_desired(ch);
+
+ } /* scan iface channel list */
}
/* When kat is stopped CouldRegister goes to false so we need to
@@ -1047,19 +1022,21 @@ static void pim_upstream_update_assert_tracking_desired(struct pim_upstream *up)
* from the OIL */
static void pim_upstream_fhr_kat_expiry(struct pim_upstream *up)
{
- if (!PIM_UPSTREAM_FLAG_TEST_FHR(up->flags))
- return;
-
- if (PIM_DEBUG_TRACE)
- zlog_debug ("kat expired on %s; clear fhr reg state", up->sg_str);
-
- /* stop reg-stop timer */
- THREAD_OFF(up->t_rs_timer);
- /* remove regiface from the OIL if it is there*/
- pim_channel_del_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM);
- /* clear the register state */
- up->reg_state = PIM_REG_NOINFO;
- PIM_UPSTREAM_FLAG_UNSET_FHR(up->flags);
+ if (!PIM_UPSTREAM_FLAG_TEST_FHR(up->flags))
+ return;
+
+ if (PIM_DEBUG_TRACE)
+ zlog_debug("kat expired on %s; clear fhr reg state",
+ up->sg_str);
+
+ /* stop reg-stop timer */
+ THREAD_OFF(up->t_rs_timer);
+ /* remove regiface from the OIL if it is there*/
+ pim_channel_del_oif(up->channel_oil, pim_regiface,
+ PIM_OIF_FLAG_PROTO_PIM);
+ /* clear the register state */
+ up->reg_state = PIM_REG_NOINFO;
+ PIM_UPSTREAM_FLAG_UNSET_FHR(up->flags);
}
/* When kat is started CouldRegister can go to true. And if it does we
@@ -1067,14 +1044,16 @@ static void pim_upstream_fhr_kat_expiry(struct pim_upstream *up)
* to the OIL */
static void pim_upstream_fhr_kat_start(struct pim_upstream *up)
{
- if (pim_upstream_could_register(up)) {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("kat started on %s; set fhr reg state to joined", up->sg_str);
-
- PIM_UPSTREAM_FLAG_SET_FHR(up->flags);
- if (up->reg_state == PIM_REG_NOINFO)
- pim_register_join (up);
- }
+ if (pim_upstream_could_register(up)) {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug(
+ "kat started on %s; set fhr reg state to joined",
+ up->sg_str);
+
+ PIM_UPSTREAM_FLAG_SET_FHR(up->flags);
+ if (up->reg_state == PIM_REG_NOINFO)
+ pim_register_join(up);
+ }
}
/*
@@ -1083,80 +1062,73 @@ static void pim_upstream_fhr_kat_start(struct pim_upstream *up)
* KAT expiry indicates that flow is inactive. If the flow was created or
* maintained by activity now is the time to deref it.
*/
-static int
-pim_upstream_keep_alive_timer (struct thread *t)
+static int pim_upstream_keep_alive_timer(struct thread *t)
{
- struct pim_upstream *up;
-
- up = THREAD_ARG(t);
-
- if (I_am_RP (up->sg.grp))
- {
- pim_br_clear_pmbr (&up->sg);
- /*
- * We need to do more here :)
- * But this is the start.
- */
- }
-
- /* source is no longer active - pull the SA from MSDP's cache */
- pim_msdp_sa_local_del(&up->sg);
-
- /* if entry was created because of activity we need to deref it */
- if (PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags))
- {
- pim_upstream_fhr_kat_expiry(up);
- if (PIM_DEBUG_TRACE)
- zlog_debug ("kat expired on %s; remove stream reference", up->sg_str);
- PIM_UPSTREAM_FLAG_UNSET_SRC_STREAM(up->flags);
- pim_upstream_del(up, __PRETTY_FUNCTION__);
- }
- else if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(up->flags))
- {
- PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(up->flags);
- pim_upstream_del(up, __PRETTY_FUNCTION__);
- }
-
- return 0;
+ struct pim_upstream *up;
+
+ up = THREAD_ARG(t);
+
+ if (I_am_RP(up->sg.grp)) {
+ pim_br_clear_pmbr(&up->sg);
+ /*
+ * We need to do more here :)
+ * But this is the start.
+ */
+ }
+
+ /* source is no longer active - pull the SA from MSDP's cache */
+ pim_msdp_sa_local_del(&up->sg);
+
+ /* if entry was created because of activity we need to deref it */
+ if (PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags)) {
+ pim_upstream_fhr_kat_expiry(up);
+ if (PIM_DEBUG_TRACE)
+ zlog_debug("kat expired on %s; remove stream reference",
+ up->sg_str);
+ PIM_UPSTREAM_FLAG_UNSET_SRC_STREAM(up->flags);
+ pim_upstream_del(up, __PRETTY_FUNCTION__);
+ } else if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(up->flags)) {
+ PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(up->flags);
+ pim_upstream_del(up, __PRETTY_FUNCTION__);
+ }
+
+ return 0;
}
-void
-pim_upstream_keep_alive_timer_start (struct pim_upstream *up,
- uint32_t time)
+void pim_upstream_keep_alive_timer_start(struct pim_upstream *up, uint32_t time)
{
- if (!PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags)) {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("kat start on %s with no stream reference", up->sg_str);
- }
- THREAD_OFF (up->t_ka_timer);
- thread_add_timer(master, pim_upstream_keep_alive_timer, up, time,
- &up->t_ka_timer);
-
- /* any time keepalive is started against a SG we will have to
- * re-evaluate our active source database */
- pim_msdp_sa_local_update(up);
+ if (!PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags)) {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug("kat start on %s with no stream reference",
+ up->sg_str);
+ }
+ THREAD_OFF(up->t_ka_timer);
+ thread_add_timer(master, pim_upstream_keep_alive_timer, up, time,
+ &up->t_ka_timer);
+
+ /* any time keepalive is started against a SG we will have to
+ * re-evaluate our active source database */
+ pim_msdp_sa_local_update(up);
}
/* MSDP on RP needs to know if a source is registerable to this RP */
-static int
-pim_upstream_msdp_reg_timer(struct thread *t)
+static int pim_upstream_msdp_reg_timer(struct thread *t)
{
- struct pim_upstream *up;
+ struct pim_upstream *up;
- up = THREAD_ARG(t);
+ up = THREAD_ARG(t);
- /* source is no longer active - pull the SA from MSDP's cache */
- pim_msdp_sa_local_del(&up->sg);
- return 1;
+ /* source is no longer active - pull the SA from MSDP's cache */
+ pim_msdp_sa_local_del(&up->sg);
+ return 1;
}
-void
-pim_upstream_msdp_reg_timer_start(struct pim_upstream *up)
+void pim_upstream_msdp_reg_timer_start(struct pim_upstream *up)
{
- THREAD_OFF(up->t_msdp_reg_timer);
- thread_add_timer(master, pim_upstream_msdp_reg_timer, up,
- PIM_MSDP_REG_RXED_PERIOD, &up->t_msdp_reg_timer);
+ THREAD_OFF(up->t_msdp_reg_timer);
+ thread_add_timer(master, pim_upstream_msdp_reg_timer, up,
+ PIM_MSDP_REG_RXED_PERIOD, &up->t_msdp_reg_timer);
- pim_msdp_sa_local_update(up);
+ pim_msdp_sa_local_update(up);
}
/*
@@ -1187,28 +1159,25 @@ pim_upstream_msdp_reg_timer_start(struct pim_upstream *up)
* SwitchToSptDesired(S,G) return true once a single packet has been
* received for the source and group.
*/
-int
-pim_upstream_switch_to_spt_desired (struct prefix_sg *sg)
+int pim_upstream_switch_to_spt_desired(struct prefix_sg *sg)
{
- if (I_am_RP (sg->grp))
- return 1;
+ if (I_am_RP(sg->grp))
+ return 1;
- return 0;
+ return 0;
}
-int
-pim_upstream_is_sg_rpt (struct pim_upstream *up)
+int pim_upstream_is_sg_rpt(struct pim_upstream *up)
{
- struct listnode *chnode;
- struct pim_ifchannel *ch;
+ struct listnode *chnode;
+ struct pim_ifchannel *ch;
- for (ALL_LIST_ELEMENTS_RO(up->ifchannels, chnode, ch))
- {
- if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags))
- return 1;
- }
+ for (ALL_LIST_ELEMENTS_RO(up->ifchannels, chnode, ch)) {
+ if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags))
+ return 1;
+ }
- return 0;
+ return 0;
}
/*
* After receiving a packet set SPTbit:
@@ -1226,241 +1195,238 @@ pim_upstream_is_sg_rpt (struct pim_upstream *up)
* }
* }
*/
-void
-pim_upstream_set_sptbit (struct pim_upstream *up, struct interface *incoming)
+void pim_upstream_set_sptbit(struct pim_upstream *up,
+ struct interface *incoming)
{
- struct pim_upstream *starup = up->parent;
-
- // iif == RPF_interfvace(S)
- if (up->rpf.source_nexthop.interface != incoming)
- {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: Incoming Interface: %s is different than RPF_interface(S) %s",
- __PRETTY_FUNCTION__, incoming->name, up->rpf.source_nexthop.interface->name);
- return;
- }
-
- // AND JoinDesired(S,G) == TRUE
- // FIXME
-
- // DirectlyConnected(S) == TRUE
- if (pim_if_connected_to_source (up->rpf.source_nexthop.interface, up->sg.src))
- {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: %s is directly connected to the source", __PRETTY_FUNCTION__,
- up->sg_str);
- up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
- return;
- }
-
- // OR RPF_interface(S) != RPF_interface(RP(G))
- if (!starup || up->rpf.source_nexthop.interface != starup->rpf.source_nexthop.interface)
- {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: %s RPF_interface(S) != RPF_interface(RP(G))",
- __PRETTY_FUNCTION__, up->sg_str);
- up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
- return;
- }
-
- // OR inherited_olist(S,G,rpt) == NULL
- if (pim_upstream_is_sg_rpt(up) && pim_upstream_empty_inherited_olist(up))
- {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: %s OR inherited_olist(S,G,rpt) == NULL", __PRETTY_FUNCTION__,
- up->sg_str);
- up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
- return;
- }
-
- // OR ( ( RPF'(S,G) == RPF'(*,G) ) AND
- // ( RPF'(S,G) != NULL ) )
- if (up->parent && pim_rpf_is_same (&up->rpf, &up->parent->rpf))
- {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: %s RPF'(S,G) is the same as RPF'(*,G)", __PRETTY_FUNCTION__,
- up->sg_str);
- up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
- return;
- }
-
- return;
+ struct pim_upstream *starup = up->parent;
+
+ // iif == RPF_interfvace(S)
+ if (up->rpf.source_nexthop.interface != incoming) {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug(
+ "%s: Incoming Interface: %s is different than RPF_interface(S) %s",
+ __PRETTY_FUNCTION__, incoming->name,
+ up->rpf.source_nexthop.interface->name);
+ return;
+ }
+
+ // AND JoinDesired(S,G) == TRUE
+ // FIXME
+
+ // DirectlyConnected(S) == TRUE
+ if (pim_if_connected_to_source(up->rpf.source_nexthop.interface,
+ up->sg.src)) {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug("%s: %s is directly connected to the source",
+ __PRETTY_FUNCTION__, up->sg_str);
+ up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
+ return;
+ }
+
+ // OR RPF_interface(S) != RPF_interface(RP(G))
+ if (!starup
+ || up->rpf.source_nexthop
+ .interface != starup->rpf.source_nexthop.interface) {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug(
+ "%s: %s RPF_interface(S) != RPF_interface(RP(G))",
+ __PRETTY_FUNCTION__, up->sg_str);
+ up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
+ return;
+ }
+
+ // OR inherited_olist(S,G,rpt) == NULL
+ if (pim_upstream_is_sg_rpt(up)
+ && pim_upstream_empty_inherited_olist(up)) {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug("%s: %s OR inherited_olist(S,G,rpt) == NULL",
+ __PRETTY_FUNCTION__, up->sg_str);
+ up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
+ return;
+ }
+
+ // OR ( ( RPF'(S,G) == RPF'(*,G) ) AND
+ // ( RPF'(S,G) != NULL ) )
+ if (up->parent && pim_rpf_is_same(&up->rpf, &up->parent->rpf)) {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug("%s: %s RPF'(S,G) is the same as RPF'(*,G)",
+ __PRETTY_FUNCTION__, up->sg_str);
+ up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
+ return;
+ }
+
+ return;
}
-const char *
-pim_upstream_state2str (enum pim_upstream_state join_state)
+const char *pim_upstream_state2str(enum pim_upstream_state join_state)
{
- switch (join_state)
- {
- case PIM_UPSTREAM_NOTJOINED:
- return "NotJoined";
- break;
- case PIM_UPSTREAM_JOINED:
- return "Joined";
- break;
- }
- return "Unknown";
+ switch (join_state) {
+ case PIM_UPSTREAM_NOTJOINED:
+ return "NotJoined";
+ break;
+ case PIM_UPSTREAM_JOINED:
+ return "Joined";
+ break;
+ }
+ return "Unknown";
}
-const char *
-pim_reg_state2str (enum pim_reg_state reg_state, char *state_str)
+const char *pim_reg_state2str(enum pim_reg_state reg_state, char *state_str)
{
- switch (reg_state)
- {
- case PIM_REG_NOINFO:
- strcpy (state_str, "RegNoInfo");
- break;
- case PIM_REG_JOIN:
- strcpy (state_str, "RegJoined");
- break;
- case PIM_REG_JOIN_PENDING:
- strcpy (state_str, "RegJoinPend");
- break;
- case PIM_REG_PRUNE:
- strcpy (state_str, "RegPrune");
- break;
- default:
- strcpy (state_str, "RegUnknown");
- }
- return state_str;
+ switch (reg_state) {
+ case PIM_REG_NOINFO:
+ strcpy(state_str, "RegNoInfo");
+ break;
+ case PIM_REG_JOIN:
+ strcpy(state_str, "RegJoined");
+ break;
+ case PIM_REG_JOIN_PENDING:
+ strcpy(state_str, "RegJoinPend");
+ break;
+ case PIM_REG_PRUNE:
+ strcpy(state_str, "RegPrune");
+ break;
+ default:
+ strcpy(state_str, "RegUnknown");
+ }
+ return state_str;
}
-static int
-pim_upstream_register_stop_timer (struct thread *t)
+static int pim_upstream_register_stop_timer(struct thread *t)
{
- struct pim_interface *pim_ifp;
- struct pim_upstream *up;
- struct pim_rpf *rpg;
- struct ip ip_hdr;
- up = THREAD_ARG (t);
-
- if (PIM_DEBUG_TRACE)
- {
- char state_str[PIM_REG_STATE_STR_LEN];
- zlog_debug ("%s: (S,G)=%s upstream register stop timer %s",
- __PRETTY_FUNCTION__, up->sg_str,
- pim_reg_state2str(up->reg_state, state_str));
- }
-
- switch (up->reg_state)
- {
- case PIM_REG_JOIN_PENDING:
- up->reg_state = PIM_REG_JOIN;
- pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM);
- break;
- case PIM_REG_JOIN:
- break;
- case PIM_REG_PRUNE:
- pim_ifp = up->rpf.source_nexthop.interface->info;
- if (!pim_ifp)
- {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: Interface: %s is not configured for pim",
- __PRETTY_FUNCTION__, up->rpf.source_nexthop.interface->name);
- return 0;
- }
- up->reg_state = PIM_REG_JOIN_PENDING;
- pim_upstream_start_register_stop_timer (up, 1);
-
- if (((up->channel_oil->cc.lastused/100) > PIM_KEEPALIVE_PERIOD) &&
- (I_am_RP (up->sg.grp)))
- {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: Stop sending the register, because I am the RP and we haven't seen a packet in a while", __PRETTY_FUNCTION__);
- return 0;
+ struct pim_interface *pim_ifp;
+ struct pim_upstream *up;
+ struct pim_rpf *rpg;
+ struct ip ip_hdr;
+ up = THREAD_ARG(t);
+
+ if (PIM_DEBUG_TRACE) {
+ char state_str[PIM_REG_STATE_STR_LEN];
+ zlog_debug("%s: (S,G)=%s upstream register stop timer %s",
+ __PRETTY_FUNCTION__, up->sg_str,
+ pim_reg_state2str(up->reg_state, state_str));
+ }
+
+ switch (up->reg_state) {
+ case PIM_REG_JOIN_PENDING:
+ up->reg_state = PIM_REG_JOIN;
+ pim_channel_add_oif(up->channel_oil, pim_regiface,
+ PIM_OIF_FLAG_PROTO_PIM);
+ break;
+ case PIM_REG_JOIN:
+ break;
+ case PIM_REG_PRUNE:
+ pim_ifp = up->rpf.source_nexthop.interface->info;
+ if (!pim_ifp) {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug(
+ "%s: Interface: %s is not configured for pim",
+ __PRETTY_FUNCTION__,
+ up->rpf.source_nexthop.interface->name);
+ return 0;
+ }
+ up->reg_state = PIM_REG_JOIN_PENDING;
+ pim_upstream_start_register_stop_timer(up, 1);
+
+ if (((up->channel_oil->cc.lastused / 100)
+ > PIM_KEEPALIVE_PERIOD)
+ && (I_am_RP(up->sg.grp))) {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug(
+ "%s: Stop sending the register, because I am the RP and we haven't seen a packet in a while",
+ __PRETTY_FUNCTION__);
+ return 0;
+ }
+ rpg = RP(up->sg.grp);
+ memset(&ip_hdr, 0, sizeof(struct ip));
+ ip_hdr.ip_p = PIM_IP_PROTO_PIM;
+ ip_hdr.ip_hl = 5;
+ ip_hdr.ip_v = 4;
+ ip_hdr.ip_src = up->sg.src;
+ ip_hdr.ip_dst = up->sg.grp;
+ ip_hdr.ip_len = htons(20);
+ // checksum is broken
+ pim_register_send((uint8_t *)&ip_hdr, sizeof(struct ip),
+ pim_ifp->primary_address, rpg, 1, up);
+ break;
+ default:
+ break;
}
- rpg = RP (up->sg.grp);
- memset (&ip_hdr, 0, sizeof (struct ip));
- ip_hdr.ip_p = PIM_IP_PROTO_PIM;
- ip_hdr.ip_hl = 5;
- ip_hdr.ip_v = 4;
- ip_hdr.ip_src = up->sg.src;
- ip_hdr.ip_dst = up->sg.grp;
- ip_hdr.ip_len = htons (20);
- // checksum is broken
- pim_register_send ((uint8_t *)&ip_hdr, sizeof (struct ip),
- pim_ifp->primary_address, rpg, 1, up);
- break;
- default:
- break;
- }
-
- return 0;
+
+ return 0;
}
-void
-pim_upstream_start_register_stop_timer (struct pim_upstream *up, int null_register)
+void pim_upstream_start_register_stop_timer(struct pim_upstream *up,
+ int null_register)
{
- uint32_t time;
-
- THREAD_TIMER_OFF (up->t_rs_timer);
-
- if (!null_register)
- {
- uint32_t lower = (0.5 * PIM_REGISTER_SUPPRESSION_PERIOD);
- uint32_t upper = (1.5 * PIM_REGISTER_SUPPRESSION_PERIOD);
- time = lower + (random () % (upper - lower + 1)) - PIM_REGISTER_PROBE_PERIOD;
- }
- else
- time = PIM_REGISTER_PROBE_PERIOD;
-
- if (PIM_DEBUG_TRACE)
- {
- zlog_debug ("%s: (S,G)=%s Starting upstream register stop timer %d",
- __PRETTY_FUNCTION__, up->sg_str, time);
- }
- thread_add_timer(master, pim_upstream_register_stop_timer, up, time,
- &up->t_rs_timer);
+ uint32_t time;
+
+ THREAD_TIMER_OFF(up->t_rs_timer);
+
+ if (!null_register) {
+ uint32_t lower = (0.5 * PIM_REGISTER_SUPPRESSION_PERIOD);
+ uint32_t upper = (1.5 * PIM_REGISTER_SUPPRESSION_PERIOD);
+ time = lower + (random() % (upper - lower + 1))
+ - PIM_REGISTER_PROBE_PERIOD;
+ } else
+ time = PIM_REGISTER_PROBE_PERIOD;
+
+ if (PIM_DEBUG_TRACE) {
+ zlog_debug(
+ "%s: (S,G)=%s Starting upstream register stop timer %d",
+ __PRETTY_FUNCTION__, up->sg_str, time);
+ }
+ thread_add_timer(master, pim_upstream_register_stop_timer, up, time,
+ &up->t_rs_timer);
}
-int
-pim_upstream_inherited_olist_decide (struct pim_upstream *up)
+int pim_upstream_inherited_olist_decide(struct pim_upstream *up)
{
- struct interface *ifp;
- struct pim_interface *pim_ifp = NULL;
- struct pim_ifchannel *ch, *starch;
- struct listnode *node;
- struct pim_upstream *starup = up->parent;
- int output_intf = 0;
-
- if (up->rpf.source_nexthop.interface)
- pim_ifp = up->rpf.source_nexthop.interface->info;
- else
- {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: up %s RPF is not present", __PRETTY_FUNCTION__, up->sg_str);
- }
- if (pim_ifp && !up->channel_oil)
- up->channel_oil = pim_channel_oil_add (&up->sg, pim_ifp->mroute_vif_index);
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
- {
- if (!ifp->info)
- continue;
-
- ch = pim_ifchannel_find (ifp, &up->sg);
-
- if (starup)
- starch = pim_ifchannel_find (ifp, &starup->sg);
- else
- starch = NULL;
-
- if (!ch && !starch)
- continue;
-
- if (pim_upstream_evaluate_join_desired_interface (up, ch, starch))
- {
- int flag = PIM_OIF_FLAG_PROTO_PIM;
-
- if (!ch)
- flag = PIM_OIF_FLAG_PROTO_STAR;
-
- pim_channel_add_oif (up->channel_oil, ifp, flag);
- output_intf++;
- }
- }
-
- return output_intf;
+ struct interface *ifp;
+ struct pim_interface *pim_ifp = NULL;
+ struct pim_ifchannel *ch, *starch;
+ struct listnode *node;
+ struct pim_upstream *starup = up->parent;
+ int output_intf = 0;
+
+ if (up->rpf.source_nexthop.interface)
+ pim_ifp = up->rpf.source_nexthop.interface->info;
+ else {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug("%s: up %s RPF is not present",
+ __PRETTY_FUNCTION__, up->sg_str);
+ }
+ if (pim_ifp && !up->channel_oil)
+ up->channel_oil =
+ pim_channel_oil_add(&up->sg, pim_ifp->mroute_vif_index);
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ if (!ifp->info)
+ continue;
+
+ ch = pim_ifchannel_find(ifp, &up->sg);
+
+ if (starup)
+ starch = pim_ifchannel_find(ifp, &starup->sg);
+ else
+ starch = NULL;
+
+ if (!ch && !starch)
+ continue;
+
+ if (pim_upstream_evaluate_join_desired_interface(up, ch,
+ starch)) {
+ int flag = PIM_OIF_FLAG_PROTO_PIM;
+
+ if (!ch)
+ flag = PIM_OIF_FLAG_PROTO_STAR;
+
+ pim_channel_add_oif(up->channel_oil, ifp, flag);
+ output_intf++;
+ }
+ }
+
+ return output_intf;
}
/*
@@ -1479,29 +1445,27 @@ pim_upstream_inherited_olist_decide (struct pim_upstream *up)
* return 1 if there are any output interfaces
* return 0 if there are not any output interfaces
*/
-int
-pim_upstream_inherited_olist (struct pim_upstream *up)
+int pim_upstream_inherited_olist(struct pim_upstream *up)
{
- int output_intf = pim_upstream_inherited_olist_decide (up);
-
- /*
- * If we have output_intf switch state to Join and work like normal
- * If we don't have an output_intf that means we are probably a
- * switch on a stick so turn on forwarding to just accept the
- * incoming packets so we don't bother the other stuff!
- */
- if (output_intf)
- pim_upstream_switch (up, PIM_UPSTREAM_JOINED);
- else
- forward_on (up);
-
- return output_intf;
+ int output_intf = pim_upstream_inherited_olist_decide(up);
+
+ /*
+ * If we have output_intf switch state to Join and work like normal
+ * If we don't have an output_intf that means we are probably a
+ * switch on a stick so turn on forwarding to just accept the
+ * incoming packets so we don't bother the other stuff!
+ */
+ if (output_intf)
+ pim_upstream_switch(up, PIM_UPSTREAM_JOINED);
+ else
+ forward_on(up);
+
+ return output_intf;
}
-int
-pim_upstream_empty_inherited_olist (struct pim_upstream *up)
+int pim_upstream_empty_inherited_olist(struct pim_upstream *up)
{
- return pim_channel_oil_empty (up->channel_oil);
+ return pim_channel_oil_empty(up->channel_oil);
}
/*
@@ -1510,58 +1474,54 @@ pim_upstream_empty_inherited_olist (struct pim_upstream *up)
* set and see if the new neighbor allows
* the join to be sent
*/
-void
-pim_upstream_find_new_rpf (void)
+void pim_upstream_find_new_rpf(void)
{
- struct listnode *up_node;
- struct listnode *up_nextnode;
- struct pim_upstream *up;
-
- /*
- * Scan all (S,G) upstreams searching for RPF'(S,G)=neigh_addr
- */
- for (ALL_LIST_ELEMENTS(pim_upstream_list, up_node, up_nextnode, up))
- {
- if (pim_rpf_addr_is_inaddr_any(&up->rpf))
- {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("Upstream %s without a path to send join, checking",
- up->sg_str);
- pim_rpf_update (up, NULL, 1);
+ struct listnode *up_node;
+ struct listnode *up_nextnode;
+ struct pim_upstream *up;
+
+ /*
+ * Scan all (S,G) upstreams searching for RPF'(S,G)=neigh_addr
+ */
+ for (ALL_LIST_ELEMENTS(pim_upstream_list, up_node, up_nextnode, up)) {
+ if (pim_rpf_addr_is_inaddr_any(&up->rpf)) {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug(
+ "Upstream %s without a path to send join, checking",
+ up->sg_str);
+ pim_rpf_update(up, NULL, 1);
+ }
}
- }
}
-static unsigned int
-pim_upstream_hash_key (void *arg)
+static unsigned int pim_upstream_hash_key(void *arg)
{
- struct pim_upstream *up = (struct pim_upstream *)arg;
+ struct pim_upstream *up = (struct pim_upstream *)arg;
- return jhash_2words (up->sg.src.s_addr, up->sg.grp.s_addr, 0);
+ return jhash_2words(up->sg.src.s_addr, up->sg.grp.s_addr, 0);
}
-void pim_upstream_terminate (void)
+void pim_upstream_terminate(void)
{
- if (pim_upstream_list)
- list_delete (pim_upstream_list);
- pim_upstream_list = NULL;
+ if (pim_upstream_list)
+ list_delete(pim_upstream_list);
+ pim_upstream_list = NULL;
- if (pim_upstream_hash)
- hash_free (pim_upstream_hash);
- pim_upstream_hash = NULL;
+ if (pim_upstream_hash)
+ hash_free(pim_upstream_hash);
+ pim_upstream_hash = NULL;
}
-static int
-pim_upstream_equal (const void *arg1, const void *arg2)
+static int pim_upstream_equal(const void *arg1, const void *arg2)
{
- const struct pim_upstream *up1 = (const struct pim_upstream *)arg1;
- const struct pim_upstream *up2 = (const struct pim_upstream *)arg2;
+ const struct pim_upstream *up1 = (const struct pim_upstream *)arg1;
+ const struct pim_upstream *up2 = (const struct pim_upstream *)arg2;
- if ((up1->sg.grp.s_addr == up2->sg.grp.s_addr) &&
- (up1->sg.src.s_addr == up2->sg.src.s_addr))
- return 1;
+ if ((up1->sg.grp.s_addr == up2->sg.grp.s_addr)
+ && (up1->sg.src.s_addr == up2->sg.src.s_addr))
+ return 1;
- return 0;
+ return 0;
}
/* rfc4601:section-4.2:"Data Packet Forwarding Rules" defines
@@ -1580,129 +1540,128 @@ pim_upstream_equal (const void *arg1, const void *arg2)
*/
static bool pim_upstream_kat_start_ok(struct pim_upstream *up)
{
- /* "iif == RPF_interface(S)" check has to be done by the kernel or hw
- * so we will skip that here */
- if (pim_if_connected_to_source(up->rpf.source_nexthop.interface,
- up->sg.src)) {
- return true;
- }
-
- if ((up->join_state == PIM_UPSTREAM_JOINED) &&
- !pim_upstream_empty_inherited_olist(up)) {
- /* XXX: I have added this RP check just for 3.2 and it's a digression from
- * what rfc-4601 says. Till now we were only running KAT on FHR and RP and
- * there is some angst around making the change to run it all routers that
- * maintain the (S, G) state. This is tracked via CM-13601 and MUST be
- * removed to handle spt turn-arounds correctly in a 3-tier clos */
- if (I_am_RP (up->sg.grp))
- return true;
- }
-
- return false;
+ /* "iif == RPF_interface(S)" check has to be done by the kernel or hw
+ * so we will skip that here */
+ if (pim_if_connected_to_source(up->rpf.source_nexthop.interface,
+ up->sg.src)) {
+ return true;
+ }
+
+ if ((up->join_state == PIM_UPSTREAM_JOINED)
+ && !pim_upstream_empty_inherited_olist(up)) {
+ /* XXX: I have added this RP check just for 3.2 and it's a
+ * digression from
+ * what rfc-4601 says. Till now we were only running KAT on FHR
+ * and RP and
+ * there is some angst around making the change to run it all
+ * routers that
+ * maintain the (S, G) state. This is tracked via CM-13601 and
+ * MUST be
+ * removed to handle spt turn-arounds correctly in a 3-tier clos
+ */
+ if (I_am_RP(up->sg.grp))
+ return true;
+ }
+
+ return false;
}
/*
* Code to check and see if we've received packets on a S,G mroute
* and if so to set the SPT bit appropriately
*/
-static void
-pim_upstream_sg_running (void *arg)
+static void pim_upstream_sg_running(void *arg)
{
- struct pim_upstream *up = (struct pim_upstream *)arg;
-
- // No packet can have arrived here if this is the case
- if (!up->channel_oil || !up->channel_oil->installed)
- {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: %s is not installed in mroute",
- __PRETTY_FUNCTION__, up->sg_str);
- return;
- }
-
- /*
- * This is a bit of a hack
- * We've noted that we should rescan but
- * we've missed the window for doing so in
- * pim_zebra.c for some reason. I am
- * only doing this at this point in time
- * to get us up and working for the moment
- */
- if (up->channel_oil->oil_inherited_rescan)
- {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: Handling unscanned inherited_olist for %s", __PRETTY_FUNCTION__, up->sg_str);
- pim_upstream_inherited_olist_decide (up);
- up->channel_oil->oil_inherited_rescan = 0;
- }
- pim_mroute_update_counters (up->channel_oil);
-
- // Have we seen packets?
- if ((up->channel_oil->cc.oldpktcnt >= up->channel_oil->cc.pktcnt) &&
- (up->channel_oil->cc.lastused/100 > 30))
- {
- if (PIM_DEBUG_TRACE)
- {
- zlog_debug ("%s: %s old packet count is equal or lastused is greater than 30, (%ld,%ld,%lld)",
- __PRETTY_FUNCTION__, up->sg_str,
- up->channel_oil->cc.oldpktcnt,
- up->channel_oil->cc.pktcnt,
- up->channel_oil->cc.lastused/100);
+ struct pim_upstream *up = (struct pim_upstream *)arg;
+
+ // No packet can have arrived here if this is the case
+ if (!up->channel_oil || !up->channel_oil->installed) {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug("%s: %s is not installed in mroute",
+ __PRETTY_FUNCTION__, up->sg_str);
+ return;
+ }
+
+ /*
+ * This is a bit of a hack
+ * We've noted that we should rescan but
+ * we've missed the window for doing so in
+ * pim_zebra.c for some reason. I am
+ * only doing this at this point in time
+ * to get us up and working for the moment
+ */
+ if (up->channel_oil->oil_inherited_rescan) {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug(
+ "%s: Handling unscanned inherited_olist for %s",
+ __PRETTY_FUNCTION__, up->sg_str);
+ pim_upstream_inherited_olist_decide(up);
+ up->channel_oil->oil_inherited_rescan = 0;
+ }
+ pim_mroute_update_counters(up->channel_oil);
+
+ // Have we seen packets?
+ if ((up->channel_oil->cc.oldpktcnt >= up->channel_oil->cc.pktcnt)
+ && (up->channel_oil->cc.lastused / 100 > 30)) {
+ if (PIM_DEBUG_TRACE) {
+ zlog_debug(
+ "%s: %s old packet count is equal or lastused is greater than 30, (%ld,%ld,%lld)",
+ __PRETTY_FUNCTION__, up->sg_str,
+ up->channel_oil->cc.oldpktcnt,
+ up->channel_oil->cc.pktcnt,
+ up->channel_oil->cc.lastused / 100);
+ }
+ return;
}
- return;
- }
-
- if (pim_upstream_kat_start_ok(up))
- {
- /* Add a source reference to the stream if
- * one doesn't already exist */
- if (!PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags))
- {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("source reference created on kat restart %s", up->sg_str);
-
- pim_upstream_ref(up, PIM_UPSTREAM_FLAG_MASK_SRC_STREAM, __PRETTY_FUNCTION__);
- PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags);
- pim_upstream_fhr_kat_start(up);
+
+ if (pim_upstream_kat_start_ok(up)) {
+ /* Add a source reference to the stream if
+ * one doesn't already exist */
+ if (!PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags)) {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug(
+ "source reference created on kat restart %s",
+ up->sg_str);
+
+ pim_upstream_ref(up, PIM_UPSTREAM_FLAG_MASK_SRC_STREAM,
+ __PRETTY_FUNCTION__);
+ PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags);
+ pim_upstream_fhr_kat_start(up);
+ }
+ pim_upstream_keep_alive_timer_start(up, qpim_keep_alive_time);
+ } else if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(up->flags))
+ pim_upstream_keep_alive_timer_start(up, qpim_keep_alive_time);
+
+ if (up->sptbit != PIM_UPSTREAM_SPTBIT_TRUE) {
+ pim_upstream_set_sptbit(up, up->rpf.source_nexthop.interface);
}
- pim_upstream_keep_alive_timer_start(up, qpim_keep_alive_time);
- }
- else if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(up->flags))
- pim_upstream_keep_alive_timer_start(up, qpim_keep_alive_time);
-
- if (up->sptbit != PIM_UPSTREAM_SPTBIT_TRUE)
- {
- pim_upstream_set_sptbit(up, up->rpf.source_nexthop.interface);
- }
- return;
+ return;
}
-void
-pim_upstream_add_lhr_star_pimreg (void)
+void pim_upstream_add_lhr_star_pimreg(void)
{
- struct pim_upstream *up;
- struct listnode *node;
+ struct pim_upstream *up;
+ struct listnode *node;
- for (ALL_LIST_ELEMENTS_RO (pim_upstream_list, node, up))
- {
- if (up->sg.src.s_addr != INADDR_ANY)
- continue;
+ for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, node, up)) {
+ if (up->sg.src.s_addr != INADDR_ANY)
+ continue;
- if (!PIM_UPSTREAM_FLAG_TEST_SRC_IGMP (up->flags))
- continue;
+ if (!PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(up->flags))
+ continue;
- pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP);
- }
+ pim_channel_add_oif(up->channel_oil, pim_regiface,
+ PIM_OIF_FLAG_PROTO_IGMP);
+ }
}
-void
-pim_upstream_spt_prefix_list_update (struct prefix_list *pl)
+void pim_upstream_spt_prefix_list_update(struct prefix_list *pl)
{
- const char *pname = prefix_list_name (pl);
+ const char *pname = prefix_list_name(pl);
- if (pimg->spt.plist && strcmp (pimg->spt.plist, pname) == 0)
- {
- pim_upstream_remove_lhr_star_pimreg (pname);
- }
+ if (pimg->spt.plist && strcmp(pimg->spt.plist, pname) == 0) {
+ pim_upstream_remove_lhr_star_pimreg(pname);
+ }
}
/*
@@ -1717,53 +1676,51 @@ pim_upstream_spt_prefix_list_update (struct prefix_list *pl)
* the interface
*
*/
-void
-pim_upstream_remove_lhr_star_pimreg (const char *nlist)
+void pim_upstream_remove_lhr_star_pimreg(const char *nlist)
{
- struct pim_upstream *up;
- struct listnode *node;
- struct prefix_list *np;
- struct prefix g;
- enum prefix_list_type apply_new;
-
- np = prefix_list_lookup (AFI_IP, nlist);
-
- g.family = AF_INET;
- g.prefixlen = IPV4_MAX_PREFIXLEN;
-
- for (ALL_LIST_ELEMENTS_RO (pim_upstream_list, node, up))
- {
- if (up->sg.src.s_addr != INADDR_ANY)
- continue;
-
- if (!PIM_UPSTREAM_FLAG_TEST_SRC_IGMP (up->flags))
- continue;
-
- if (!nlist)
- {
- pim_channel_del_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP);
- continue;
- }
- g.u.prefix4 = up->sg.grp;
- apply_new = prefix_list_apply (np, &g);
- if (apply_new == PREFIX_DENY)
- pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP);
- else
- pim_channel_del_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP);
- }
+ struct pim_upstream *up;
+ struct listnode *node;
+ struct prefix_list *np;
+ struct prefix g;
+ enum prefix_list_type apply_new;
+
+ np = prefix_list_lookup(AFI_IP, nlist);
+
+ g.family = AF_INET;
+ g.prefixlen = IPV4_MAX_PREFIXLEN;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_upstream_list, node, up)) {
+ if (up->sg.src.s_addr != INADDR_ANY)
+ continue;
+
+ if (!PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(up->flags))
+ continue;
+
+ if (!nlist) {
+ pim_channel_del_oif(up->channel_oil, pim_regiface,
+ PIM_OIF_FLAG_PROTO_IGMP);
+ continue;
+ }
+ g.u.prefix4 = up->sg.grp;
+ apply_new = prefix_list_apply(np, &g);
+ if (apply_new == PREFIX_DENY)
+ pim_channel_add_oif(up->channel_oil, pim_regiface,
+ PIM_OIF_FLAG_PROTO_IGMP);
+ else
+ pim_channel_del_oif(up->channel_oil, pim_regiface,
+ PIM_OIF_FLAG_PROTO_IGMP);
+ }
}
-void
-pim_upstream_init (void)
+void pim_upstream_init(void)
{
- pim_upstream_sg_wheel = wheel_init (master, 31000, 100,
- pim_upstream_hash_key,
- pim_upstream_sg_running);
- pim_upstream_hash = hash_create_size (8192, pim_upstream_hash_key,
- pim_upstream_equal, NULL);
-
- pim_upstream_list = list_new ();
- pim_upstream_list->del = (void (*)(void *)) pim_upstream_free;
- pim_upstream_list->cmp = pim_upstream_compare;
-
+ pim_upstream_sg_wheel =
+ wheel_init(master, 31000, 100, pim_upstream_hash_key,
+ pim_upstream_sg_running);
+ pim_upstream_hash = hash_create_size(8192, pim_upstream_hash_key,
+ pim_upstream_equal, NULL);
+
+ pim_upstream_list = list_new();
+ pim_upstream_list->del = (void (*)(void *))pim_upstream_free;
+ pim_upstream_list->cmp = pim_upstream_compare;
}
diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h
index acb4b17c7..b6a9729f0 100644
--- a/pimd/pim_upstream.h
+++ b/pimd/pim_upstream.h
@@ -70,100 +70,102 @@
#define PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SRC_LHR)
enum pim_upstream_state {
- PIM_UPSTREAM_NOTJOINED,
- PIM_UPSTREAM_JOINED,
+ PIM_UPSTREAM_NOTJOINED,
+ PIM_UPSTREAM_JOINED,
};
enum pim_reg_state {
- PIM_REG_NOINFO,
- PIM_REG_JOIN,
- PIM_REG_JOIN_PENDING,
- PIM_REG_PRUNE,
+ PIM_REG_NOINFO,
+ PIM_REG_JOIN,
+ PIM_REG_JOIN_PENDING,
+ PIM_REG_PRUNE,
};
enum pim_upstream_sptbit {
- PIM_UPSTREAM_SPTBIT_FALSE,
- PIM_UPSTREAM_SPTBIT_TRUE
+ PIM_UPSTREAM_SPTBIT_FALSE,
+ PIM_UPSTREAM_SPTBIT_TRUE
};
/*
Upstream (S,G) channel in Joined state
-
+
(S,G) in the "Not Joined" state is not represented
-
+
See RFC 4601: 4.5.7. Sending (S,G) Join/Prune Message
*/
struct pim_upstream {
- struct pim_upstream *parent;
- struct in_addr upstream_addr;/* Who we are talking to */
- struct in_addr upstream_register; /*Who we received a register from*/
- struct prefix_sg sg; /* (S,G) group key */
- char sg_str[PIM_SG_LEN];
- uint32_t flags;
- struct channel_oil *channel_oil;
- struct list *sources;
- struct list *ifchannels;
-
- enum pim_upstream_state join_state;
- enum pim_reg_state reg_state;
- enum pim_upstream_sptbit sptbit;
-
- int ref_count;
-
- struct pim_rpf rpf;
-
- struct thread *t_join_timer;
-
- /*
- * RST(S,G)
- */
- struct thread *t_rs_timer;
+ struct pim_upstream *parent;
+ struct in_addr upstream_addr; /* Who we are talking to */
+ struct in_addr upstream_register; /*Who we received a register from*/
+ struct prefix_sg sg; /* (S,G) group key */
+ char sg_str[PIM_SG_LEN];
+ uint32_t flags;
+ struct channel_oil *channel_oil;
+ struct list *sources;
+ struct list *ifchannels;
+
+ enum pim_upstream_state join_state;
+ enum pim_reg_state reg_state;
+ enum pim_upstream_sptbit sptbit;
+
+ int ref_count;
+
+ struct pim_rpf rpf;
+
+ struct thread *t_join_timer;
+
+ /*
+ * RST(S,G)
+ */
+ struct thread *t_rs_timer;
#define PIM_REGISTER_SUPPRESSION_PERIOD (60)
#define PIM_REGISTER_PROBE_PERIOD (15)
- /*
- * KAT(S,G)
- */
- struct thread *t_ka_timer;
+ /*
+ * KAT(S,G)
+ */
+ struct thread *t_ka_timer;
#define PIM_KEEPALIVE_PERIOD (210)
#define PIM_RP_KEEPALIVE_PERIOD ( 3 * qpim_register_suppress_time + qpim_register_probe_time )
- /* on the RP we restart a timer to indicate if registers are being rxed for
- * SG. This is needed by MSDP to determine its local SA cache */
- struct thread *t_msdp_reg_timer;
+ /* on the RP we restart a timer to indicate if registers are being rxed
+ * for
+ * SG. This is needed by MSDP to determine its local SA cache */
+ struct thread *t_msdp_reg_timer;
#define PIM_MSDP_REG_RXED_PERIOD (3 * (1.5 * qpim_register_suppress_time))
- int64_t state_transition; /* Record current state uptime */
+ int64_t state_transition; /* Record current state uptime */
};
struct list *pim_upstream_list;
struct hash *pim_upstream_hash;
void pim_upstream_free(struct pim_upstream *up);
-struct pim_upstream *pim_upstream_find (struct prefix_sg *sg);
-struct pim_upstream *pim_upstream_find_or_add (struct prefix_sg *sg,
- struct interface *ifp, int flags,
- const char *name);
-struct pim_upstream *pim_upstream_add (struct prefix_sg *sg,
- struct interface *ifp, int flags,
- const char *name);
-void pim_upstream_ref (struct pim_upstream *up, int flags, const char *name);
-struct pim_upstream *pim_upstream_del(struct pim_upstream *up, const char *name);
+struct pim_upstream *pim_upstream_find(struct prefix_sg *sg);
+struct pim_upstream *pim_upstream_find_or_add(struct prefix_sg *sg,
+ struct interface *ifp, int flags,
+ const char *name);
+struct pim_upstream *pim_upstream_add(struct prefix_sg *sg,
+ struct interface *ifp, int flags,
+ const char *name);
+void pim_upstream_ref(struct pim_upstream *up, int flags, const char *name);
+struct pim_upstream *pim_upstream_del(struct pim_upstream *up,
+ const char *name);
int pim_upstream_evaluate_join_desired(struct pim_upstream *up);
int pim_upstream_evaluate_join_desired_interface(struct pim_upstream *up,
- struct pim_ifchannel *ch,
- struct pim_ifchannel *starch);
+ struct pim_ifchannel *ch,
+ struct pim_ifchannel *starch);
void pim_upstream_update_join_desired(struct pim_upstream *up);
void pim_upstream_join_suppress(struct pim_upstream *up,
- struct in_addr rpf_addr,
- int holdtime);
+ struct in_addr rpf_addr, int holdtime);
void pim_upstream_join_timer_decrease_to_t_override(const char *debug_label,
- struct pim_upstream *up);
+ struct pim_upstream *up);
-void pim_upstream_join_timer_restart(struct pim_upstream *up, struct pim_rpf *old);
+void pim_upstream_join_timer_restart(struct pim_upstream *up,
+ struct pim_rpf *old);
void pim_upstream_rpf_genid_changed(struct in_addr neigh_addr);
void pim_upstream_rpf_interface_changed(struct pim_upstream *up,
struct interface *old_rpf_ifp);
@@ -171,40 +173,44 @@ void pim_upstream_rpf_interface_changed(struct pim_upstream *up,
void pim_upstream_update_could_assert(struct pim_upstream *up);
void pim_upstream_update_my_assert_metric(struct pim_upstream *up);
-void pim_upstream_keep_alive_timer_start (struct pim_upstream *up, uint32_t time);
+void pim_upstream_keep_alive_timer_start(struct pim_upstream *up,
+ uint32_t time);
-int pim_upstream_switch_to_spt_desired (struct prefix_sg *sg);
+int pim_upstream_switch_to_spt_desired(struct prefix_sg *sg);
#define SwitchToSptDesired(sg) pim_upstream_switch_to_spt_desired (sg)
-int pim_upstream_is_sg_rpt (struct pim_upstream *up);
+int pim_upstream_is_sg_rpt(struct pim_upstream *up);
-void pim_upstream_set_sptbit (struct pim_upstream *up, struct interface *incoming);
+void pim_upstream_set_sptbit(struct pim_upstream *up,
+ struct interface *incoming);
-void pim_upstream_start_register_stop_timer (struct pim_upstream *up, int null_register);
+void pim_upstream_start_register_stop_timer(struct pim_upstream *up,
+ int null_register);
-void pim_upstream_send_join (struct pim_upstream *up);
+void pim_upstream_send_join(struct pim_upstream *up);
-void pim_upstream_switch (struct pim_upstream *up, enum pim_upstream_state new_state);
+void pim_upstream_switch(struct pim_upstream *up,
+ enum pim_upstream_state new_state);
-const char *pim_upstream_state2str (enum pim_upstream_state join_state);
+const char *pim_upstream_state2str(enum pim_upstream_state join_state);
#define PIM_REG_STATE_STR_LEN 12
-const char *pim_reg_state2str (enum pim_reg_state state, char *state_str);
+const char *pim_reg_state2str(enum pim_reg_state state, char *state_str);
-int pim_upstream_inherited_olist_decide (struct pim_upstream *up);
-int pim_upstream_inherited_olist (struct pim_upstream *up);
-int pim_upstream_empty_inherited_olist (struct pim_upstream *up);
+int pim_upstream_inherited_olist_decide(struct pim_upstream *up);
+int pim_upstream_inherited_olist(struct pim_upstream *up);
+int pim_upstream_empty_inherited_olist(struct pim_upstream *up);
-void pim_upstream_find_new_rpf (void);
+void pim_upstream_find_new_rpf(void);
void pim_upstream_msdp_reg_timer_start(struct pim_upstream *up);
-void pim_upstream_init (void);
-void pim_upstream_terminate (void);
+void pim_upstream_init(void);
+void pim_upstream_terminate(void);
-void join_timer_start (struct pim_upstream *up);
-int pim_upstream_compare (void *arg1, void *arg2);
-void pim_upstream_register_reevaluate (void);
+void join_timer_start(struct pim_upstream *up);
+int pim_upstream_compare(void *arg1, void *arg2);
+void pim_upstream_register_reevaluate(void);
-void pim_upstream_add_lhr_star_pimreg (void);
-void pim_upstream_remove_lhr_star_pimreg (const char *nlist);
+void pim_upstream_add_lhr_star_pimreg(void);
+void pim_upstream_remove_lhr_star_pimreg(const char *nlist);
-void pim_upstream_spt_prefix_list_update (struct prefix_list *pl);
+void pim_upstream_spt_prefix_list_update(struct prefix_list *pl);
#endif /* PIM_UPSTREAM_H */
diff --git a/pimd/pim_util.c b/pimd/pim_util.c
index 139c0e3fb..c2e4b2a46 100644
--- a/pimd/pim_util.c
+++ b/pimd/pim_util.c
@@ -26,18 +26,18 @@
/*
RFC 3376: 4.1.7. QQIC (Querier's Query Interval Code)
-
+
If QQIC < 128, QQI = QQIC
If QQIC >= 128, QQI = (mant | 0x10) << (exp + 3)
-
+
0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|1| exp | mant |
+-+-+-+-+-+-+-+-+
-
+
Since exp=0..7 then (exp+3)=3..10, then QQI has
one of the following bit patterns:
-
+
exp=0: QQI = 0000.0000.1MMM.M000
exp=1: QQI = 0000.0001.MMMM.0000
...
@@ -48,33 +48,32 @@
*/
uint8_t igmp_msg_encode16to8(uint16_t value)
{
- uint8_t code;
-
- if (value < 128) {
- code = value;
- }
- else {
- uint16_t mask = 0x4000;
- uint8_t exp;
- uint16_t mant;
- for (exp = 7; exp > 0; --exp) {
- if (mask & value)
- break;
- mask >>= 1;
- }
- mant = 0x000F & (value >> (exp + 3));
- code = ((uint8_t) 1 << 7) | ((uint8_t) exp << 4) | (uint8_t) mant;
- }
-
- return code;
+ uint8_t code;
+
+ if (value < 128) {
+ code = value;
+ } else {
+ uint16_t mask = 0x4000;
+ uint8_t exp;
+ uint16_t mant;
+ for (exp = 7; exp > 0; --exp) {
+ if (mask & value)
+ break;
+ mask >>= 1;
+ }
+ mant = 0x000F & (value >> (exp + 3));
+ code = ((uint8_t)1 << 7) | ((uint8_t)exp << 4) | (uint8_t)mant;
+ }
+
+ return code;
}
/*
RFC 3376: 4.1.7. QQIC (Querier's Query Interval Code)
-
+
If QQIC < 128, QQI = QQIC
If QQIC >= 128, QQI = (mant | 0x10) << (exp + 3)
-
+
0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|1| exp | mant |
@@ -82,64 +81,57 @@ uint8_t igmp_msg_encode16to8(uint16_t value)
*/
uint16_t igmp_msg_decode8to16(uint8_t code)
{
- uint16_t value;
-
- if (code < 128) {
- value = code;
- }
- else {
- uint16_t mant = (code & 0x0F);
- uint8_t exp = (code & 0x70) >> 4;
- value = (mant | 0x10) << (exp + 3);
- }
-
- return value;
+ uint16_t value;
+
+ if (code < 128) {
+ value = code;
+ } else {
+ uint16_t mant = (code & 0x0F);
+ uint8_t exp = (code & 0x70) >> 4;
+ value = (mant | 0x10) << (exp + 3);
+ }
+
+ return value;
}
void pim_pkt_dump(const char *label, const uint8_t *buf, int size)
{
- zlog_debug("%s: pkt dump size=%d",
- label,
- size);
- zlog_hexdump(buf, size);
+ zlog_debug("%s: pkt dump size=%d", label, size);
+ zlog_hexdump(buf, size);
}
-int
-pim_is_group_224_0_0_0_24 (struct in_addr group_addr)
+int pim_is_group_224_0_0_0_24(struct in_addr group_addr)
{
- static int first = 1;
- static struct prefix group_224;
- struct prefix group;
+ static int first = 1;
+ static struct prefix group_224;
+ struct prefix group;
- if (first)
- {
- str2prefix ("224.0.0.0/24", &group_224);
- first = 0;
- }
+ if (first) {
+ str2prefix("224.0.0.0/24", &group_224);
+ first = 0;
+ }
- group.family = AF_INET;
- group.u.prefix4 = group_addr;
- group.prefixlen = 32;
+ group.family = AF_INET;
+ group.u.prefix4 = group_addr;
+ group.prefixlen = 32;
- return prefix_match (&group_224, &group);
+ return prefix_match(&group_224, &group);
}
-int
-pim_is_group_224_4 (struct in_addr group_addr)
+int pim_is_group_224_4(struct in_addr group_addr)
{
- static int first = 1;
- static struct prefix group_all;
- struct prefix group;
+ static int first = 1;
+ static struct prefix group_all;
+ struct prefix group;
- if (first)
- {
- str2prefix ("224.0.0.0/4", &group_all);
- first = 0;
- }
+ if (first) {
+ str2prefix("224.0.0.0/4", &group_all);
+ first = 0;
+ }
- group.family = AF_INET;
- group.u.prefix4 = group_addr;
- group.prefixlen = 32;
+ group.family = AF_INET;
+ group.u.prefix4 = group_addr;
+ group.prefixlen = 32;
- return prefix_match (&group_all, &group);
+ return prefix_match(&group_all, &group);
}
diff --git a/pimd/pim_util.h b/pimd/pim_util.h
index 478800520..1b319cfe4 100644
--- a/pimd/pim_util.h
+++ b/pimd/pim_util.h
@@ -31,6 +31,6 @@ uint16_t igmp_msg_decode8to16(uint8_t code);
void pim_pkt_dump(const char *label, const uint8_t *buf, int size);
-int pim_is_group_224_0_0_0_24 (struct in_addr group_addr);
-int pim_is_group_224_4 (struct in_addr group_addr);
+int pim_is_group_224_0_0_0_24(struct in_addr group_addr);
+int pim_is_group_224_4(struct in_addr group_addr);
#endif /* PIM_UTIL_H */
diff --git a/pimd/pim_version.c b/pimd/pim_version.c
index 1da4b9663..439f745ac 100644
--- a/pimd/pim_version.c
+++ b/pimd/pim_version.c
@@ -21,4 +21,4 @@
#include "pim_version.h"
-const char * const PIMD_VERSION = PIMD_VERSION_STR;
+const char *const PIMD_VERSION = PIMD_VERSION_STR;
diff --git a/pimd/pim_version.h b/pimd/pim_version.h
index 589c6f68a..c45d01a13 100644
--- a/pimd/pim_version.h
+++ b/pimd/pim_version.h
@@ -22,6 +22,6 @@
#define PIMD_VERSION_STR "0.166"
-const char * const PIMD_VERSION;
+const char *const PIMD_VERSION;
#endif /* PIM_VERSION_H */
diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c
index 81b49c630..a78776791 100644
--- a/pimd/pim_vty.c
+++ b/pimd/pim_vty.c
@@ -40,284 +40,287 @@
#include "pim_ssm.h"
#include "pim_bfd.h"
-int
-pim_debug_config_write (struct vty *vty)
+int pim_debug_config_write(struct vty *vty)
{
- int writes = 0;
-
- if (PIM_DEBUG_MSDP_EVENTS) {
- vty_out (vty, "debug msdp events\n");
- ++writes;
- }
- if (PIM_DEBUG_MSDP_PACKETS) {
- vty_out (vty, "debug msdp packets\n");
- ++writes;
- }
- if (PIM_DEBUG_MSDP_INTERNAL) {
- vty_out (vty, "debug msdp internal\n");
- ++writes;
- }
- if (PIM_DEBUG_IGMP_EVENTS) {
- vty_out (vty, "debug igmp events\n");
- ++writes;
- }
- if (PIM_DEBUG_IGMP_PACKETS) {
- vty_out (vty, "debug igmp packets\n");
- ++writes;
- }
- if (PIM_DEBUG_IGMP_TRACE) {
- vty_out (vty, "debug igmp trace\n");
- ++writes;
- }
- if (PIM_DEBUG_IGMP_TRACE_DETAIL) {
- vty_out (vty, "debug igmp trace detail\n");
- ++writes;
- }
-
- if (PIM_DEBUG_MROUTE) {
- vty_out (vty, "debug mroute\n");
- ++writes;
- }
-
- if (PIM_DEBUG_MROUTE_DETAIL) {
- vty_out (vty, "debug mroute detail\n");
- ++writes;
- }
-
- if (PIM_DEBUG_PIM_EVENTS) {
- vty_out (vty, "debug pim events\n");
- ++writes;
- }
- if (PIM_DEBUG_PIM_PACKETS) {
- vty_out (vty, "debug pim packets\n");
- ++writes;
- }
- if (PIM_DEBUG_PIM_PACKETDUMP_SEND) {
- vty_out (vty, "debug pim packet-dump send\n");
- ++writes;
- }
- if (PIM_DEBUG_PIM_PACKETDUMP_RECV) {
- vty_out (vty, "debug pim packet-dump receive\n");
- ++writes;
- }
-
- if (PIM_DEBUG_PIM_TRACE) {
- vty_out (vty, "debug pim trace\n");
- ++writes;
- }
- if (PIM_DEBUG_PIM_TRACE_DETAIL) {
- vty_out (vty, "debug pim trace detail\n");
- ++writes;
- }
-
- if (PIM_DEBUG_ZEBRA) {
- vty_out (vty, "debug pim zebra\n");
- ++writes;
- }
-
- if (PIM_DEBUG_SSMPINGD) {
- vty_out (vty, "debug ssmpingd\n");
- ++writes;
- }
-
- if (PIM_DEBUG_PIM_HELLO) {
- vty_out (vty, "debug pim packets hello\n");
- ++writes;
- }
-
- if (PIM_DEBUG_PIM_J_P) {
- vty_out (vty, "debug pim packets joins\n");
- ++writes;
- }
-
- if (PIM_DEBUG_PIM_REG) {
- vty_out (vty, "debug pim packets register\n");
- ++writes;
- }
-
- if (PIM_DEBUG_STATIC) {
- vty_out (vty, "debug pim static\n");
- ++writes;
- }
-
- return writes;
+ int writes = 0;
+
+ if (PIM_DEBUG_MSDP_EVENTS) {
+ vty_out(vty, "debug msdp events\n");
+ ++writes;
+ }
+ if (PIM_DEBUG_MSDP_PACKETS) {
+ vty_out(vty, "debug msdp packets\n");
+ ++writes;
+ }
+ if (PIM_DEBUG_MSDP_INTERNAL) {
+ vty_out(vty, "debug msdp internal\n");
+ ++writes;
+ }
+ if (PIM_DEBUG_IGMP_EVENTS) {
+ vty_out(vty, "debug igmp events\n");
+ ++writes;
+ }
+ if (PIM_DEBUG_IGMP_PACKETS) {
+ vty_out(vty, "debug igmp packets\n");
+ ++writes;
+ }
+ if (PIM_DEBUG_IGMP_TRACE) {
+ vty_out(vty, "debug igmp trace\n");
+ ++writes;
+ }
+ if (PIM_DEBUG_IGMP_TRACE_DETAIL) {
+ vty_out(vty, "debug igmp trace detail\n");
+ ++writes;
+ }
+
+ if (PIM_DEBUG_MROUTE) {
+ vty_out(vty, "debug mroute\n");
+ ++writes;
+ }
+
+ if (PIM_DEBUG_MROUTE_DETAIL) {
+ vty_out(vty, "debug mroute detail\n");
+ ++writes;
+ }
+
+ if (PIM_DEBUG_PIM_EVENTS) {
+ vty_out(vty, "debug pim events\n");
+ ++writes;
+ }
+ if (PIM_DEBUG_PIM_PACKETS) {
+ vty_out(vty, "debug pim packets\n");
+ ++writes;
+ }
+ if (PIM_DEBUG_PIM_PACKETDUMP_SEND) {
+ vty_out(vty, "debug pim packet-dump send\n");
+ ++writes;
+ }
+ if (PIM_DEBUG_PIM_PACKETDUMP_RECV) {
+ vty_out(vty, "debug pim packet-dump receive\n");
+ ++writes;
+ }
+
+ if (PIM_DEBUG_PIM_TRACE) {
+ vty_out(vty, "debug pim trace\n");
+ ++writes;
+ }
+ if (PIM_DEBUG_PIM_TRACE_DETAIL) {
+ vty_out(vty, "debug pim trace detail\n");
+ ++writes;
+ }
+
+ if (PIM_DEBUG_ZEBRA) {
+ vty_out(vty, "debug pim zebra\n");
+ ++writes;
+ }
+
+ if (PIM_DEBUG_SSMPINGD) {
+ vty_out(vty, "debug ssmpingd\n");
+ ++writes;
+ }
+
+ if (PIM_DEBUG_PIM_HELLO) {
+ vty_out(vty, "debug pim packets hello\n");
+ ++writes;
+ }
+
+ if (PIM_DEBUG_PIM_J_P) {
+ vty_out(vty, "debug pim packets joins\n");
+ ++writes;
+ }
+
+ if (PIM_DEBUG_PIM_REG) {
+ vty_out(vty, "debug pim packets register\n");
+ ++writes;
+ }
+
+ if (PIM_DEBUG_STATIC) {
+ vty_out(vty, "debug pim static\n");
+ ++writes;
+ }
+
+ return writes;
}
int pim_global_config_write(struct vty *vty)
{
- int writes = 0;
- struct pim_ssm *ssm = pimg->ssm_info;
-
- writes += pim_msdp_config_write (vty);
-
- if (!pimg->send_v6_secondary)
- {
- vty_out (vty, "no ip pim send-v6-secondary\n");
- ++writes;
- }
-
- writes += pim_rp_config_write (vty);
-
- if (qpim_register_suppress_time != PIM_REGISTER_SUPPRESSION_TIME_DEFAULT)
- {
- vty_out (vty, "ip pim register-suppress-time %d\n",
- qpim_register_suppress_time);
- ++writes;
- }
- if (qpim_t_periodic != PIM_DEFAULT_T_PERIODIC)
- {
- vty_out (vty, "ip pim join-prune-interval %d\n",
- qpim_t_periodic);
- ++writes;
- }
- if (qpim_keep_alive_time != PIM_KEEPALIVE_PERIOD)
- {
- vty_out (vty, "ip pim keep-alive-timer %d\n",
- qpim_keep_alive_time);
- ++writes;
- }
- if (qpim_packet_process != PIM_DEFAULT_PACKET_PROCESS)
- {
- vty_out (vty, "ip pim packets %d\n",
- qpim_packet_process);
- ++writes;
- }
- if (ssm->plist_name)
- {
- vty_out (vty, "ip pim ssm prefix-list %s\n",
- ssm->plist_name);
- ++writes;
- }
- if (pimg->spt.switchover == PIM_SPT_INFINITY)
- {
- if (pimg->spt.plist)
- vty_out (vty, "ip pim spt-switchover infinity-and-beyond prefix-list %s\n",
- pimg->spt.plist);
- else
- vty_out (vty,"ip pim spt-switchover infinity-and-beyond\n");
- ++writes;
- }
- if (qpim_ecmp_rebalance_enable)
- {
- vty_out (vty, "ip pim ecmp rebalance\n");
- ++writes;
- }
- else if (qpim_ecmp_enable)
- {
- vty_out (vty, "ip pim ecmp\n");
- ++writes;
- }
- if (qpim_ssmpingd_list) {
- struct listnode *node;
- struct ssmpingd_sock *ss;
- vty_out (vty, "!\n");
- ++writes;
- for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list, node, ss)) {
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str));
- vty_out (vty, "ip ssmpingd %s\n", source_str);
- ++writes;
- }
- }
-
- return writes;
-}
+ int writes = 0;
+ struct pim_ssm *ssm = pimg->ssm_info;
-int pim_interface_config_write(struct vty *vty)
-{
- int writes = 0;
- struct listnode *node;
- struct interface *ifp;
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) {
-
- /* IF name */
- vty_out (vty, "interface %s\n", ifp->name);
- ++writes;
-
- if (ifp->info) {
- struct pim_interface *pim_ifp = ifp->info;
-
- if (PIM_IF_TEST_PIM(pim_ifp->options)) {
- vty_out (vty, " ip pim sm\n");
- ++writes;
- }
-
- /* IF ip pim drpriority */
- if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
- vty_out (vty, " ip pim drpriority %u\n",pim_ifp->pim_dr_priority);
- ++writes;
- }
-
- /* IF ip pim hello */
- if (pim_ifp->pim_hello_period != PIM_DEFAULT_HELLO_PERIOD) {
- vty_out(vty, " ip pim hello %d", pim_ifp->pim_hello_period);
- if (pim_ifp->pim_default_holdtime != -1)
- vty_out(vty, " %d", pim_ifp->pim_default_holdtime);
- vty_out (vty, "\n");
- }
-
- /* update source */
- if (PIM_INADDR_ISNOT_ANY(pim_ifp->update_source)) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", pim_ifp->update_source, src_str,
- sizeof(src_str));
- vty_out (vty, " ip pim use-source %s\n", src_str);
- ++writes;
- }
-
- /* IF ip igmp */
- if (PIM_IF_TEST_IGMP(pim_ifp->options)) {
- vty_out (vty, " ip igmp\n");
- ++writes;
- }
-
- /* ip igmp version */
- if (pim_ifp->igmp_version != IGMP_DEFAULT_VERSION)
- {
- vty_out (vty, " ip igmp version %d\n",
- pim_ifp->igmp_version);
- ++writes;
- }
-
- /* IF ip igmp query-interval */
- if (pim_ifp->igmp_default_query_interval != IGMP_GENERAL_QUERY_INTERVAL)
- {
- vty_out (vty, " ip igmp query-interval %d\n",
- pim_ifp->igmp_default_query_interval);
- ++writes;
+ writes += pim_msdp_config_write(vty);
+
+ if (!pimg->send_v6_secondary) {
+ vty_out(vty, "no ip pim send-v6-secondary\n");
+ ++writes;
}
- /* IF ip igmp query-max-response-time */
- if (pim_ifp->igmp_query_max_response_time_dsec != IGMP_QUERY_MAX_RESPONSE_TIME_DSEC)
- {
- vty_out (vty, " ip igmp query-max-response-time %d\n",
- pim_ifp->igmp_query_max_response_time_dsec);
- ++writes;
+ writes += pim_rp_config_write(vty);
+
+ if (qpim_register_suppress_time
+ != PIM_REGISTER_SUPPRESSION_TIME_DEFAULT) {
+ vty_out(vty, "ip pim register-suppress-time %d\n",
+ qpim_register_suppress_time);
+ ++writes;
}
+ if (qpim_t_periodic != PIM_DEFAULT_T_PERIODIC) {
+ vty_out(vty, "ip pim join-prune-interval %d\n",
+ qpim_t_periodic);
+ ++writes;
+ }
+ if (qpim_keep_alive_time != PIM_KEEPALIVE_PERIOD) {
+ vty_out(vty, "ip pim keep-alive-timer %d\n",
+ qpim_keep_alive_time);
+ ++writes;
+ }
+ if (qpim_packet_process != PIM_DEFAULT_PACKET_PROCESS) {
+ vty_out(vty, "ip pim packets %d\n", qpim_packet_process);
+ ++writes;
+ }
+ if (ssm->plist_name) {
+ vty_out(vty, "ip pim ssm prefix-list %s\n", ssm->plist_name);
+ ++writes;
+ }
+ if (pimg->spt.switchover == PIM_SPT_INFINITY) {
+ if (pimg->spt.plist)
+ vty_out(vty,
+ "ip pim spt-switchover infinity-and-beyond prefix-list %s\n",
+ pimg->spt.plist);
+ else
+ vty_out(vty,
+ "ip pim spt-switchover infinity-and-beyond\n");
+ ++writes;
+ }
+ if (qpim_ecmp_rebalance_enable) {
+ vty_out(vty, "ip pim ecmp rebalance\n");
+ ++writes;
+ } else if (qpim_ecmp_enable) {
+ vty_out(vty, "ip pim ecmp\n");
+ ++writes;
+ }
+ if (qpim_ssmpingd_list) {
+ struct listnode *node;
+ struct ssmpingd_sock *ss;
+ vty_out(vty, "!\n");
+ ++writes;
+ for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list, node, ss)) {
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", ss->source_addr, source_str,
+ sizeof(source_str));
+ vty_out(vty, "ip ssmpingd %s\n", source_str);
+ ++writes;
+ }
+ }
+
+ return writes;
+}
- /* IF ip igmp join */
- if (pim_ifp->igmp_join_list) {
+int pim_interface_config_write(struct vty *vty)
+{
+ int writes = 0;
struct listnode *node;
- struct igmp_join *ij;
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_join_list, node, ij)) {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<grp?>", ij->group_addr, group_str, sizeof(group_str));
- inet_ntop(AF_INET, &ij->source_addr, source_str, sizeof(source_str));
- vty_out (vty, " ip igmp join %s %s\n",
- group_str,source_str);
- ++writes;
+ struct interface *ifp;
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+
+ /* IF name */
+ vty_out(vty, "interface %s\n", ifp->name);
+ ++writes;
+
+ if (ifp->info) {
+ struct pim_interface *pim_ifp = ifp->info;
+
+ if (PIM_IF_TEST_PIM(pim_ifp->options)) {
+ vty_out(vty, " ip pim sm\n");
+ ++writes;
+ }
+
+ /* IF ip pim drpriority */
+ if (pim_ifp->pim_dr_priority
+ != PIM_DEFAULT_DR_PRIORITY) {
+ vty_out(vty, " ip pim drpriority %u\n",
+ pim_ifp->pim_dr_priority);
+ ++writes;
+ }
+
+ /* IF ip pim hello */
+ if (pim_ifp->pim_hello_period
+ != PIM_DEFAULT_HELLO_PERIOD) {
+ vty_out(vty, " ip pim hello %d",
+ pim_ifp->pim_hello_period);
+ if (pim_ifp->pim_default_holdtime != -1)
+ vty_out(vty, " %d",
+ pim_ifp->pim_default_holdtime);
+ vty_out(vty, "\n");
+ }
+
+ /* update source */
+ if (PIM_INADDR_ISNOT_ANY(pim_ifp->update_source)) {
+ char src_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<src?>", pim_ifp->update_source,
+ src_str, sizeof(src_str));
+ vty_out(vty, " ip pim use-source %s\n",
+ src_str);
+ ++writes;
+ }
+
+ /* IF ip igmp */
+ if (PIM_IF_TEST_IGMP(pim_ifp->options)) {
+ vty_out(vty, " ip igmp\n");
+ ++writes;
+ }
+
+ /* ip igmp version */
+ if (pim_ifp->igmp_version != IGMP_DEFAULT_VERSION) {
+ vty_out(vty, " ip igmp version %d\n",
+ pim_ifp->igmp_version);
+ ++writes;
+ }
+
+ /* IF ip igmp query-interval */
+ if (pim_ifp->igmp_default_query_interval
+ != IGMP_GENERAL_QUERY_INTERVAL) {
+ vty_out(vty, " ip igmp query-interval %d\n",
+ pim_ifp->igmp_default_query_interval);
+ ++writes;
+ }
+
+ /* IF ip igmp query-max-response-time */
+ if (pim_ifp->igmp_query_max_response_time_dsec
+ != IGMP_QUERY_MAX_RESPONSE_TIME_DSEC) {
+ vty_out(vty,
+ " ip igmp query-max-response-time %d\n",
+ pim_ifp->igmp_query_max_response_time_dsec);
+ ++writes;
+ }
+
+ /* IF ip igmp join */
+ if (pim_ifp->igmp_join_list) {
+ struct listnode *node;
+ struct igmp_join *ij;
+ for (ALL_LIST_ELEMENTS_RO(
+ pim_ifp->igmp_join_list, node,
+ ij)) {
+ char group_str[INET_ADDRSTRLEN];
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<grp?>", ij->group_addr,
+ group_str,
+ sizeof(group_str));
+ inet_ntop(AF_INET, &ij->source_addr,
+ source_str,
+ sizeof(source_str));
+ vty_out(vty, " ip igmp join %s %s\n",
+ group_str, source_str);
+ ++writes;
+ }
+ }
+
+ writes += pim_static_write_mroute(vty, ifp);
+ }
+ vty_out(vty, "!\n");
+ ++writes;
+ /* PIM BFD write */
+ pim_bfd_write_config(vty, ifp);
}
- }
-
- writes += pim_static_write_mroute (vty, ifp);
- }
- vty_out (vty, "!\n");
- ++writes;
- /* PIM BFD write */
- pim_bfd_write_config (vty, ifp);
- }
- return writes;
+ return writes;
}
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index b4fff9712..c5cca7d1b 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -58,906 +58,950 @@ static struct zclient *zclient = NULL;
static int pim_router_id_update_zebra(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
- struct prefix router_id;
+ struct prefix router_id;
- zebra_router_id_update_read(zclient->ibuf, &router_id);
+ zebra_router_id_update_read(zclient->ibuf, &router_id);
- return 0;
+ return 0;
}
static int pim_zebra_if_add(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
- struct interface *ifp;
-
- /*
- zebra api adds/dels interfaces using the same call
- interface_add_read below, see comments in lib/zclient.c
- */
- ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
- if (!ifp)
- return 0;
-
- if (PIM_DEBUG_ZEBRA) {
- zlog_debug("%s: %s index %d flags %ld metric %d mtu %d operative %d",
- __PRETTY_FUNCTION__,
- ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric,
- ifp->mtu, if_is_operative(ifp));
- }
-
- if (if_is_operative(ifp))
- pim_if_addr_add_all(ifp);
-
- return 0;
+ struct interface *ifp;
+
+ /*
+ zebra api adds/dels interfaces using the same call
+ interface_add_read below, see comments in lib/zclient.c
+ */
+ ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
+ if (!ifp)
+ return 0;
+
+ if (PIM_DEBUG_ZEBRA) {
+ zlog_debug(
+ "%s: %s index %d flags %ld metric %d mtu %d operative %d",
+ __PRETTY_FUNCTION__, ifp->name, ifp->ifindex,
+ (long)ifp->flags, ifp->metric, ifp->mtu,
+ if_is_operative(ifp));
+ }
+
+ if (if_is_operative(ifp))
+ pim_if_addr_add_all(ifp);
+
+ return 0;
}
static int pim_zebra_if_del(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
- struct interface *ifp;
-
- /*
- zebra api adds/dels interfaces using the same call
- interface_add_read below, see comments in lib/zclient.c
-
- comments in lib/zclient.c seem to indicate that calling
- zebra_interface_add_read is the correct call, but that
- results in an attemted out of bounds read which causes
- pimd to assert. Other clients use zebra_interface_state_read
- and it appears to work just fine.
- */
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
- if (!ifp)
- return 0;
-
- if (PIM_DEBUG_ZEBRA) {
- zlog_debug("%s: %s index %d flags %ld metric %d mtu %d operative %d",
- __PRETTY_FUNCTION__,
- ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric,
- ifp->mtu, if_is_operative(ifp));
- }
-
- if (!if_is_operative(ifp))
- pim_if_addr_del_all(ifp);
-
- return 0;
+ struct interface *ifp;
+
+ /*
+ zebra api adds/dels interfaces using the same call
+ interface_add_read below, see comments in lib/zclient.c
+
+ comments in lib/zclient.c seem to indicate that calling
+ zebra_interface_add_read is the correct call, but that
+ results in an attemted out of bounds read which causes
+ pimd to assert. Other clients use zebra_interface_state_read
+ and it appears to work just fine.
+ */
+ ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
+ if (!ifp)
+ return 0;
+
+ if (PIM_DEBUG_ZEBRA) {
+ zlog_debug(
+ "%s: %s index %d flags %ld metric %d mtu %d operative %d",
+ __PRETTY_FUNCTION__, ifp->name, ifp->ifindex,
+ (long)ifp->flags, ifp->metric, ifp->mtu,
+ if_is_operative(ifp));
+ }
+
+ if (!if_is_operative(ifp))
+ pim_if_addr_del_all(ifp);
+
+ return 0;
}
static int pim_zebra_if_state_up(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
- struct interface *ifp;
-
- /*
- zebra api notifies interface up/down events by using the same call
- zebra_interface_state_read below, see comments in lib/zclient.c
- */
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
- if (!ifp)
- return 0;
-
- if (PIM_DEBUG_ZEBRA) {
- zlog_debug("%s: %s index %d flags %ld metric %d mtu %d operative %d",
- __PRETTY_FUNCTION__,
- ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric,
- ifp->mtu, if_is_operative(ifp));
- }
-
- if (if_is_operative(ifp)) {
- /*
- pim_if_addr_add_all() suffices for bringing up both IGMP and PIM
- */
- pim_if_addr_add_all(ifp);
- }
-
- return 0;
+ struct interface *ifp;
+
+ /*
+ zebra api notifies interface up/down events by using the same call
+ zebra_interface_state_read below, see comments in lib/zclient.c
+ */
+ ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
+ if (!ifp)
+ return 0;
+
+ if (PIM_DEBUG_ZEBRA) {
+ zlog_debug(
+ "%s: %s index %d flags %ld metric %d mtu %d operative %d",
+ __PRETTY_FUNCTION__, ifp->name, ifp->ifindex,
+ (long)ifp->flags, ifp->metric, ifp->mtu,
+ if_is_operative(ifp));
+ }
+
+ if (if_is_operative(ifp)) {
+ /*
+ pim_if_addr_add_all() suffices for bringing up both IGMP and
+ PIM
+ */
+ pim_if_addr_add_all(ifp);
+ }
+
+ return 0;
}
static int pim_zebra_if_state_down(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
- struct interface *ifp;
-
- /*
- zebra api notifies interface up/down events by using the same call
- zebra_interface_state_read below, see comments in lib/zclient.c
- */
- ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
- if (!ifp)
- return 0;
-
- if (PIM_DEBUG_ZEBRA) {
- zlog_debug("%s: %s index %d flags %ld metric %d mtu %d operative %d",
- __PRETTY_FUNCTION__,
- ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric,
- ifp->mtu, if_is_operative(ifp));
- }
-
- if (!if_is_operative(ifp)) {
- pim_ifchannel_delete_all(ifp);
- /*
- pim_if_addr_del_all() suffices for shutting down IGMP,
- but not for shutting down PIM
- */
- pim_if_addr_del_all(ifp);
-
- /*
- pim_sock_delete() closes the socket, stops read and timer threads,
- and kills all neighbors.
- */
- if (ifp->info) {
- pim_sock_delete(ifp, "link down");
- }
- }
-
- if (ifp->info)
- pim_if_del_vif(ifp);
-
- return 0;
+ struct interface *ifp;
+
+ /*
+ zebra api notifies interface up/down events by using the same call
+ zebra_interface_state_read below, see comments in lib/zclient.c
+ */
+ ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
+ if (!ifp)
+ return 0;
+
+ if (PIM_DEBUG_ZEBRA) {
+ zlog_debug(
+ "%s: %s index %d flags %ld metric %d mtu %d operative %d",
+ __PRETTY_FUNCTION__, ifp->name, ifp->ifindex,
+ (long)ifp->flags, ifp->metric, ifp->mtu,
+ if_is_operative(ifp));
+ }
+
+ if (!if_is_operative(ifp)) {
+ pim_ifchannel_delete_all(ifp);
+ /*
+ pim_if_addr_del_all() suffices for shutting down IGMP,
+ but not for shutting down PIM
+ */
+ pim_if_addr_del_all(ifp);
+
+ /*
+ pim_sock_delete() closes the socket, stops read and timer
+ threads,
+ and kills all neighbors.
+ */
+ if (ifp->info) {
+ pim_sock_delete(ifp, "link down");
+ }
+ }
+
+ if (ifp->info)
+ pim_if_del_vif(ifp);
+
+ return 0;
}
#ifdef PIM_DEBUG_IFADDR_DUMP
static void dump_if_address(struct interface *ifp)
{
- struct connected *ifc;
- struct listnode *node;
-
- zlog_debug("%s %s: interface %s addresses:",
- __FILE__, __PRETTY_FUNCTION__,
- ifp->name);
-
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
- struct prefix *p = ifc->address;
-
- if (p->family != AF_INET)
- continue;
-
- zlog_debug("%s %s: interface %s address %s %s",
- __FILE__, __PRETTY_FUNCTION__,
- ifp->name,
- inet_ntoa(p->u.prefix4),
- CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ?
- "secondary" : "primary");
- }
+ struct connected *ifc;
+ struct listnode *node;
+
+ zlog_debug("%s %s: interface %s addresses:", __FILE__,
+ __PRETTY_FUNCTION__, ifp->name);
+
+ for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
+ struct prefix *p = ifc->address;
+
+ if (p->family != AF_INET)
+ continue;
+
+ zlog_debug("%s %s: interface %s address %s %s", __FILE__,
+ __PRETTY_FUNCTION__, ifp->name,
+ inet_ntoa(p->u.prefix4),
+ CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)
+ ? "secondary"
+ : "primary");
+ }
}
#endif
static int pim_zebra_if_address_add(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
- struct connected *c;
- struct prefix *p;
- struct pim_interface *pim_ifp;
-
- /*
- zebra api notifies address adds/dels events by using the same call
- interface_add_read below, see comments in lib/zclient.c
-
- zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, ...)
- will add address to interface list by calling
- connected_add_by_prefix()
- */
- c = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
- if (!c)
- return 0;
-
- pim_ifp = c->ifp->info;
- p = c->address;
-
- if (PIM_DEBUG_ZEBRA) {
- char buf[BUFSIZ];
- prefix2str(p, buf, BUFSIZ);
- zlog_debug("%s: %s connected IP address %s flags %u %s",
- __PRETTY_FUNCTION__,
- c->ifp->name, buf, c->flags,
- CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY) ? "secondary" : "primary");
-
+ struct connected *c;
+ struct prefix *p;
+ struct pim_interface *pim_ifp;
+
+ /*
+ zebra api notifies address adds/dels events by using the same call
+ interface_add_read below, see comments in lib/zclient.c
+
+ zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, ...)
+ will add address to interface list by calling
+ connected_add_by_prefix()
+ */
+ c = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
+ if (!c)
+ return 0;
+
+ pim_ifp = c->ifp->info;
+ p = c->address;
+
+ if (PIM_DEBUG_ZEBRA) {
+ char buf[BUFSIZ];
+ prefix2str(p, buf, BUFSIZ);
+ zlog_debug("%s: %s connected IP address %s flags %u %s",
+ __PRETTY_FUNCTION__, c->ifp->name, buf, c->flags,
+ CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)
+ ? "secondary"
+ : "primary");
+
#ifdef PIM_DEBUG_IFADDR_DUMP
- dump_if_address(c->ifp);
+ dump_if_address(c->ifp);
#endif
- }
+ }
- if (!CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)) {
- /* trying to add primary address */
+ if (!CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)) {
+ /* trying to add primary address */
- struct in_addr primary_addr = pim_find_primary_addr(c->ifp);
- if (p->family != AF_INET || primary_addr.s_addr != p->u.prefix4.s_addr) {
- if (PIM_DEBUG_ZEBRA) {
- /* but we had a primary address already */
+ struct in_addr primary_addr = pim_find_primary_addr(c->ifp);
+ if (p->family != AF_INET
+ || primary_addr.s_addr != p->u.prefix4.s_addr) {
+ if (PIM_DEBUG_ZEBRA) {
+ /* but we had a primary address already */
- char buf[BUFSIZ];
+ char buf[BUFSIZ];
- prefix2str(p, buf, BUFSIZ);
+ prefix2str(p, buf, BUFSIZ);
- zlog_warn("%s: %s : forcing secondary flag on %s",
- __PRETTY_FUNCTION__,
- c->ifp->name, buf);
- }
- SET_FLAG(c->flags, ZEBRA_IFA_SECONDARY);
- }
- }
+ zlog_warn(
+ "%s: %s : forcing secondary flag on %s",
+ __PRETTY_FUNCTION__, c->ifp->name, buf);
+ }
+ SET_FLAG(c->flags, ZEBRA_IFA_SECONDARY);
+ }
+ }
- pim_if_addr_add(c);
- if (pim_ifp)
- pim_rp_check_on_if_add(pim_ifp);
+ pim_if_addr_add(c);
+ if (pim_ifp)
+ pim_rp_check_on_if_add(pim_ifp);
- if (if_is_loopback (c->ifp))
- {
- struct listnode *ifnode;
- struct interface *ifp;
+ if (if_is_loopback(c->ifp)) {
+ struct listnode *ifnode;
+ struct interface *ifp;
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp))
- {
- if (!if_is_loopback (ifp) && if_is_operative (ifp))
- pim_if_addr_add_all (ifp);
- }
- }
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), ifnode,
+ ifp)) {
+ if (!if_is_loopback(ifp) && if_is_operative(ifp))
+ pim_if_addr_add_all(ifp);
+ }
+ }
- return 0;
+ return 0;
}
static int pim_zebra_if_address_del(int command, struct zclient *client,
zebra_size_t length, vrf_id_t vrf_id)
{
- struct connected *c;
- struct prefix *p;
-
- /*
- zebra api notifies address adds/dels events by using the same call
- interface_add_read below, see comments in lib/zclient.c
-
- zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, ...)
- will remove address from interface list by calling
- connected_delete_by_prefix()
- */
- c = zebra_interface_address_read(command, client->ibuf, vrf_id);
- if (!c)
- return 0;
-
- p = c->address;
- if (p->family == AF_INET)
- {
- if (PIM_DEBUG_ZEBRA) {
- char buf[BUFSIZ];
- prefix2str(p, buf, BUFSIZ);
- zlog_debug("%s: %s disconnected IP address %s flags %u %s",
- __PRETTY_FUNCTION__,
- c->ifp->name, buf, c->flags,
- CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY) ? "secondary" : "primary");
+ struct connected *c;
+ struct prefix *p;
+
+ /*
+ zebra api notifies address adds/dels events by using the same call
+ interface_add_read below, see comments in lib/zclient.c
+
+ zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, ...)
+ will remove address from interface list by calling
+ connected_delete_by_prefix()
+ */
+ c = zebra_interface_address_read(command, client->ibuf, vrf_id);
+ if (!c)
+ return 0;
+
+ p = c->address;
+ if (p->family == AF_INET) {
+ if (PIM_DEBUG_ZEBRA) {
+ char buf[BUFSIZ];
+ prefix2str(p, buf, BUFSIZ);
+ zlog_debug(
+ "%s: %s disconnected IP address %s flags %u %s",
+ __PRETTY_FUNCTION__, c->ifp->name, buf,
+ c->flags,
+ CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)
+ ? "secondary"
+ : "primary");
#ifdef PIM_DEBUG_IFADDR_DUMP
- dump_if_address(c->ifp);
+ dump_if_address(c->ifp);
#endif
- }
+ }
- pim_if_addr_del(c, 0);
- pim_rp_setup();
- pim_i_am_rp_re_evaluate();
- }
+ pim_if_addr_del(c, 0);
+ pim_rp_setup();
+ pim_i_am_rp_re_evaluate();
+ }
- connected_free (c);
- return 0;
+ connected_free(c);
+ return 0;
}
static void scan_upstream_rpf_cache()
{
- struct listnode *up_node;
- struct listnode *ifnode;
- struct listnode *up_nextnode;
- struct listnode *node;
- struct pim_upstream *up;
- struct interface *ifp;
-
- for (ALL_LIST_ELEMENTS(pim_upstream_list, up_node, up_nextnode, up)) {
- enum pim_rpf_result rpf_result;
- struct pim_rpf old;
- struct prefix nht_p;
-
- nht_p.family = AF_INET;
- nht_p.prefixlen = IPV4_MAX_BITLEN;
- nht_p.u.prefix4.s_addr = up->upstream_addr.s_addr;
- pim_resolve_upstream_nh (&nht_p);
-
- old.source_nexthop.interface = up->rpf.source_nexthop.interface;
- old.source_nexthop.nbr = up->rpf.source_nexthop.nbr;
- rpf_result = pim_rpf_update(up, &old, 0);
-
- if (rpf_result == PIM_RPF_FAILURE)
- continue;
-
- if (rpf_result == PIM_RPF_CHANGED) {
- struct pim_neighbor *nbr;
-
- nbr = pim_neighbor_find (old.source_nexthop.interface,
- old.rpf_addr.u.prefix4);
- if (nbr)
- pim_jp_agg_remove_group (nbr->upstream_jp_agg, up);
-
- /*
- * We have detected a case where we might need to rescan
- * the inherited o_list so do it.
- */
- if (up->channel_oil->oil_inherited_rescan)
- {
- pim_upstream_inherited_olist_decide (up);
- up->channel_oil->oil_inherited_rescan = 0;
- }
-
- if (up->join_state == PIM_UPSTREAM_JOINED) {
- /*
- * If we come up real fast we can be here
- * where the mroute has not been installed
- * so install it.
- */
- if (!up->channel_oil->installed)
- pim_mroute_add (up->channel_oil, __PRETTY_FUNCTION__);
-
- /*
- * RFC 4601: 4.5.7. Sending (S,G) Join/Prune Messages
- *
- * Transitions from Joined State
- *
- * RPF'(S,G) changes not due to an Assert
- *
- * The upstream (S,G) state machine remains in Joined
- * state. Send Join(S,G) to the new upstream neighbor, which is
- * the new value of RPF'(S,G). Send Prune(S,G) to the old
- * upstream neighbor, which is the old value of RPF'(S,G). Set
- * the Join Timer (JT) to expire after t_periodic seconds.
- */
- pim_jp_agg_switch_interface (&old, &up->rpf, up);
-
- pim_upstream_join_timer_restart(up, &old);
- } /* up->join_state == PIM_UPSTREAM_JOINED */
-
- /* FIXME can join_desired actually be changed by pim_rpf_update()
- returning PIM_RPF_CHANGED ? */
- pim_upstream_update_join_desired(up);
-
- } /* PIM_RPF_CHANGED */
-
- } /* for (qpim_upstream_list) */
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp))
- if (ifp->info)
- {
- struct pim_interface *pim_ifp = ifp->info;
- struct pim_iface_upstream_switch *us;
-
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->upstream_switch_list, node, us))
- {
- struct pim_rpf rpf;
- rpf.source_nexthop.interface = ifp;
- rpf.rpf_addr.u.prefix4 = us->address;
- pim_joinprune_send(&rpf, us->us);
- pim_jp_agg_clear_group(us->us);
- }
- }
+ struct listnode *up_node;
+ struct listnode *ifnode;
+ struct listnode *up_nextnode;
+ struct listnode *node;
+ struct pim_upstream *up;
+ struct interface *ifp;
+
+ for (ALL_LIST_ELEMENTS(pim_upstream_list, up_node, up_nextnode, up)) {
+ enum pim_rpf_result rpf_result;
+ struct pim_rpf old;
+ struct prefix nht_p;
+
+ nht_p.family = AF_INET;
+ nht_p.prefixlen = IPV4_MAX_BITLEN;
+ nht_p.u.prefix4.s_addr = up->upstream_addr.s_addr;
+ pim_resolve_upstream_nh(&nht_p);
+
+ old.source_nexthop.interface = up->rpf.source_nexthop.interface;
+ old.source_nexthop.nbr = up->rpf.source_nexthop.nbr;
+ rpf_result = pim_rpf_update(up, &old, 0);
+
+ if (rpf_result == PIM_RPF_FAILURE)
+ continue;
+
+ if (rpf_result == PIM_RPF_CHANGED) {
+ struct pim_neighbor *nbr;
+
+ nbr = pim_neighbor_find(old.source_nexthop.interface,
+ old.rpf_addr.u.prefix4);
+ if (nbr)
+ pim_jp_agg_remove_group(nbr->upstream_jp_agg,
+ up);
+
+ /*
+ * We have detected a case where we might need to rescan
+ * the inherited o_list so do it.
+ */
+ if (up->channel_oil->oil_inherited_rescan) {
+ pim_upstream_inherited_olist_decide(up);
+ up->channel_oil->oil_inherited_rescan = 0;
+ }
+
+ if (up->join_state == PIM_UPSTREAM_JOINED) {
+ /*
+ * If we come up real fast we can be here
+ * where the mroute has not been installed
+ * so install it.
+ */
+ if (!up->channel_oil->installed)
+ pim_mroute_add(up->channel_oil,
+ __PRETTY_FUNCTION__);
+
+ /*
+ * RFC 4601: 4.5.7. Sending (S,G) Join/Prune
+ * Messages
+ *
+ * Transitions from Joined State
+ *
+ * RPF'(S,G) changes not due to an Assert
+ *
+ * The upstream (S,G) state machine remains in
+ * Joined
+ * state. Send Join(S,G) to the new upstream
+ * neighbor, which is
+ * the new value of RPF'(S,G). Send Prune(S,G)
+ * to the old
+ * upstream neighbor, which is the old value of
+ * RPF'(S,G). Set
+ * the Join Timer (JT) to expire after
+ * t_periodic seconds.
+ */
+ pim_jp_agg_switch_interface(&old, &up->rpf, up);
+
+ pim_upstream_join_timer_restart(up, &old);
+ } /* up->join_state == PIM_UPSTREAM_JOINED */
+
+ /* FIXME can join_desired actually be changed by
+ pim_rpf_update()
+ returning PIM_RPF_CHANGED ? */
+ pim_upstream_update_join_desired(up);
+
+ } /* PIM_RPF_CHANGED */
+
+ } /* for (qpim_upstream_list) */
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), ifnode, ifp))
+ if (ifp->info) {
+ struct pim_interface *pim_ifp = ifp->info;
+ struct pim_iface_upstream_switch *us;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->upstream_switch_list,
+ node, us)) {
+ struct pim_rpf rpf;
+ rpf.source_nexthop.interface = ifp;
+ rpf.rpf_addr.u.prefix4 = us->address;
+ pim_joinprune_send(&rpf, us->us);
+ pim_jp_agg_clear_group(us->us);
+ }
+ }
}
-void
-pim_scan_individual_oil (struct channel_oil *c_oil, int in_vif_index)
+void pim_scan_individual_oil(struct channel_oil *c_oil, int in_vif_index)
{
- struct in_addr vif_source;
- int input_iface_vif_index;
- int old_vif_index;
-
- if (!pim_rp_set_upstream_addr (&vif_source, c_oil->oil.mfcc_origin, c_oil->oil.mfcc_mcastgrp))
- return;
-
- if (in_vif_index)
- input_iface_vif_index = in_vif_index;
- else
- {
- struct prefix src, grp;
-
- src.family = AF_INET;
- src.prefixlen = IPV4_MAX_BITLEN;
- src.u.prefix4 = vif_source;
- grp.family = AF_INET;
- grp.prefixlen = IPV4_MAX_BITLEN;
- grp.u.prefix4 = c_oil->oil.mfcc_mcastgrp;
-
- if (PIM_DEBUG_ZEBRA)
- {
- char source_str[INET_ADDRSTRLEN];
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- zlog_debug ("%s: channel_oil (%s, %s) upstream info is not present.",
- __PRETTY_FUNCTION__, source_str, group_str);
- }
- input_iface_vif_index = pim_ecmp_fib_lookup_if_vif_index(vif_source, &src, &grp);
- }
-
- if (input_iface_vif_index < 1)
- {
- if (PIM_DEBUG_ZEBRA)
- {
- char source_str[INET_ADDRSTRLEN];
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- zlog_debug("%s %s: could not find input interface(%d) for (S,G)=(%s,%s)",
- __FILE__, __PRETTY_FUNCTION__, c_oil->oil.mfcc_parent,
- source_str, group_str);
- }
- pim_mroute_del (c_oil, __PRETTY_FUNCTION__);
- return;
- }
-
- if (input_iface_vif_index == c_oil->oil.mfcc_parent)
- {
- if (!c_oil->installed)
- pim_mroute_add (c_oil, __PRETTY_FUNCTION__);
-
- /* RPF unchanged */
- return;
- }
-
- if (PIM_DEBUG_ZEBRA)
- {
- struct interface *old_iif = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
- struct interface *new_iif = pim_if_find_by_vif_index(input_iface_vif_index);
- char source_str[INET_ADDRSTRLEN];
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- zlog_debug("%s %s: (S,G)=(%s,%s) input interface changed from %s vif_index=%d to %s vif_index=%d",
- __FILE__, __PRETTY_FUNCTION__,
- source_str, group_str,
- old_iif->name, c_oil->oil.mfcc_parent,
- new_iif->name, input_iface_vif_index);
- }
-
- /* new iif loops to existing oif ? */
- if (c_oil->oil.mfcc_ttls[input_iface_vif_index])
- {
- struct interface *new_iif = pim_if_find_by_vif_index(input_iface_vif_index);
-
- if (PIM_DEBUG_ZEBRA) {
- char source_str[INET_ADDRSTRLEN];
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- zlog_debug("%s %s: (S,G)=(%s,%s) new iif loops to existing oif: %s vif_index=%d",
- __FILE__, __PRETTY_FUNCTION__,
- source_str, group_str,
- new_iif->name, input_iface_vif_index);
- }
- }
-
- /* update iif vif_index */
- old_vif_index = c_oil->oil.mfcc_parent;
- c_oil->oil.mfcc_parent = input_iface_vif_index;
-
- /* update kernel multicast forwarding cache (MFC) */
- if (pim_mroute_add(c_oil, __PRETTY_FUNCTION__))
- {
- if (PIM_DEBUG_MROUTE)
- {
- /* just log warning */
- struct interface *old_iif = pim_if_find_by_vif_index(old_vif_index);
- struct interface *new_iif = pim_if_find_by_vif_index(input_iface_vif_index);
- char source_str[INET_ADDRSTRLEN];
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
- zlog_debug("%s %s: (S,G)=(%s,%s) failure updating input interface from %s vif_index=%d to %s vif_index=%d",
- __FILE__, __PRETTY_FUNCTION__,
- source_str, group_str,
- old_iif ? old_iif->name : "<old_iif?>", c_oil->oil.mfcc_parent,
- new_iif ? new_iif->name : "<new_iif?>", input_iface_vif_index);
- }
- }
+ struct in_addr vif_source;
+ int input_iface_vif_index;
+ int old_vif_index;
+
+ if (!pim_rp_set_upstream_addr(&vif_source, c_oil->oil.mfcc_origin,
+ c_oil->oil.mfcc_mcastgrp))
+ return;
+
+ if (in_vif_index)
+ input_iface_vif_index = in_vif_index;
+ else {
+ struct prefix src, grp;
+
+ src.family = AF_INET;
+ src.prefixlen = IPV4_MAX_BITLEN;
+ src.u.prefix4 = vif_source;
+ grp.family = AF_INET;
+ grp.prefixlen = IPV4_MAX_BITLEN;
+ grp.u.prefix4 = c_oil->oil.mfcc_mcastgrp;
+
+ if (PIM_DEBUG_ZEBRA) {
+ char source_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
+ source_str, sizeof(source_str));
+ pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
+ group_str, sizeof(group_str));
+ zlog_debug(
+ "%s: channel_oil (%s, %s) upstream info is not present.",
+ __PRETTY_FUNCTION__, source_str, group_str);
+ }
+ input_iface_vif_index = pim_ecmp_fib_lookup_if_vif_index(
+ vif_source, &src, &grp);
+ }
+
+ if (input_iface_vif_index < 1) {
+ if (PIM_DEBUG_ZEBRA) {
+ char source_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
+ source_str, sizeof(source_str));
+ pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
+ group_str, sizeof(group_str));
+ zlog_debug(
+ "%s %s: could not find input interface(%d) for (S,G)=(%s,%s)",
+ __FILE__, __PRETTY_FUNCTION__,
+ c_oil->oil.mfcc_parent, source_str, group_str);
+ }
+ pim_mroute_del(c_oil, __PRETTY_FUNCTION__);
+ return;
+ }
+
+ if (input_iface_vif_index == c_oil->oil.mfcc_parent) {
+ if (!c_oil->installed)
+ pim_mroute_add(c_oil, __PRETTY_FUNCTION__);
+
+ /* RPF unchanged */
+ return;
+ }
+
+ if (PIM_DEBUG_ZEBRA) {
+ struct interface *old_iif =
+ pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
+ struct interface *new_iif =
+ pim_if_find_by_vif_index(input_iface_vif_index);
+ char source_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str,
+ sizeof(source_str));
+ pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str,
+ sizeof(group_str));
+ zlog_debug(
+ "%s %s: (S,G)=(%s,%s) input interface changed from %s vif_index=%d to %s vif_index=%d",
+ __FILE__, __PRETTY_FUNCTION__, source_str, group_str,
+ old_iif->name, c_oil->oil.mfcc_parent, new_iif->name,
+ input_iface_vif_index);
+ }
+
+ /* new iif loops to existing oif ? */
+ if (c_oil->oil.mfcc_ttls[input_iface_vif_index]) {
+ struct interface *new_iif =
+ pim_if_find_by_vif_index(input_iface_vif_index);
+
+ if (PIM_DEBUG_ZEBRA) {
+ char source_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
+ source_str, sizeof(source_str));
+ pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
+ group_str, sizeof(group_str));
+ zlog_debug(
+ "%s %s: (S,G)=(%s,%s) new iif loops to existing oif: %s vif_index=%d",
+ __FILE__, __PRETTY_FUNCTION__, source_str,
+ group_str, new_iif->name,
+ input_iface_vif_index);
+ }
+ }
+
+ /* update iif vif_index */
+ old_vif_index = c_oil->oil.mfcc_parent;
+ c_oil->oil.mfcc_parent = input_iface_vif_index;
+
+ /* update kernel multicast forwarding cache (MFC) */
+ if (pim_mroute_add(c_oil, __PRETTY_FUNCTION__)) {
+ if (PIM_DEBUG_MROUTE) {
+ /* just log warning */
+ struct interface *old_iif =
+ pim_if_find_by_vif_index(old_vif_index);
+ struct interface *new_iif =
+ pim_if_find_by_vif_index(input_iface_vif_index);
+ char source_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
+ source_str, sizeof(source_str));
+ pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
+ group_str, sizeof(group_str));
+ zlog_debug(
+ "%s %s: (S,G)=(%s,%s) failure updating input interface from %s vif_index=%d to %s vif_index=%d",
+ __FILE__, __PRETTY_FUNCTION__, source_str,
+ group_str,
+ old_iif ? old_iif->name : "<old_iif?>",
+ c_oil->oil.mfcc_parent,
+ new_iif ? new_iif->name : "<new_iif?>",
+ input_iface_vif_index);
+ }
+ }
}
void pim_scan_oil()
{
- struct listnode *node;
- struct listnode *nextnode;
- struct channel_oil *c_oil;
- ifindex_t ifindex;
- int vif_index = 0;
-
- qpim_scan_oil_last = pim_time_monotonic_sec();
- ++qpim_scan_oil_events;
-
- for (ALL_LIST_ELEMENTS(pim_channel_oil_list, node, nextnode, c_oil))
- {
- if (c_oil->up && c_oil->up->rpf.source_nexthop.interface)
- {
- ifindex = c_oil->up->rpf.source_nexthop.interface->ifindex;
- vif_index = pim_if_find_vifindex_by_ifindex (ifindex);
- /* Pass Current selected NH vif index to mroute download */
- if (vif_index)
- pim_scan_individual_oil (c_oil, vif_index);
- }
- else
- pim_scan_individual_oil (c_oil, 0);
- }
+ struct listnode *node;
+ struct listnode *nextnode;
+ struct channel_oil *c_oil;
+ ifindex_t ifindex;
+ int vif_index = 0;
+
+ qpim_scan_oil_last = pim_time_monotonic_sec();
+ ++qpim_scan_oil_events;
+
+ for (ALL_LIST_ELEMENTS(pim_channel_oil_list, node, nextnode, c_oil)) {
+ if (c_oil->up && c_oil->up->rpf.source_nexthop.interface) {
+ ifindex = c_oil->up->rpf.source_nexthop
+ .interface->ifindex;
+ vif_index = pim_if_find_vifindex_by_ifindex(ifindex);
+ /* Pass Current selected NH vif index to mroute download
+ */
+ if (vif_index)
+ pim_scan_individual_oil(c_oil, vif_index);
+ } else
+ pim_scan_individual_oil(c_oil, 0);
+ }
}
static int on_rpf_cache_refresh(struct thread *t)
{
- /* update PIM protocol state */
- scan_upstream_rpf_cache();
+ /* update PIM protocol state */
+ scan_upstream_rpf_cache();
- /* update kernel multicast forwarding cache (MFC) */
- pim_scan_oil();
+ /* update kernel multicast forwarding cache (MFC) */
+ pim_scan_oil();
- qpim_rpf_cache_refresh_last = pim_time_monotonic_sec();
- ++qpim_rpf_cache_refresh_events;
+ qpim_rpf_cache_refresh_last = pim_time_monotonic_sec();
+ ++qpim_rpf_cache_refresh_events;
- //It is called as part of pim_neighbor_add
- //pim_rp_setup ();
- return 0;
+ // It is called as part of pim_neighbor_add
+ // pim_rp_setup ();
+ return 0;
}
void sched_rpf_cache_refresh(void)
{
- ++qpim_rpf_cache_refresh_requests;
+ ++qpim_rpf_cache_refresh_requests;
- pim_rpf_set_refresh_time ();
+ pim_rpf_set_refresh_time();
- if (qpim_rpf_cache_refresher) {
- /* Refresh timer is already running */
- return;
- }
+ if (qpim_rpf_cache_refresher) {
+ /* Refresh timer is already running */
+ return;
+ }
- /* Start refresh timer */
+ /* Start refresh timer */
- if (PIM_DEBUG_ZEBRA) {
- zlog_debug("%s: triggering %ld msec timer",
- __PRETTY_FUNCTION__,
- qpim_rpf_cache_refresh_delay_msec);
- }
+ if (PIM_DEBUG_ZEBRA) {
+ zlog_debug("%s: triggering %ld msec timer", __PRETTY_FUNCTION__,
+ qpim_rpf_cache_refresh_delay_msec);
+ }
- thread_add_timer_msec(master, on_rpf_cache_refresh, 0,
- qpim_rpf_cache_refresh_delay_msec,
- &qpim_rpf_cache_refresher);
+ thread_add_timer_msec(master, on_rpf_cache_refresh, 0,
+ qpim_rpf_cache_refresh_delay_msec,
+ &qpim_rpf_cache_refresher);
}
-static void
-pim_zebra_connected (struct zclient *zclient)
+static void pim_zebra_connected(struct zclient *zclient)
{
- /* Send the client registration */
- bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER);
+ /* Send the client registration */
+ bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER);
- zclient_send_reg_requests (zclient, VRF_DEFAULT);
+ zclient_send_reg_requests(zclient, VRF_DEFAULT);
}
void pim_zebra_init(void)
{
- int i;
+ int i;
#ifdef HAVE_TCP_ZEBRA
- zlog_notice("zclient update contacting ZEBRA daemon at socket TCP %s,%d", "127.0.0.1", ZEBRA_PORT);
+ zlog_notice(
+ "zclient update contacting ZEBRA daemon at socket TCP %s,%d",
+ "127.0.0.1", ZEBRA_PORT);
#else
- zlog_notice("zclient update contacting ZEBRA daemon at socket UNIX %s", zclient_serv_path_get());
+ zlog_notice("zclient update contacting ZEBRA daemon at socket UNIX %s",
+ zclient_serv_path_get());
#endif
- /* Socket for receiving updates from Zebra daemon */
- zclient = zclient_new (master);
-
- zclient->zebra_connected = pim_zebra_connected;
- zclient->router_id_update = pim_router_id_update_zebra;
- zclient->interface_add = pim_zebra_if_add;
- zclient->interface_delete = pim_zebra_if_del;
- zclient->interface_up = pim_zebra_if_state_up;
- zclient->interface_down = pim_zebra_if_state_down;
- zclient->interface_address_add = pim_zebra_if_address_add;
- zclient->interface_address_delete = pim_zebra_if_address_del;
- zclient->nexthop_update = pim_parse_nexthop_update;
-
- zclient_init(zclient, ZEBRA_ROUTE_PIM, 0);
- if (PIM_DEBUG_PIM_TRACE) {
- zlog_info("zclient_init cleared redistribution request");
- }
-
- zassert(zclient->redist_default == ZEBRA_ROUTE_PIM);
-
- /* Request all redistribution */
- for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
- if (i == zclient->redist_default)
- continue;
- vrf_bitmap_set (zclient->redist[AFI_IP][i], VRF_DEFAULT);;
- if (PIM_DEBUG_PIM_TRACE) {
- zlog_debug("%s: requesting redistribution for %s (%i)",
- __PRETTY_FUNCTION__, zebra_route_string(i), i);
- }
- }
-
- /* Request default information */
- zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
- zclient, VRF_DEFAULT);
-
- if (PIM_DEBUG_PIM_TRACE) {
- zlog_info("%s: requesting default information redistribution",
- __PRETTY_FUNCTION__);
-
- zlog_notice("%s: zclient update socket initialized",
- __PRETTY_FUNCTION__);
- }
-
- zclient_lookup_new();
+ /* Socket for receiving updates from Zebra daemon */
+ zclient = zclient_new(master);
+
+ zclient->zebra_connected = pim_zebra_connected;
+ zclient->router_id_update = pim_router_id_update_zebra;
+ zclient->interface_add = pim_zebra_if_add;
+ zclient->interface_delete = pim_zebra_if_del;
+ zclient->interface_up = pim_zebra_if_state_up;
+ zclient->interface_down = pim_zebra_if_state_down;
+ zclient->interface_address_add = pim_zebra_if_address_add;
+ zclient->interface_address_delete = pim_zebra_if_address_del;
+ zclient->nexthop_update = pim_parse_nexthop_update;
+
+ zclient_init(zclient, ZEBRA_ROUTE_PIM, 0);
+ if (PIM_DEBUG_PIM_TRACE) {
+ zlog_info("zclient_init cleared redistribution request");
+ }
+
+ zassert(zclient->redist_default == ZEBRA_ROUTE_PIM);
+
+ /* Request all redistribution */
+ for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
+ if (i == zclient->redist_default)
+ continue;
+ vrf_bitmap_set(zclient->redist[AFI_IP][i], VRF_DEFAULT);
+ ;
+ if (PIM_DEBUG_PIM_TRACE) {
+ zlog_debug("%s: requesting redistribution for %s (%i)",
+ __PRETTY_FUNCTION__, zebra_route_string(i),
+ i);
+ }
+ }
+
+ /* Request default information */
+ zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient,
+ VRF_DEFAULT);
+
+ if (PIM_DEBUG_PIM_TRACE) {
+ zlog_info("%s: requesting default information redistribution",
+ __PRETTY_FUNCTION__);
+
+ zlog_notice("%s: zclient update socket initialized",
+ __PRETTY_FUNCTION__);
+ }
+
+ zclient_lookup_new();
}
void igmp_anysource_forward_start(struct igmp_group *group)
{
- struct igmp_source *source;
- struct in_addr src_addr = { .s_addr = 0 };
- /* Any source (*,G) is forwarded only if mode is EXCLUDE {empty} */
- zassert(group->group_filtermode_isexcl);
- zassert(listcount(group->group_source_list) < 1);
-
- source = source_new (group, src_addr);
- if (!source)
- {
- zlog_warn ("%s: Failure to create * source", __PRETTY_FUNCTION__);
- return;
- }
-
- igmp_source_forward_start (source);
+ struct igmp_source *source;
+ struct in_addr src_addr = {.s_addr = 0};
+ /* Any source (*,G) is forwarded only if mode is EXCLUDE {empty} */
+ zassert(group->group_filtermode_isexcl);
+ zassert(listcount(group->group_source_list) < 1);
+
+ source = source_new(group, src_addr);
+ if (!source) {
+ zlog_warn("%s: Failure to create * source",
+ __PRETTY_FUNCTION__);
+ return;
+ }
+
+ igmp_source_forward_start(source);
}
void igmp_anysource_forward_stop(struct igmp_group *group)
{
- struct igmp_source *source;
- struct in_addr star = { .s_addr = 0 };
+ struct igmp_source *source;
+ struct in_addr star = {.s_addr = 0};
- source = igmp_find_source_by_addr (group, star);
- if (source)
- igmp_source_forward_stop (source);
+ source = igmp_find_source_by_addr(group, star);
+ if (source)
+ igmp_source_forward_stop(source);
}
-static void
-igmp_source_forward_reevaluate_one(struct igmp_source *source)
+static void igmp_source_forward_reevaluate_one(struct igmp_source *source)
{
- struct prefix_sg sg;
- struct igmp_group *group = source->source_group;
- struct pim_ifchannel *ch;
-
- if ((source->source_addr.s_addr != INADDR_ANY) ||
- !IGMP_SOURCE_TEST_FORWARDING (source->source_flags))
- return;
-
- memset (&sg, 0, sizeof (struct prefix_sg));
- sg.src = source->source_addr;
- sg.grp = group->group_addr;
-
- ch = pim_ifchannel_find (group->group_igmp_sock->interface, &sg);
- if (pim_is_grp_ssm (group->group_addr))
- {
- /* If SSM group withdraw local membership */
- if (ch && (ch->local_ifmembership == PIM_IFMEMBERSHIP_INCLUDE))
- {
- if (PIM_DEBUG_PIM_EVENTS)
- zlog_debug ("local membership del for %s as G is now SSM",
- pim_str_sg_dump (&sg));
- pim_ifchannel_local_membership_del (group->group_igmp_sock->interface, &sg);
- }
- }
- else
- {
- /* If ASM group add local membership */
- if (!ch || (ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO))
- {
- if (PIM_DEBUG_PIM_EVENTS)
- zlog_debug ("local membership add for %s as G is now ASM",
- pim_str_sg_dump (&sg));
- pim_ifchannel_local_membership_add (group->group_igmp_sock->interface, &sg);
- }
- }
+ struct prefix_sg sg;
+ struct igmp_group *group = source->source_group;
+ struct pim_ifchannel *ch;
+
+ if ((source->source_addr.s_addr != INADDR_ANY)
+ || !IGMP_SOURCE_TEST_FORWARDING(source->source_flags))
+ return;
+
+ memset(&sg, 0, sizeof(struct prefix_sg));
+ sg.src = source->source_addr;
+ sg.grp = group->group_addr;
+
+ ch = pim_ifchannel_find(group->group_igmp_sock->interface, &sg);
+ if (pim_is_grp_ssm(group->group_addr)) {
+ /* If SSM group withdraw local membership */
+ if (ch
+ && (ch->local_ifmembership == PIM_IFMEMBERSHIP_INCLUDE)) {
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_debug(
+ "local membership del for %s as G is now SSM",
+ pim_str_sg_dump(&sg));
+ pim_ifchannel_local_membership_del(
+ group->group_igmp_sock->interface, &sg);
+ }
+ } else {
+ /* If ASM group add local membership */
+ if (!ch
+ || (ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO)) {
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_debug(
+ "local membership add for %s as G is now ASM",
+ pim_str_sg_dump(&sg));
+ pim_ifchannel_local_membership_add(
+ group->group_igmp_sock->interface, &sg);
+ }
+ }
}
-void
-igmp_source_forward_reevaluate_all(void)
+void igmp_source_forward_reevaluate_all(void)
{
- struct listnode *ifnode;
- struct interface *ifp;
-
- for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp))
- {
- struct pim_interface *pim_ifp = ifp->info;
- struct listnode *sock_node;
- struct igmp_sock *igmp;
-
- if (!pim_ifp)
- continue;
-
- /* scan igmp sockets */
- for (ALL_LIST_ELEMENTS_RO (pim_ifp->igmp_socket_list, sock_node, igmp))
- {
- struct listnode *grpnode;
- struct igmp_group *grp;
-
- /* scan igmp groups */
- for (ALL_LIST_ELEMENTS_RO (igmp->igmp_group_list, grpnode, grp))
- {
- struct listnode *srcnode;
- struct igmp_source *src;
-
- /* scan group sources */
- for (ALL_LIST_ELEMENTS_RO (grp->group_source_list,
- srcnode, src))
- {
- igmp_source_forward_reevaluate_one (src);
- } /* scan group sources */
- } /* scan igmp groups */
- } /* scan igmp sockets */
- } /* scan interfaces */
+ struct listnode *ifnode;
+ struct interface *ifp;
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), ifnode, ifp)) {
+ struct pim_interface *pim_ifp = ifp->info;
+ struct listnode *sock_node;
+ struct igmp_sock *igmp;
+
+ if (!pim_ifp)
+ continue;
+
+ /* scan igmp sockets */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
+ igmp)) {
+ struct listnode *grpnode;
+ struct igmp_group *grp;
+
+ /* scan igmp groups */
+ for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
+ grpnode, grp)) {
+ struct listnode *srcnode;
+ struct igmp_source *src;
+
+ /* scan group sources */
+ for (ALL_LIST_ELEMENTS_RO(
+ grp->group_source_list, srcnode,
+ src)) {
+ igmp_source_forward_reevaluate_one(src);
+ } /* scan group sources */
+ } /* scan igmp groups */
+ } /* scan igmp sockets */
+ } /* scan interfaces */
}
void igmp_source_forward_start(struct igmp_source *source)
{
- struct igmp_group *group;
- struct prefix_sg sg;
- int result;
- int input_iface_vif_index = 0;
-
- memset (&sg, 0, sizeof (struct prefix_sg));
- sg.src = source->source_addr;
- sg.grp = source->source_group->group_addr;
-
- if (PIM_DEBUG_IGMP_TRACE) {
- zlog_debug("%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d",
- __PRETTY_FUNCTION__,
- pim_str_sg_dump (&sg),
- source->source_group->group_igmp_sock->fd,
- source->source_group->group_igmp_sock->interface->name,
- IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
- }
-
- /* Prevent IGMP interface from installing multicast route multiple
- times */
- if (IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) {
- return;
- }
-
- group = source->source_group;
-
- if (!source->source_channel_oil) {
- struct in_addr vif_source;
- struct pim_interface *pim_oif;
- struct prefix nht_p, src, grp;
- int ret = 0;
- struct pim_nexthop_cache out_pnc;
- struct pim_nexthop nexthop;
- struct pim_upstream *up = NULL;
-
- if (!pim_rp_set_upstream_addr (&vif_source, source->source_addr, sg.grp))
- return;
-
- /* Register addr with Zebra NHT */
- nht_p.family = AF_INET;
- nht_p.prefixlen = IPV4_MAX_BITLEN;
- nht_p.u.prefix4 = vif_source;
- memset (&out_pnc, 0, sizeof (struct pim_nexthop_cache));
-
- src.family = AF_INET;
- src.prefixlen = IPV4_MAX_BITLEN;
- src.u.prefix4 = vif_source; //RP or Src address
- grp.family = AF_INET;
- grp.prefixlen = IPV4_MAX_BITLEN;
- grp.u.prefix4 = sg.grp;
-
- if ((ret = pim_find_or_track_nexthop (&nht_p, NULL, NULL, &out_pnc)) == 1)
- {
- if (out_pnc.nexthop_num)
- {
- up = pim_upstream_find (&sg);
- memset (&nexthop, 0, sizeof (struct pim_nexthop));
- if (up)
- memcpy (&nexthop, &up->rpf.source_nexthop, sizeof (struct pim_nexthop));
- //Compute PIM RPF using Cached nexthop
- pim_ecmp_nexthop_search (&out_pnc, &nexthop, &src, &grp, 0);
- if (nexthop.interface)
- input_iface_vif_index = pim_if_find_vifindex_by_ifindex (nexthop.interface->ifindex);
- }
- else
- {
- if (PIM_DEBUG_ZEBRA)
- {
- char buf1[INET_ADDRSTRLEN];
- char buf2[INET_ADDRSTRLEN];
- pim_inet4_dump("<source?>", nht_p.u.prefix4, buf1, sizeof(buf1));
- pim_inet4_dump("<source?>", grp.u.prefix4, buf2, sizeof(buf2));
- zlog_debug ("%s: NHT Nexthop not found for addr %s grp %s" ,
- __PRETTY_FUNCTION__, buf1, buf2);
- }
- }
- }
- else
- input_iface_vif_index = pim_ecmp_fib_lookup_if_vif_index(vif_source, &src, &grp);
-
- if (PIM_DEBUG_ZEBRA)
- {
- char buf2[INET_ADDRSTRLEN];
- pim_inet4_dump("<source?>", vif_source, buf2, sizeof(buf2));
- zlog_debug ("%s: NHT %s vif_source %s vif_index:%d ", __PRETTY_FUNCTION__,
- pim_str_sg_dump (&sg), buf2, input_iface_vif_index);
- }
-
- if (input_iface_vif_index < 1) {
- if (PIM_DEBUG_IGMP_TRACE)
- {
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
- zlog_debug("%s %s: could not find input interface for source %s",
- __FILE__, __PRETTY_FUNCTION__,
- source_str);
+ struct igmp_group *group;
+ struct prefix_sg sg;
+ int result;
+ int input_iface_vif_index = 0;
+
+ memset(&sg, 0, sizeof(struct prefix_sg));
+ sg.src = source->source_addr;
+ sg.grp = source->source_group->group_addr;
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ zlog_debug(
+ "%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(&sg),
+ source->source_group->group_igmp_sock->fd,
+ source->source_group->group_igmp_sock->interface->name,
+ IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
+ }
+
+ /* Prevent IGMP interface from installing multicast route multiple
+ times */
+ if (IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) {
+ return;
}
- return;
- }
-
- /*
- Protect IGMP against adding looped MFC entries created by both
- source and receiver attached to the same interface. See TODO
- T22.
- */
- pim_oif = source->source_group->group_igmp_sock->interface->info;
- if (!pim_oif) {
- if (PIM_DEBUG_IGMP_TRACE)
- {
- zlog_debug("%s: multicast not enabled on oif=%s ?",
- __PRETTY_FUNCTION__,
- source->source_group->group_igmp_sock->interface->name);
+
+ group = source->source_group;
+
+ if (!source->source_channel_oil) {
+ struct in_addr vif_source;
+ struct pim_interface *pim_oif;
+ struct prefix nht_p, src, grp;
+ int ret = 0;
+ struct pim_nexthop_cache out_pnc;
+ struct pim_nexthop nexthop;
+ struct pim_upstream *up = NULL;
+
+ if (!pim_rp_set_upstream_addr(&vif_source, source->source_addr,
+ sg.grp))
+ return;
+
+ /* Register addr with Zebra NHT */
+ nht_p.family = AF_INET;
+ nht_p.prefixlen = IPV4_MAX_BITLEN;
+ nht_p.u.prefix4 = vif_source;
+ memset(&out_pnc, 0, sizeof(struct pim_nexthop_cache));
+
+ src.family = AF_INET;
+ src.prefixlen = IPV4_MAX_BITLEN;
+ src.u.prefix4 = vif_source; // RP or Src address
+ grp.family = AF_INET;
+ grp.prefixlen = IPV4_MAX_BITLEN;
+ grp.u.prefix4 = sg.grp;
+
+ if ((ret = pim_find_or_track_nexthop(&nht_p, NULL, NULL,
+ &out_pnc))
+ == 1) {
+ if (out_pnc.nexthop_num) {
+ up = pim_upstream_find(&sg);
+ memset(&nexthop, 0, sizeof(struct pim_nexthop));
+ if (up)
+ memcpy(&nexthop,
+ &up->rpf.source_nexthop,
+ sizeof(struct pim_nexthop));
+ // Compute PIM RPF using Cached nexthop
+ pim_ecmp_nexthop_search(&out_pnc, &nexthop,
+ &src, &grp, 0);
+ if (nexthop.interface)
+ input_iface_vif_index =
+ pim_if_find_vifindex_by_ifindex(
+ nexthop.interface->ifindex);
+ } else {
+ if (PIM_DEBUG_ZEBRA) {
+ char buf1[INET_ADDRSTRLEN];
+ char buf2[INET_ADDRSTRLEN];
+ pim_inet4_dump("<source?>",
+ nht_p.u.prefix4, buf1,
+ sizeof(buf1));
+ pim_inet4_dump("<source?>",
+ grp.u.prefix4, buf2,
+ sizeof(buf2));
+ zlog_debug(
+ "%s: NHT Nexthop not found for addr %s grp %s",
+ __PRETTY_FUNCTION__, buf1,
+ buf2);
+ }
+ }
+ } else
+ input_iface_vif_index =
+ pim_ecmp_fib_lookup_if_vif_index(vif_source,
+ &src, &grp);
+
+ if (PIM_DEBUG_ZEBRA) {
+ char buf2[INET_ADDRSTRLEN];
+ pim_inet4_dump("<source?>", vif_source, buf2,
+ sizeof(buf2));
+ zlog_debug("%s: NHT %s vif_source %s vif_index:%d ",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(&sg),
+ buf2, input_iface_vif_index);
+ }
+
+ if (input_iface_vif_index < 1) {
+ if (PIM_DEBUG_IGMP_TRACE) {
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<source?>", source->source_addr,
+ source_str, sizeof(source_str));
+ zlog_debug(
+ "%s %s: could not find input interface for source %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ source_str);
+ }
+ return;
+ }
+
+ /*
+ Protect IGMP against adding looped MFC entries created by both
+ source and receiver attached to the same interface. See TODO
+ T22.
+ */
+ pim_oif =
+ source->source_group->group_igmp_sock->interface->info;
+ if (!pim_oif) {
+ if (PIM_DEBUG_IGMP_TRACE) {
+ zlog_debug(
+ "%s: multicast not enabled on oif=%s ?",
+ __PRETTY_FUNCTION__,
+ source->source_group->group_igmp_sock
+ ->interface->name);
+ }
+ return;
+ }
+
+ if (input_iface_vif_index == pim_oif->mroute_vif_index) {
+ /* ignore request for looped MFC entry */
+ if (PIM_DEBUG_IGMP_TRACE) {
+ zlog_debug(
+ "%s: ignoring request for looped MFC entry (S,G)=%s: igmp_sock=%d oif=%s vif_index=%d",
+ __PRETTY_FUNCTION__,
+ pim_str_sg_dump(&sg),
+ source->source_group->group_igmp_sock
+ ->fd,
+ source->source_group->group_igmp_sock
+ ->interface->name,
+ input_iface_vif_index);
+ }
+ return;
+ }
+
+ source->source_channel_oil =
+ pim_channel_oil_add(&sg, input_iface_vif_index);
+ if (!source->source_channel_oil) {
+ if (PIM_DEBUG_IGMP_TRACE) {
+ zlog_debug(
+ "%s %s: could not create OIL for channel (S,G)=%s",
+ __FILE__, __PRETTY_FUNCTION__,
+ pim_str_sg_dump(&sg));
+ }
+ return;
+ }
}
- return;
- }
-
- if (input_iface_vif_index == pim_oif->mroute_vif_index) {
- /* ignore request for looped MFC entry */
- if (PIM_DEBUG_IGMP_TRACE) {
- zlog_debug("%s: ignoring request for looped MFC entry (S,G)=%s: igmp_sock=%d oif=%s vif_index=%d",
- __PRETTY_FUNCTION__,
- pim_str_sg_dump (&sg),
- source->source_group->group_igmp_sock->fd,
- source->source_group->group_igmp_sock->interface->name,
- input_iface_vif_index);
- }
- return;
- }
-
- source->source_channel_oil = pim_channel_oil_add(&sg,
- input_iface_vif_index);
- if (!source->source_channel_oil) {
- if (PIM_DEBUG_IGMP_TRACE)
- {
- zlog_debug("%s %s: could not create OIL for channel (S,G)=%s",
- __FILE__, __PRETTY_FUNCTION__,
- pim_str_sg_dump (&sg));
+
+ result = pim_channel_add_oif(source->source_channel_oil,
+ group->group_igmp_sock->interface,
+ PIM_OIF_FLAG_PROTO_IGMP);
+ if (result) {
+ if (PIM_DEBUG_MROUTE) {
+ zlog_warn("%s: add_oif() failed with return=%d",
+ __func__, result);
+ }
+ return;
}
- return;
- }
- }
-
- result = pim_channel_add_oif(source->source_channel_oil,
- group->group_igmp_sock->interface,
- PIM_OIF_FLAG_PROTO_IGMP);
- if (result) {
- if (PIM_DEBUG_MROUTE)
- {
- zlog_warn("%s: add_oif() failed with return=%d",
- __func__, result);
- }
- return;
- }
-
- /*
- Feed IGMPv3-gathered local membership information into PIM
- per-interface (S,G) state.
- */
- if (!pim_ifchannel_local_membership_add(group->group_igmp_sock->interface, &sg))
- {
- if (PIM_DEBUG_MROUTE)
- zlog_warn ("%s: Failure to add local membership for %s",
- __PRETTY_FUNCTION__, pim_str_sg_dump (&sg));
- return;
- }
-
- IGMP_SOURCE_DO_FORWARDING(source->source_flags);
+
+ /*
+ Feed IGMPv3-gathered local membership information into PIM
+ per-interface (S,G) state.
+ */
+ if (!pim_ifchannel_local_membership_add(
+ group->group_igmp_sock->interface, &sg)) {
+ if (PIM_DEBUG_MROUTE)
+ zlog_warn("%s: Failure to add local membership for %s",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(&sg));
+ return;
+ }
+
+ IGMP_SOURCE_DO_FORWARDING(source->source_flags);
}
/*
@@ -966,203 +1010,219 @@ void igmp_source_forward_start(struct igmp_source *source)
*/
void igmp_source_forward_stop(struct igmp_source *source)
{
- struct igmp_group *group;
- struct prefix_sg sg;
- int result;
-
- memset (&sg, 0, sizeof (struct prefix_sg));
- sg.src = source->source_addr;
- sg.grp = source->source_group->group_addr;
-
- if (PIM_DEBUG_IGMP_TRACE) {
- zlog_debug("%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d",
- __PRETTY_FUNCTION__,
- pim_str_sg_dump (&sg),
- source->source_group->group_igmp_sock->fd,
- source->source_group->group_igmp_sock->interface->name,
- IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
- }
-
- /* Prevent IGMP interface from removing multicast route multiple
- times */
- if (!IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) {
- return;
- }
-
- group = source->source_group;
-
- /*
- It appears that in certain circumstances that
- igmp_source_forward_stop is called when IGMP forwarding
- was not enabled in oif_flags for this outgoing interface.
- Possibly because of multiple calls. When that happens, we
- enter the below if statement and this function returns early
- which in turn triggers the calling function to assert.
- Making the call to pim_channel_del_oif and ignoring the return code
- fixes the issue without ill effect, similar to
- pim_forward_stop below.
- */
- result = pim_channel_del_oif(source->source_channel_oil,
- group->group_igmp_sock->interface,
- PIM_OIF_FLAG_PROTO_IGMP);
- if (result) {
- if (PIM_DEBUG_IGMP_TRACE)
- zlog_debug("%s: pim_channel_del_oif() failed with return=%d",
- __func__, result);
- return;
- }
-
- /*
- Feed IGMPv3-gathered local membership information into PIM
- per-interface (S,G) state.
- */
- pim_ifchannel_local_membership_del(group->group_igmp_sock->interface,
- &sg);
-
- IGMP_SOURCE_DONT_FORWARDING(source->source_flags);
+ struct igmp_group *group;
+ struct prefix_sg sg;
+ int result;
+
+ memset(&sg, 0, sizeof(struct prefix_sg));
+ sg.src = source->source_addr;
+ sg.grp = source->source_group->group_addr;
+
+ if (PIM_DEBUG_IGMP_TRACE) {
+ zlog_debug(
+ "%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(&sg),
+ source->source_group->group_igmp_sock->fd,
+ source->source_group->group_igmp_sock->interface->name,
+ IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
+ }
+
+ /* Prevent IGMP interface from removing multicast route multiple
+ times */
+ if (!IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) {
+ return;
+ }
+
+ group = source->source_group;
+
+ /*
+ It appears that in certain circumstances that
+ igmp_source_forward_stop is called when IGMP forwarding
+ was not enabled in oif_flags for this outgoing interface.
+ Possibly because of multiple calls. When that happens, we
+ enter the below if statement and this function returns early
+ which in turn triggers the calling function to assert.
+ Making the call to pim_channel_del_oif and ignoring the return code
+ fixes the issue without ill effect, similar to
+ pim_forward_stop below.
+ */
+ result = pim_channel_del_oif(source->source_channel_oil,
+ group->group_igmp_sock->interface,
+ PIM_OIF_FLAG_PROTO_IGMP);
+ if (result) {
+ if (PIM_DEBUG_IGMP_TRACE)
+ zlog_debug(
+ "%s: pim_channel_del_oif() failed with return=%d",
+ __func__, result);
+ return;
+ }
+
+ /*
+ Feed IGMPv3-gathered local membership information into PIM
+ per-interface (S,G) state.
+ */
+ pim_ifchannel_local_membership_del(group->group_igmp_sock->interface,
+ &sg);
+
+ IGMP_SOURCE_DONT_FORWARDING(source->source_flags);
}
void pim_forward_start(struct pim_ifchannel *ch)
{
- struct pim_upstream *up = ch->upstream;
- uint32_t mask = PIM_OIF_FLAG_PROTO_PIM;
- int input_iface_vif_index = 0;
-
- if (PIM_DEBUG_PIM_TRACE) {
- char source_str[INET_ADDRSTRLEN];
- char group_str[INET_ADDRSTRLEN];
- char upstream_str[INET_ADDRSTRLEN];
-
- pim_inet4_dump("<source?>", ch->sg.src, source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", ch->sg.grp, group_str, sizeof(group_str));
- pim_inet4_dump("<upstream?>", up->upstream_addr, upstream_str, sizeof(upstream_str));
- zlog_debug("%s: (S,G)=(%s,%s) oif=%s (%s)",
- __PRETTY_FUNCTION__,
- source_str, group_str, ch->interface->name, upstream_str);
- }
-
- /* Resolve IIF for upstream as mroute_del sets mfcc_parent to MAXVIFS,
- as part of mroute_del called by pim_forward_stop.
- */
- if (!up->channel_oil ||
- (up->channel_oil && up->channel_oil->oil.mfcc_parent >= MAXVIFS))
- {
- struct prefix nht_p, src, grp;
- int ret = 0;
- struct pim_nexthop_cache out_pnc;
-
- /* Register addr with Zebra NHT */
- nht_p.family = AF_INET;
- nht_p.prefixlen = IPV4_MAX_BITLEN;
- nht_p.u.prefix4.s_addr = up->upstream_addr.s_addr;
- grp.family = AF_INET;
- grp.prefixlen = IPV4_MAX_BITLEN;
- grp.u.prefix4 = up->sg.grp;
- memset (&out_pnc, 0, sizeof (struct pim_nexthop_cache));
-
- if ((ret = pim_find_or_track_nexthop (&nht_p, NULL, NULL, &out_pnc)) == 1)
- {
- if (out_pnc.nexthop_num)
- {
- src.family = AF_INET;
- src.prefixlen = IPV4_MAX_BITLEN;
- src.u.prefix4 = up->upstream_addr; //RP or Src address
- grp.family = AF_INET;
- grp.prefixlen = IPV4_MAX_BITLEN;
- grp.u.prefix4 = up->sg.grp;
- //Compute PIM RPF using Cached nexthop
- if (pim_ecmp_nexthop_search (&out_pnc, &up->rpf.source_nexthop, &src, &grp, 0) == 0)
- input_iface_vif_index = pim_if_find_vifindex_by_ifindex (up->rpf.source_nexthop.interface->ifindex);
- else
- {
- if (PIM_DEBUG_TRACE)
- zlog_debug ("%s: Nexthop selection failed for %s ", __PRETTY_FUNCTION__, up->sg_str);
- }
- }
- else
- {
- if (PIM_DEBUG_ZEBRA)
- {
- char buf1[INET_ADDRSTRLEN];
- char buf2[INET_ADDRSTRLEN];
- pim_inet4_dump("<source?>", nht_p.u.prefix4, buf1, sizeof(buf1));
- pim_inet4_dump("<source?>", grp.u.prefix4, buf2, sizeof(buf2));
- zlog_debug ("%s: NHT pnc is NULL for addr %s grp %s" ,
- __PRETTY_FUNCTION__, buf1, buf2);
- }
- }
- }
- else
- input_iface_vif_index = pim_ecmp_fib_lookup_if_vif_index(up->upstream_addr, &src, &grp);
-
- if (input_iface_vif_index < 1)
- {
- if (PIM_DEBUG_PIM_TRACE)
- {
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<source?>", up->sg.src, source_str, sizeof(source_str));
- zlog_debug("%s %s: could not find input interface for source %s",
- __FILE__, __PRETTY_FUNCTION__,
- source_str);
- }
- return;
- }
- if (PIM_DEBUG_TRACE)
- {
- struct interface *in_intf = pim_if_find_by_vif_index (input_iface_vif_index);
- zlog_debug ("%s: Update channel_oil IIF %s VIFI %d entry %s ",
- __PRETTY_FUNCTION__, in_intf ? in_intf->name : "NIL",
- input_iface_vif_index, up->sg_str);
- }
- up->channel_oil = pim_channel_oil_add (&up->sg, input_iface_vif_index);
- if (!up->channel_oil)
- {
- if (PIM_DEBUG_PIM_TRACE)
- zlog_debug ("%s %s: could not create OIL for channel (S,G)=%s",
- __FILE__, __PRETTY_FUNCTION__, up->sg_str);
- return;
- }
- }
-
- if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
- mask = PIM_OIF_FLAG_PROTO_IGMP;
-
- pim_channel_add_oif (up->channel_oil, ch->interface, mask);
+ struct pim_upstream *up = ch->upstream;
+ uint32_t mask = PIM_OIF_FLAG_PROTO_PIM;
+ int input_iface_vif_index = 0;
+
+ if (PIM_DEBUG_PIM_TRACE) {
+ char source_str[INET_ADDRSTRLEN];
+ char group_str[INET_ADDRSTRLEN];
+ char upstream_str[INET_ADDRSTRLEN];
+
+ pim_inet4_dump("<source?>", ch->sg.src, source_str,
+ sizeof(source_str));
+ pim_inet4_dump("<group?>", ch->sg.grp, group_str,
+ sizeof(group_str));
+ pim_inet4_dump("<upstream?>", up->upstream_addr, upstream_str,
+ sizeof(upstream_str));
+ zlog_debug("%s: (S,G)=(%s,%s) oif=%s (%s)", __PRETTY_FUNCTION__,
+ source_str, group_str, ch->interface->name,
+ upstream_str);
+ }
+
+ /* Resolve IIF for upstream as mroute_del sets mfcc_parent to MAXVIFS,
+ as part of mroute_del called by pim_forward_stop.
+ */
+ if (!up->channel_oil
+ || (up->channel_oil
+ && up->channel_oil->oil.mfcc_parent >= MAXVIFS)) {
+ struct prefix nht_p, src, grp;
+ int ret = 0;
+ struct pim_nexthop_cache out_pnc;
+
+ /* Register addr with Zebra NHT */
+ nht_p.family = AF_INET;
+ nht_p.prefixlen = IPV4_MAX_BITLEN;
+ nht_p.u.prefix4.s_addr = up->upstream_addr.s_addr;
+ grp.family = AF_INET;
+ grp.prefixlen = IPV4_MAX_BITLEN;
+ grp.u.prefix4 = up->sg.grp;
+ memset(&out_pnc, 0, sizeof(struct pim_nexthop_cache));
+
+ if ((ret = pim_find_or_track_nexthop(&nht_p, NULL, NULL,
+ &out_pnc))
+ == 1) {
+ if (out_pnc.nexthop_num) {
+ src.family = AF_INET;
+ src.prefixlen = IPV4_MAX_BITLEN;
+ src.u.prefix4 =
+ up->upstream_addr; // RP or Src address
+ grp.family = AF_INET;
+ grp.prefixlen = IPV4_MAX_BITLEN;
+ grp.u.prefix4 = up->sg.grp;
+ // Compute PIM RPF using Cached nexthop
+ if (pim_ecmp_nexthop_search(
+ &out_pnc, &up->rpf.source_nexthop,
+ &src, &grp, 0)
+ == 0)
+ input_iface_vif_index =
+ pim_if_find_vifindex_by_ifindex(
+ up->rpf.source_nexthop
+ .interface->ifindex);
+ else {
+ if (PIM_DEBUG_TRACE)
+ zlog_debug(
+ "%s: Nexthop selection failed for %s ",
+ __PRETTY_FUNCTION__,
+ up->sg_str);
+ }
+ } else {
+ if (PIM_DEBUG_ZEBRA) {
+ char buf1[INET_ADDRSTRLEN];
+ char buf2[INET_ADDRSTRLEN];
+ pim_inet4_dump("<source?>",
+ nht_p.u.prefix4, buf1,
+ sizeof(buf1));
+ pim_inet4_dump("<source?>",
+ grp.u.prefix4, buf2,
+ sizeof(buf2));
+ zlog_debug(
+ "%s: NHT pnc is NULL for addr %s grp %s",
+ __PRETTY_FUNCTION__, buf1,
+ buf2);
+ }
+ }
+ } else
+ input_iface_vif_index =
+ pim_ecmp_fib_lookup_if_vif_index(
+ up->upstream_addr, &src, &grp);
+
+ if (input_iface_vif_index < 1) {
+ if (PIM_DEBUG_PIM_TRACE) {
+ char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<source?>", up->sg.src,
+ source_str, sizeof(source_str));
+ zlog_debug(
+ "%s %s: could not find input interface for source %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ source_str);
+ }
+ return;
+ }
+ if (PIM_DEBUG_TRACE) {
+ struct interface *in_intf =
+ pim_if_find_by_vif_index(input_iface_vif_index);
+ zlog_debug(
+ "%s: Update channel_oil IIF %s VIFI %d entry %s ",
+ __PRETTY_FUNCTION__,
+ in_intf ? in_intf->name : "NIL",
+ input_iface_vif_index, up->sg_str);
+ }
+ up->channel_oil =
+ pim_channel_oil_add(&up->sg, input_iface_vif_index);
+ if (!up->channel_oil) {
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug(
+ "%s %s: could not create OIL for channel (S,G)=%s",
+ __FILE__, __PRETTY_FUNCTION__,
+ up->sg_str);
+ return;
+ }
+ }
+
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
+ mask = PIM_OIF_FLAG_PROTO_IGMP;
+
+ pim_channel_add_oif(up->channel_oil, ch->interface, mask);
}
void pim_forward_stop(struct pim_ifchannel *ch)
{
- struct pim_upstream *up = ch->upstream;
+ struct pim_upstream *up = ch->upstream;
- if (PIM_DEBUG_PIM_TRACE) {
- zlog_debug("%s: (S,G)=%s oif=%s",
- __PRETTY_FUNCTION__,
- ch->sg_str, ch->interface->name);
- }
+ if (PIM_DEBUG_PIM_TRACE) {
+ zlog_debug("%s: (S,G)=%s oif=%s", __PRETTY_FUNCTION__,
+ ch->sg_str, ch->interface->name);
+ }
- pim_channel_del_oif(up->channel_oil,
- ch->interface,
- PIM_OIF_FLAG_PROTO_PIM);
+ pim_channel_del_oif(up->channel_oil, ch->interface,
+ PIM_OIF_FLAG_PROTO_PIM);
}
-void
-pim_zebra_zclient_update (struct vty *vty)
+void pim_zebra_zclient_update(struct vty *vty)
{
- vty_out(vty, "Zclient update socket: ");
-
- if (zclient) {
- vty_out (vty, "%d failures=%d\n", zclient->sock,
- zclient->fail);
- }
- else {
- vty_out (vty, "<null zclient>\n");
- }
+ vty_out(vty, "Zclient update socket: ");
+
+ if (zclient) {
+ vty_out(vty, "%d failures=%d\n", zclient->sock, zclient->fail);
+ } else {
+ vty_out(vty, "<null zclient>\n");
+ }
}
-struct zclient *pim_zebra_zclient_get (void)
+struct zclient *pim_zebra_zclient_get(void)
{
- if (zclient)
- return zclient;
- else
- return NULL;
+ if (zclient)
+ return zclient;
+ else
+ return NULL;
}
diff --git a/pimd/pim_zebra.h b/pimd/pim_zebra.h
index 37024073e..9b5450d66 100644
--- a/pimd/pim_zebra.h
+++ b/pimd/pim_zebra.h
@@ -27,9 +27,9 @@
#include "pim_ifchannel.h"
void pim_zebra_init(void);
-void pim_zebra_zclient_update (struct vty *vty);
+void pim_zebra_zclient_update(struct vty *vty);
-void pim_scan_individual_oil (struct channel_oil *c_oil, int in_vif_index);
+void pim_scan_individual_oil(struct channel_oil *c_oil, int in_vif_index);
void pim_scan_oil(void);
void igmp_anysource_forward_start(struct igmp_group *group);
@@ -43,5 +43,5 @@ void pim_forward_start(struct pim_ifchannel *ch);
void pim_forward_stop(struct pim_ifchannel *ch);
void sched_rpf_cache_refresh(void);
-struct zclient *pim_zebra_zclient_get (void);
+struct zclient *pim_zebra_zclient_get(void);
#endif /* PIM_ZEBRA_H */
diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c
index f405a39c9..027b18e12 100644
--- a/pimd/pim_zlookup.c
+++ b/pimd/pim_zlookup.c
@@ -43,491 +43,504 @@ static void zclient_lookup_sched(struct zclient *zlookup, int delay);
/* Connect to zebra for nexthop lookup. */
static int zclient_lookup_connect(struct thread *t)
{
- struct zclient *zlookup;
-
- zlookup = THREAD_ARG(t);
-
- if (zlookup->sock >= 0) {
- return 0;
- }
-
- if (zclient_socket_connect(zlookup) < 0) {
- ++zlookup->fail;
- zlog_warn("%s: failure connecting zclient socket: failures=%d",
- __PRETTY_FUNCTION__, zlookup->fail);
- }
- else {
- zlookup->fail = 0; /* reset counter on connection */
- }
-
- if (zlookup->sock < 0) {
- /* Since last connect failed, retry within 10 secs */
- zclient_lookup_sched(zlookup, 10);
- return -1;
- }
-
- return 0;
+ struct zclient *zlookup;
+
+ zlookup = THREAD_ARG(t);
+
+ if (zlookup->sock >= 0) {
+ return 0;
+ }
+
+ if (zclient_socket_connect(zlookup) < 0) {
+ ++zlookup->fail;
+ zlog_warn("%s: failure connecting zclient socket: failures=%d",
+ __PRETTY_FUNCTION__, zlookup->fail);
+ } else {
+ zlookup->fail = 0; /* reset counter on connection */
+ }
+
+ if (zlookup->sock < 0) {
+ /* Since last connect failed, retry within 10 secs */
+ zclient_lookup_sched(zlookup, 10);
+ return -1;
+ }
+
+ return 0;
}
/* Schedule connection with delay. */
static void zclient_lookup_sched(struct zclient *zlookup, int delay)
{
- thread_add_timer(master, zclient_lookup_connect, zlookup, delay,
- &zlookup->t_connect);
+ thread_add_timer(master, zclient_lookup_connect, zlookup, delay,
+ &zlookup->t_connect);
- zlog_notice("%s: zclient lookup connection scheduled for %d seconds",
- __PRETTY_FUNCTION__, delay);
+ zlog_notice("%s: zclient lookup connection scheduled for %d seconds",
+ __PRETTY_FUNCTION__, delay);
}
/* Schedule connection for now. */
static void zclient_lookup_sched_now(struct zclient *zlookup)
{
- thread_add_event(master, zclient_lookup_connect, zlookup, 0,
- &zlookup->t_connect);
+ thread_add_event(master, zclient_lookup_connect, zlookup, 0,
+ &zlookup->t_connect);
- zlog_notice("%s: zclient lookup immediate connection scheduled",
- __PRETTY_FUNCTION__);
+ zlog_notice("%s: zclient lookup immediate connection scheduled",
+ __PRETTY_FUNCTION__);
}
/* Schedule reconnection, if needed. */
static void zclient_lookup_reconnect(struct zclient *zlookup)
{
- if (zlookup->t_connect) {
- return;
- }
+ if (zlookup->t_connect) {
+ return;
+ }
- zclient_lookup_sched_now(zlookup);
+ zclient_lookup_sched_now(zlookup);
}
static void zclient_lookup_failed(struct zclient *zlookup)
{
- if (zlookup->sock >= 0) {
- if (close(zlookup->sock)) {
- zlog_warn("%s: closing fd=%d: errno=%d %s", __func__, zlookup->sock,
- errno, safe_strerror(errno));
- }
- zlookup->sock = -1;
- }
-
- zclient_lookup_reconnect(zlookup);
+ if (zlookup->sock >= 0) {
+ if (close(zlookup->sock)) {
+ zlog_warn("%s: closing fd=%d: errno=%d %s", __func__,
+ zlookup->sock, errno, safe_strerror(errno));
+ }
+ zlookup->sock = -1;
+ }
+
+ zclient_lookup_reconnect(zlookup);
}
-void
-zclient_lookup_free (void)
+void zclient_lookup_free(void)
{
- zclient_stop (zlookup);
- zclient_free (zlookup);
- zlookup = NULL;
+ zclient_stop(zlookup);
+ zclient_free(zlookup);
+ zlookup = NULL;
}
-void
-zclient_lookup_new (void)
+void zclient_lookup_new(void)
{
- zlookup = zclient_new (master);
- if (!zlookup) {
- zlog_err("%s: zclient_new() failure",
- __PRETTY_FUNCTION__);
- return;
- }
-
- zlookup->sock = -1;
- zlookup->t_connect = NULL;
+ zlookup = zclient_new(master);
+ if (!zlookup) {
+ zlog_err("%s: zclient_new() failure", __PRETTY_FUNCTION__);
+ return;
+ }
- zclient_lookup_sched_now(zlookup);
+ zlookup->sock = -1;
+ zlookup->t_connect = NULL;
- zlog_notice("%s: zclient lookup socket initialized",
- __PRETTY_FUNCTION__);
+ zclient_lookup_sched_now(zlookup);
+ zlog_notice("%s: zclient lookup socket initialized",
+ __PRETTY_FUNCTION__);
}
static int zclient_read_nexthop(struct zclient *zlookup,
struct pim_zlookup_nexthop nexthop_tab[],
- const int tab_size,
- struct in_addr addr)
+ const int tab_size, struct in_addr addr)
{
- int num_ifindex = 0;
- struct stream *s;
- const uint16_t MIN_LEN = 10; /* getipv4=4 getc=1 getl=4 getc=1 */
- uint16_t length;
- u_char marker;
- u_char version;
- vrf_id_t vrf_id;
- uint16_t command = 0;
- struct in_addr raddr;
- uint8_t distance;
- uint32_t metric;
- int nexthop_num;
- int i, err;
-
- if (PIM_DEBUG_PIM_TRACE_DETAIL) {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_debug("%s: addr=%s",
- __PRETTY_FUNCTION__,
- addr_str);
- }
-
- s = zlookup->ibuf;
-
- while (command != ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB)
- {
- stream_reset(s);
- err = zclient_read_header (s, zlookup->sock, &length, &marker, &version,
- &vrf_id, &command);
- if (err < 0) {
- zlog_err("%s %s: zclient_read_header() failed",
- __FILE__, __PRETTY_FUNCTION__);
- zclient_lookup_failed(zlookup);
- return -1;
- }
-
- if (length < MIN_LEN) {
- zlog_err("%s %s: failure reading zclient lookup socket: len=%d < MIN_LEN=%d",
- __FILE__, __PRETTY_FUNCTION__, length, MIN_LEN);
- zclient_lookup_failed(zlookup);
- return -2;
- }
- }
-
- raddr.s_addr = stream_get_ipv4(s);
-
- if (raddr.s_addr != addr.s_addr) {
- char addr_str[INET_ADDRSTRLEN];
- char raddr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- pim_inet4_dump("<raddr?>", raddr, raddr_str, sizeof(raddr_str));
- zlog_warn("%s: address mismatch: addr=%s raddr=%s",
- __PRETTY_FUNCTION__,
- addr_str, raddr_str);
- /* warning only */
- }
-
- distance = stream_getc(s);
- metric = stream_getl(s);
- nexthop_num = stream_getc(s);
-
- if (nexthop_num < 1) {
- zlog_err("%s: socket %d bad nexthop_num=%d",
- __func__, zlookup->sock, nexthop_num);
- return -6;
- }
-
- for (i = 0; i < nexthop_num; ++i) {
- enum nexthop_types_t nexthop_type;
- struct pim_neighbor *nbr;
- struct prefix p;
-
- nexthop_type = stream_getc(s);
- if (num_ifindex >= tab_size) {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_warn("%s %s: found too many nexthop ifindexes (%d > %d) for address %s",
- __FILE__, __PRETTY_FUNCTION__,
- (num_ifindex + 1), tab_size, addr_str);
- return num_ifindex;
- }
- switch (nexthop_type) {
- case NEXTHOP_TYPE_IFINDEX:
- case NEXTHOP_TYPE_IPV4_IFINDEX:
- case NEXTHOP_TYPE_IPV4:
- nexthop_tab[num_ifindex].nexthop_addr.family = AF_INET;
- if (nexthop_type == NEXTHOP_TYPE_IPV4_IFINDEX ||
- nexthop_type == NEXTHOP_TYPE_IPV4) {
- nexthop_tab[num_ifindex].nexthop_addr.u.prefix4.s_addr = stream_get_ipv4(s);
- }
- else {
- nexthop_tab[num_ifindex].nexthop_addr.u.prefix4.s_addr = PIM_NET_INADDR_ANY;
- }
- nexthop_tab[num_ifindex].ifindex = stream_getl(s);
- nexthop_tab[num_ifindex].protocol_distance = distance;
- nexthop_tab[num_ifindex].route_metric = metric;
- ++num_ifindex;
- break;
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- nexthop_tab[num_ifindex].nexthop_addr.family = AF_INET6;
- stream_get (&nexthop_tab[num_ifindex].nexthop_addr.u.prefix6,
- s,
- sizeof(struct in6_addr));
- nexthop_tab[num_ifindex].ifindex = stream_getl (s);
-
- p.family = AF_INET6;
- p.prefixlen = IPV6_MAX_PREFIXLEN;
- memcpy (&p.u.prefix6,
- &nexthop_tab[num_ifindex].nexthop_addr.u.prefix6,
- sizeof(struct in6_addr));
-
- /*
- * If we are sending v6 secondary assume we receive v6 secondary
- */
- if (pimg->send_v6_secondary)
- nbr = pim_neighbor_find_by_secondary(if_lookup_by_index (nexthop_tab[num_ifindex].ifindex, VRF_DEFAULT), &p);
- else
- nbr = pim_neighbor_find_if (if_lookup_by_index (nexthop_tab[num_ifindex].ifindex, VRF_DEFAULT));
- if (nbr)
- {
- nexthop_tab[num_ifindex].nexthop_addr.family = AF_INET;
- nexthop_tab[num_ifindex].nexthop_addr.u.prefix4 = nbr->source_addr;
- }
- ++num_ifindex;
- break;
- default:
- /* do nothing */
- {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_warn("%s %s: found non-ifindex nexthop type=%d for address %s",
- __FILE__, __PRETTY_FUNCTION__,
- nexthop_type, addr_str);
- }
- break;
- }
- }
-
- return num_ifindex;
+ int num_ifindex = 0;
+ struct stream *s;
+ const uint16_t MIN_LEN = 10; /* getipv4=4 getc=1 getl=4 getc=1 */
+ uint16_t length;
+ u_char marker;
+ u_char version;
+ vrf_id_t vrf_id;
+ uint16_t command = 0;
+ struct in_addr raddr;
+ uint8_t distance;
+ uint32_t metric;
+ int nexthop_num;
+ int i, err;
+
+ if (PIM_DEBUG_PIM_TRACE_DETAIL) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+ zlog_debug("%s: addr=%s", __PRETTY_FUNCTION__, addr_str);
+ }
+
+ s = zlookup->ibuf;
+
+ while (command != ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB) {
+ stream_reset(s);
+ err = zclient_read_header(s, zlookup->sock, &length, &marker,
+ &version, &vrf_id, &command);
+ if (err < 0) {
+ zlog_err("%s %s: zclient_read_header() failed",
+ __FILE__, __PRETTY_FUNCTION__);
+ zclient_lookup_failed(zlookup);
+ return -1;
+ }
+
+ if (length < MIN_LEN) {
+ zlog_err(
+ "%s %s: failure reading zclient lookup socket: len=%d < MIN_LEN=%d",
+ __FILE__, __PRETTY_FUNCTION__, length, MIN_LEN);
+ zclient_lookup_failed(zlookup);
+ return -2;
+ }
+ }
+
+ raddr.s_addr = stream_get_ipv4(s);
+
+ if (raddr.s_addr != addr.s_addr) {
+ char addr_str[INET_ADDRSTRLEN];
+ char raddr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+ pim_inet4_dump("<raddr?>", raddr, raddr_str, sizeof(raddr_str));
+ zlog_warn("%s: address mismatch: addr=%s raddr=%s",
+ __PRETTY_FUNCTION__, addr_str, raddr_str);
+ /* warning only */
+ }
+
+ distance = stream_getc(s);
+ metric = stream_getl(s);
+ nexthop_num = stream_getc(s);
+
+ if (nexthop_num < 1) {
+ zlog_err("%s: socket %d bad nexthop_num=%d", __func__,
+ zlookup->sock, nexthop_num);
+ return -6;
+ }
+
+ for (i = 0; i < nexthop_num; ++i) {
+ enum nexthop_types_t nexthop_type;
+ struct pim_neighbor *nbr;
+ struct prefix p;
+
+ nexthop_type = stream_getc(s);
+ if (num_ifindex >= tab_size) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str,
+ sizeof(addr_str));
+ zlog_warn(
+ "%s %s: found too many nexthop ifindexes (%d > %d) for address %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ (num_ifindex + 1), tab_size, addr_str);
+ return num_ifindex;
+ }
+ switch (nexthop_type) {
+ case NEXTHOP_TYPE_IFINDEX:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ case NEXTHOP_TYPE_IPV4:
+ nexthop_tab[num_ifindex].nexthop_addr.family = AF_INET;
+ if (nexthop_type == NEXTHOP_TYPE_IPV4_IFINDEX
+ || nexthop_type == NEXTHOP_TYPE_IPV4) {
+ nexthop_tab[num_ifindex]
+ .nexthop_addr.u.prefix4.s_addr =
+ stream_get_ipv4(s);
+ } else {
+ nexthop_tab[num_ifindex]
+ .nexthop_addr.u.prefix4.s_addr =
+ PIM_NET_INADDR_ANY;
+ }
+ nexthop_tab[num_ifindex].ifindex = stream_getl(s);
+ nexthop_tab[num_ifindex].protocol_distance = distance;
+ nexthop_tab[num_ifindex].route_metric = metric;
+ ++num_ifindex;
+ break;
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ nexthop_tab[num_ifindex].nexthop_addr.family = AF_INET6;
+ stream_get(&nexthop_tab[num_ifindex]
+ .nexthop_addr.u.prefix6,
+ s, sizeof(struct in6_addr));
+ nexthop_tab[num_ifindex].ifindex = stream_getl(s);
+
+ p.family = AF_INET6;
+ p.prefixlen = IPV6_MAX_PREFIXLEN;
+ memcpy(&p.u.prefix6,
+ &nexthop_tab[num_ifindex].nexthop_addr.u.prefix6,
+ sizeof(struct in6_addr));
+
+ /*
+ * If we are sending v6 secondary assume we receive v6
+ * secondary
+ */
+ if (pimg->send_v6_secondary)
+ nbr = pim_neighbor_find_by_secondary(
+ if_lookup_by_index(
+ nexthop_tab[num_ifindex]
+ .ifindex,
+ VRF_DEFAULT),
+ &p);
+ else
+ nbr = pim_neighbor_find_if(if_lookup_by_index(
+ nexthop_tab[num_ifindex].ifindex,
+ VRF_DEFAULT));
+ if (nbr) {
+ nexthop_tab[num_ifindex].nexthop_addr.family =
+ AF_INET;
+ nexthop_tab[num_ifindex]
+ .nexthop_addr.u.prefix4 =
+ nbr->source_addr;
+ }
+ ++num_ifindex;
+ break;
+ default:
+ /* do nothing */
+ {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str,
+ sizeof(addr_str));
+ zlog_warn(
+ "%s %s: found non-ifindex nexthop type=%d for address %s",
+ __FILE__, __PRETTY_FUNCTION__,
+ nexthop_type, addr_str);
+ }
+ break;
+ }
+ }
+
+ return num_ifindex;
}
-static int
-zclient_lookup_nexthop_once (struct pim_zlookup_nexthop nexthop_tab[],
- const int tab_size,
- struct in_addr addr)
+static int zclient_lookup_nexthop_once(struct pim_zlookup_nexthop nexthop_tab[],
+ const int tab_size, struct in_addr addr)
{
- struct stream *s;
- int ret;
-
- if (PIM_DEBUG_PIM_TRACE_DETAIL) {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_debug("%s: addr=%s",
- __PRETTY_FUNCTION__,
- addr_str);
- }
-
- /* Check socket. */
- if (zlookup->sock < 0) {
- zlog_err("%s %s: zclient lookup socket is not connected",
- __FILE__, __PRETTY_FUNCTION__);
- zclient_lookup_failed(zlookup);
- return -1;
- }
-
- s = zlookup->obuf;
- stream_reset(s);
- zclient_create_header(s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, VRF_DEFAULT);
- stream_put_in_addr(s, &addr);
- stream_putw_at(s, 0, stream_get_endp(s));
-
- ret = writen(zlookup->sock, s->data, stream_get_endp(s));
- if (ret < 0) {
- zlog_err("%s %s: writen() failure: %d writing to zclient lookup socket",
- __FILE__, __PRETTY_FUNCTION__, errno);
- zclient_lookup_failed(zlookup);
- return -2;
- }
- if (ret == 0) {
- zlog_err("%s %s: connection closed on zclient lookup socket",
- __FILE__, __PRETTY_FUNCTION__);
- zclient_lookup_failed(zlookup);
- return -3;
- }
-
- return zclient_read_nexthop(zlookup, nexthop_tab,
- tab_size, addr);
+ struct stream *s;
+ int ret;
+
+ if (PIM_DEBUG_PIM_TRACE_DETAIL) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+ zlog_debug("%s: addr=%s", __PRETTY_FUNCTION__, addr_str);
+ }
+
+ /* Check socket. */
+ if (zlookup->sock < 0) {
+ zlog_err("%s %s: zclient lookup socket is not connected",
+ __FILE__, __PRETTY_FUNCTION__);
+ zclient_lookup_failed(zlookup);
+ return -1;
+ }
+
+ s = zlookup->obuf;
+ stream_reset(s);
+ zclient_create_header(s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, VRF_DEFAULT);
+ stream_put_in_addr(s, &addr);
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ ret = writen(zlookup->sock, s->data, stream_get_endp(s));
+ if (ret < 0) {
+ zlog_err(
+ "%s %s: writen() failure: %d writing to zclient lookup socket",
+ __FILE__, __PRETTY_FUNCTION__, errno);
+ zclient_lookup_failed(zlookup);
+ return -2;
+ }
+ if (ret == 0) {
+ zlog_err("%s %s: connection closed on zclient lookup socket",
+ __FILE__, __PRETTY_FUNCTION__);
+ zclient_lookup_failed(zlookup);
+ return -3;
+ }
+
+ return zclient_read_nexthop(zlookup, nexthop_tab, tab_size, addr);
}
-int
-zclient_lookup_nexthop (struct pim_zlookup_nexthop nexthop_tab[],
- const int tab_size,
- struct in_addr addr,
- int max_lookup)
+int zclient_lookup_nexthop(struct pim_zlookup_nexthop nexthop_tab[],
+ const int tab_size, struct in_addr addr,
+ int max_lookup)
{
- int lookup;
- uint32_t route_metric = 0xFFFFFFFF;
- uint8_t protocol_distance = 0xFF;
-
- qpim_nexthop_lookups++;
-
- for (lookup = 0; lookup < max_lookup; ++lookup) {
- int num_ifindex;
- int first_ifindex;
- struct prefix nexthop_addr;
-
- num_ifindex = zclient_lookup_nexthop_once(nexthop_tab,
- tab_size, addr);
- if (num_ifindex < 1) {
- if (PIM_DEBUG_ZEBRA) {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_debug("%s %s: lookup=%d/%d: could not find nexthop ifindex for address %s",
- __FILE__, __PRETTY_FUNCTION__,
- lookup, max_lookup, addr_str);
- }
- return -1;
- }
-
- if (lookup < 1) {
- /* this is the non-recursive lookup - save original metric/distance */
- route_metric = nexthop_tab[0].route_metric;
- protocol_distance = nexthop_tab[0].protocol_distance;
- }
-
- /*
- * FIXME: Non-recursive nexthop ensured only for first ifindex.
- * However, recursive route lookup should really be fixed in zebra daemon.
- * See also TODO T24.
- *
- * So Zebra for NEXTHOP_TYPE_IPV4 returns the ifindex now since
- * it was being stored. This Doesn't solve all cases of
- * recursive lookup but for the most common types it does.
- */
- first_ifindex = nexthop_tab[0].ifindex;
- nexthop_addr = nexthop_tab[0].nexthop_addr;
- if (first_ifindex > 0) {
- /* found: first ifindex is non-recursive nexthop */
-
- if (lookup > 0) {
- /* Report non-recursive success after first lookup */
+ int lookup;
+ uint32_t route_metric = 0xFFFFFFFF;
+ uint8_t protocol_distance = 0xFF;
+
+ qpim_nexthop_lookups++;
+
+ for (lookup = 0; lookup < max_lookup; ++lookup) {
+ int num_ifindex;
+ int first_ifindex;
+ struct prefix nexthop_addr;
+
+ num_ifindex = zclient_lookup_nexthop_once(nexthop_tab, tab_size,
+ addr);
+ if (num_ifindex < 1) {
+ if (PIM_DEBUG_ZEBRA) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str,
+ sizeof(addr_str));
+ zlog_debug(
+ "%s %s: lookup=%d/%d: could not find nexthop ifindex for address %s",
+ __FILE__, __PRETTY_FUNCTION__, lookup,
+ max_lookup, addr_str);
+ }
+ return -1;
+ }
+
+ if (lookup < 1) {
+ /* this is the non-recursive lookup - save original
+ * metric/distance */
+ route_metric = nexthop_tab[0].route_metric;
+ protocol_distance = nexthop_tab[0].protocol_distance;
+ }
+
+ /*
+ * FIXME: Non-recursive nexthop ensured only for first ifindex.
+ * However, recursive route lookup should really be fixed in
+ * zebra daemon.
+ * See also TODO T24.
+ *
+ * So Zebra for NEXTHOP_TYPE_IPV4 returns the ifindex now since
+ * it was being stored. This Doesn't solve all cases of
+ * recursive lookup but for the most common types it does.
+ */
+ first_ifindex = nexthop_tab[0].ifindex;
+ nexthop_addr = nexthop_tab[0].nexthop_addr;
+ if (first_ifindex > 0) {
+ /* found: first ifindex is non-recursive nexthop */
+
+ if (lookup > 0) {
+ /* Report non-recursive success after first
+ * lookup */
+ if (PIM_DEBUG_ZEBRA) {
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr,
+ addr_str,
+ sizeof(addr_str));
+ zlog_debug(
+ "%s %s: lookup=%d/%d: found non-recursive ifindex=%d for address %s dist=%d met=%d",
+ __FILE__, __PRETTY_FUNCTION__,
+ lookup, max_lookup,
+ first_ifindex, addr_str,
+ nexthop_tab[0]
+ .protocol_distance,
+ nexthop_tab[0].route_metric);
+ }
+
+ /* use last address as nexthop address */
+ nexthop_tab[0].nexthop_addr.u.prefix4 = addr;
+
+ /* report original route metric/distance */
+ nexthop_tab[0].route_metric = route_metric;
+ nexthop_tab[0].protocol_distance =
+ protocol_distance;
+ }
+
+ return num_ifindex;
+ }
+
+ if (PIM_DEBUG_ZEBRA) {
+ char addr_str[INET_ADDRSTRLEN];
+ char nexthop_str[PREFIX_STRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str,
+ sizeof(addr_str));
+ pim_addr_dump("<nexthop?>", &nexthop_addr, nexthop_str,
+ sizeof(nexthop_str));
+ zlog_debug(
+ "%s %s: lookup=%d/%d: zebra returned recursive nexthop %s for address %s dist=%d met=%d",
+ __FILE__, __PRETTY_FUNCTION__, lookup,
+ max_lookup, nexthop_str, addr_str,
+ nexthop_tab[0].protocol_distance,
+ nexthop_tab[0].route_metric);
+ }
+
+ addr =
+ nexthop_addr.u.prefix4; /* use nexthop addr for
+ recursive lookup */
+
+ } /* for (max_lookup) */
+
if (PIM_DEBUG_ZEBRA) {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_debug("%s %s: lookup=%d/%d: found non-recursive ifindex=%d for address %s dist=%d met=%d",
- __FILE__, __PRETTY_FUNCTION__,
- lookup, max_lookup, first_ifindex, addr_str,
- nexthop_tab[0].protocol_distance,
- nexthop_tab[0].route_metric);
+ char addr_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+ zlog_warn(
+ "%s %s: lookup=%d/%d: failure searching recursive nexthop ifindex for address %s",
+ __FILE__, __PRETTY_FUNCTION__, lookup, max_lookup,
+ addr_str);
}
- /* use last address as nexthop address */
- nexthop_tab[0].nexthop_addr.u.prefix4 = addr;
-
- /* report original route metric/distance */
- nexthop_tab[0].route_metric = route_metric;
- nexthop_tab[0].protocol_distance = protocol_distance;
- }
-
- return num_ifindex;
- }
-
- if (PIM_DEBUG_ZEBRA) {
- char addr_str[INET_ADDRSTRLEN];
- char nexthop_str[PREFIX_STRLEN];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- pim_addr_dump("<nexthop?>", &nexthop_addr, nexthop_str, sizeof(nexthop_str));
- zlog_debug("%s %s: lookup=%d/%d: zebra returned recursive nexthop %s for address %s dist=%d met=%d",
- __FILE__, __PRETTY_FUNCTION__,
- lookup, max_lookup, nexthop_str, addr_str,
- nexthop_tab[0].protocol_distance,
- nexthop_tab[0].route_metric);
- }
-
- addr = nexthop_addr.u.prefix4; /* use nexthop addr for recursive lookup */
-
- } /* for (max_lookup) */
-
- if (PIM_DEBUG_ZEBRA) {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
- zlog_warn("%s %s: lookup=%d/%d: failure searching recursive nexthop ifindex for address %s",
- __FILE__, __PRETTY_FUNCTION__,
- lookup, max_lookup, addr_str);
- }
-
- return -2;
+ return -2;
}
-void
-pim_zlookup_show_ip_multicast (struct vty *vty)
+void pim_zlookup_show_ip_multicast(struct vty *vty)
{
- vty_out(vty, "Zclient lookup socket: ");
- if (zlookup) {
- vty_out (vty, "%d failures=%d\n", zlookup->sock,
- zlookup->fail);
- }
- else {
- vty_out (vty, "<null zclient>\n");
- }
+ vty_out(vty, "Zclient lookup socket: ");
+ if (zlookup) {
+ vty_out(vty, "%d failures=%d\n", zlookup->sock, zlookup->fail);
+ } else {
+ vty_out(vty, "<null zclient>\n");
+ }
}
-int
-pim_zlookup_sg_statistics (struct channel_oil *c_oil)
+int pim_zlookup_sg_statistics(struct channel_oil *c_oil)
{
- struct stream *s = zlookup->obuf;
- uint16_t command = 0;
- unsigned long long lastused;
- struct prefix_sg sg;
- int count = 0;
- int ret;
- struct interface *ifp = pim_if_find_by_vif_index (c_oil->oil.mfcc_parent);
-
- if (PIM_DEBUG_ZEBRA)
- {
- struct prefix_sg more;
-
- more.src = c_oil->oil.mfcc_origin;
- more.grp = c_oil->oil.mfcc_mcastgrp;
- zlog_debug ("Sending Request for New Channel Oil Information(%s) VIIF %d",
- pim_str_sg_dump (&more), c_oil->oil.mfcc_parent);
- }
-
- if (!ifp)
- return -1;
-
- stream_reset (s);
- zclient_create_header (s, ZEBRA_IPMR_ROUTE_STATS, VRF_DEFAULT);
- stream_put_in_addr (s, &c_oil->oil.mfcc_origin);
- stream_put_in_addr (s, &c_oil->oil.mfcc_mcastgrp);
- stream_putl (s, ifp->ifindex);
- stream_putw_at(s, 0, stream_get_endp(s));
-
- count = stream_get_endp (s);
- ret = writen (zlookup->sock, s->data, count);
- if (ret <= 0)
- {
- zlog_err("%s %s: writen() failure: %d writing to zclient lookup socket",
- __FILE__, __PRETTY_FUNCTION__, errno);
- return -1;
- }
-
- s = zlookup->ibuf;
-
- while (command != ZEBRA_IPMR_ROUTE_STATS)
- {
- int err;
- uint16_t length = 0;
- vrf_id_t vrf_id;
- u_char marker;
- u_char version;
-
- stream_reset (s);
- err = zclient_read_header (s, zlookup->sock, &length, &marker, &version,
- &vrf_id, &command);
- if (err < 0)
- {
- zlog_err ("%s %s: zclient_read_header() failed",
- __FILE__, __PRETTY_FUNCTION__);
- zclient_lookup_failed(zlookup);
- return -1;
- }
- }
-
- sg.src.s_addr = stream_get_ipv4 (s);
- sg.grp.s_addr = stream_get_ipv4 (s);
- if (sg.src.s_addr != c_oil->oil.mfcc_origin.s_addr ||
- sg.grp.s_addr != c_oil->oil.mfcc_mcastgrp.s_addr)
- {
- zlog_err ("%s: Received wrong %s information",
- __PRETTY_FUNCTION__, pim_str_sg_dump (&sg));
- zclient_lookup_failed (zlookup);
- return -3;
- }
-
- stream_get (&lastused, s, sizeof (lastused));
- ret = stream_getl (s);
-
- if (PIM_DEBUG_ZEBRA)
- zlog_debug ("Received %lld for %s success: %d", lastused, pim_str_sg_dump (&sg), ret);
-
- c_oil->cc.lastused = lastused;
-
- return 0;
+ struct stream *s = zlookup->obuf;
+ uint16_t command = 0;
+ unsigned long long lastused;
+ struct prefix_sg sg;
+ int count = 0;
+ int ret;
+ struct interface *ifp =
+ pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
+
+ if (PIM_DEBUG_ZEBRA) {
+ struct prefix_sg more;
+
+ more.src = c_oil->oil.mfcc_origin;
+ more.grp = c_oil->oil.mfcc_mcastgrp;
+ zlog_debug(
+ "Sending Request for New Channel Oil Information(%s) VIIF %d",
+ pim_str_sg_dump(&more), c_oil->oil.mfcc_parent);
+ }
+
+ if (!ifp)
+ return -1;
+
+ stream_reset(s);
+ zclient_create_header(s, ZEBRA_IPMR_ROUTE_STATS, VRF_DEFAULT);
+ stream_put_in_addr(s, &c_oil->oil.mfcc_origin);
+ stream_put_in_addr(s, &c_oil->oil.mfcc_mcastgrp);
+ stream_putl(s, ifp->ifindex);
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ count = stream_get_endp(s);
+ ret = writen(zlookup->sock, s->data, count);
+ if (ret <= 0) {
+ zlog_err(
+ "%s %s: writen() failure: %d writing to zclient lookup socket",
+ __FILE__, __PRETTY_FUNCTION__, errno);
+ return -1;
+ }
+
+ s = zlookup->ibuf;
+
+ while (command != ZEBRA_IPMR_ROUTE_STATS) {
+ int err;
+ uint16_t length = 0;
+ vrf_id_t vrf_id;
+ u_char marker;
+ u_char version;
+
+ stream_reset(s);
+ err = zclient_read_header(s, zlookup->sock, &length, &marker,
+ &version, &vrf_id, &command);
+ if (err < 0) {
+ zlog_err("%s %s: zclient_read_header() failed",
+ __FILE__, __PRETTY_FUNCTION__);
+ zclient_lookup_failed(zlookup);
+ return -1;
+ }
+ }
+
+ sg.src.s_addr = stream_get_ipv4(s);
+ sg.grp.s_addr = stream_get_ipv4(s);
+ if (sg.src.s_addr != c_oil->oil.mfcc_origin.s_addr
+ || sg.grp.s_addr != c_oil->oil.mfcc_mcastgrp.s_addr) {
+ zlog_err("%s: Received wrong %s information",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(&sg));
+ zclient_lookup_failed(zlookup);
+ return -3;
+ }
+
+ stream_get(&lastused, s, sizeof(lastused));
+ ret = stream_getl(s);
+
+ if (PIM_DEBUG_ZEBRA)
+ zlog_debug("Received %lld for %s success: %d", lastused,
+ pim_str_sg_dump(&sg), ret);
+
+ c_oil->cc.lastused = lastused;
+ return 0;
}
diff --git a/pimd/pim_zlookup.h b/pimd/pim_zlookup.h
index 08c8768d1..d168464ce 100644
--- a/pimd/pim_zlookup.h
+++ b/pimd/pim_zlookup.h
@@ -27,21 +27,20 @@
#define PIM_NEXTHOP_LOOKUP_MAX (3) /* max. recursive route lookup */
struct pim_zlookup_nexthop {
- struct prefix nexthop_addr;
- ifindex_t ifindex;
- uint32_t route_metric;
- uint8_t protocol_distance;
+ struct prefix nexthop_addr;
+ ifindex_t ifindex;
+ uint32_t route_metric;
+ uint8_t protocol_distance;
};
-void zclient_lookup_new (void);
-void zclient_lookup_free (void);
+void zclient_lookup_new(void);
+void zclient_lookup_free(void);
int zclient_lookup_nexthop(struct pim_zlookup_nexthop nexthop_tab[],
- const int tab_size,
- struct in_addr addr,
+ const int tab_size, struct in_addr addr,
int max_lookup);
-void pim_zlookup_show_ip_multicast (struct vty *vty);
+void pim_zlookup_show_ip_multicast(struct vty *vty);
-int pim_zlookup_sg_statistics (struct channel_oil *c_oil);
+int pim_zlookup_sg_statistics(struct channel_oil *c_oil);
#endif /* PIM_ZLOOKUP_H */
diff --git a/pimd/pimd.c b/pimd/pimd.c
index b1d566f51..89b235bed 100644
--- a/pimd/pimd.c
+++ b/pimd/pimd.c
@@ -45,289 +45,272 @@
#include "pim_zlookup.h"
#include "pim_nht.h"
-const char *const PIM_ALL_SYSTEMS = MCAST_ALL_SYSTEMS;
-const char *const PIM_ALL_ROUTERS = MCAST_ALL_ROUTERS;
-const char *const PIM_ALL_PIM_ROUTERS = MCAST_ALL_PIM_ROUTERS;
+const char *const PIM_ALL_SYSTEMS = MCAST_ALL_SYSTEMS;
+const char *const PIM_ALL_ROUTERS = MCAST_ALL_ROUTERS;
+const char *const PIM_ALL_PIM_ROUTERS = MCAST_ALL_PIM_ROUTERS;
const char *const PIM_ALL_IGMP_ROUTERS = MCAST_ALL_IGMP_ROUTERS;
-struct thread_master *master = NULL;
-uint32_t qpim_debugs = 0;
-int qpim_mroute_socket_fd = -1;
-int64_t qpim_mroute_socket_creation = 0; /* timestamp of creation */
-int qpim_t_periodic = PIM_DEFAULT_T_PERIODIC; /* Period between Join/Prune Messages */
-struct pim_assert_metric qpim_infinite_assert_metric;
-long qpim_rpf_cache_refresh_delay_msec = 50;
-struct thread *qpim_rpf_cache_refresher = NULL;
-int64_t qpim_rpf_cache_refresh_requests = 0;
-int64_t qpim_rpf_cache_refresh_events = 0;
-int64_t qpim_rpf_cache_refresh_last = 0;
-struct list *qpim_ssmpingd_list = NULL;
-struct in_addr qpim_ssmpingd_group_addr;
-int64_t qpim_scan_oil_events = 0;
-int64_t qpim_scan_oil_last = 0;
-int64_t qpim_mroute_add_events = 0;
-int64_t qpim_mroute_add_last = 0;
-int64_t qpim_mroute_del_events = 0;
-int64_t qpim_mroute_del_last = 0;
-struct list *qpim_static_route_list = NULL;
-unsigned int qpim_keep_alive_time = PIM_KEEPALIVE_PERIOD;
-signed int qpim_rp_keep_alive_time = 0;
-int64_t qpim_nexthop_lookups = 0;
-int qpim_packet_process = PIM_DEFAULT_PACKET_PROCESS;
-uint8_t qpim_ecmp_enable = 0;
-uint8_t qpim_ecmp_rebalance_enable = 0;
-struct pim_instance *pimg = NULL;
+struct thread_master *master = NULL;
+uint32_t qpim_debugs = 0;
+int qpim_mroute_socket_fd = -1;
+int64_t qpim_mroute_socket_creation = 0; /* timestamp of creation */
+int qpim_t_periodic =
+ PIM_DEFAULT_T_PERIODIC; /* Period between Join/Prune Messages */
+struct pim_assert_metric qpim_infinite_assert_metric;
+long qpim_rpf_cache_refresh_delay_msec = 50;
+struct thread *qpim_rpf_cache_refresher = NULL;
+int64_t qpim_rpf_cache_refresh_requests = 0;
+int64_t qpim_rpf_cache_refresh_events = 0;
+int64_t qpim_rpf_cache_refresh_last = 0;
+struct list *qpim_ssmpingd_list = NULL;
+struct in_addr qpim_ssmpingd_group_addr;
+int64_t qpim_scan_oil_events = 0;
+int64_t qpim_scan_oil_last = 0;
+int64_t qpim_mroute_add_events = 0;
+int64_t qpim_mroute_add_last = 0;
+int64_t qpim_mroute_del_events = 0;
+int64_t qpim_mroute_del_last = 0;
+struct list *qpim_static_route_list = NULL;
+unsigned int qpim_keep_alive_time = PIM_KEEPALIVE_PERIOD;
+signed int qpim_rp_keep_alive_time = 0;
+int64_t qpim_nexthop_lookups = 0;
+int qpim_packet_process = PIM_DEFAULT_PACKET_PROCESS;
+uint8_t qpim_ecmp_enable = 0;
+uint8_t qpim_ecmp_rebalance_enable = 0;
+struct pim_instance *pimg = NULL;
int32_t qpim_register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT;
int32_t qpim_register_probe_time = PIM_REGISTER_PROBE_TIME_DEFAULT;
-static struct pim_instance *pim_instance_init (vrf_id_t vrf_id, afi_t afi);
-static void pim_instance_terminate (void);
+static struct pim_instance *pim_instance_init(vrf_id_t vrf_id, afi_t afi);
+static void pim_instance_terminate(void);
-static int
-pim_vrf_new (struct vrf *vrf)
+static int pim_vrf_new(struct vrf *vrf)
{
- zlog_debug ("VRF Created: %s(%d)", vrf->name, vrf->vrf_id);
- return 0;
+ zlog_debug("VRF Created: %s(%d)", vrf->name, vrf->vrf_id);
+ return 0;
}
-static int
-pim_vrf_delete (struct vrf *vrf)
+static int pim_vrf_delete(struct vrf *vrf)
{
- zlog_debug ("VRF Deletion: %s(%d)", vrf->name, vrf->vrf_id);
- return 0;
+ zlog_debug("VRF Deletion: %s(%d)", vrf->name, vrf->vrf_id);
+ return 0;
}
-static int
-pim_vrf_enable (struct vrf *vrf)
+static int pim_vrf_enable(struct vrf *vrf)
{
- if (!vrf) // unexpected
- return -1;
-
- if (vrf->vrf_id == VRF_DEFAULT)
- {
- pimg = pim_instance_init (VRF_DEFAULT, AFI_IP);
- if (pimg == NULL)
- {
- zlog_err ("%s %s: pim class init failure ", __FILE__,
- __PRETTY_FUNCTION__);
- /*
- * We will crash and burn otherwise
- */
- exit(1);
- }
-
- pimg->send_v6_secondary = 1;
-
- }
- return 0;
+ if (!vrf) // unexpected
+ return -1;
+
+ if (vrf->vrf_id == VRF_DEFAULT) {
+ pimg = pim_instance_init(VRF_DEFAULT, AFI_IP);
+ if (pimg == NULL) {
+ zlog_err("%s %s: pim class init failure ", __FILE__,
+ __PRETTY_FUNCTION__);
+ /*
+ * We will crash and burn otherwise
+ */
+ exit(1);
+ }
+
+ pimg->send_v6_secondary = 1;
+ }
+ return 0;
}
-static int
-pim_vrf_disable (struct vrf *vrf)
+static int pim_vrf_disable(struct vrf *vrf)
{
- if (vrf->vrf_id == VRF_DEFAULT)
- return 0;
+ if (vrf->vrf_id == VRF_DEFAULT)
+ return 0;
- if (vrf->vrf_id == VRF_DEFAULT)
- pim_instance_terminate ();
+ if (vrf->vrf_id == VRF_DEFAULT)
+ pim_instance_terminate();
- /* Note: This is a callback, the VRF will be deleted by the caller. */
- return 0;
+ /* Note: This is a callback, the VRF will be deleted by the caller. */
+ return 0;
}
-void
-pim_vrf_init (void)
+void pim_vrf_init(void)
{
- vrf_init (pim_vrf_new,
- pim_vrf_enable,
- pim_vrf_disable,
- pim_vrf_delete);
+ vrf_init(pim_vrf_new, pim_vrf_enable, pim_vrf_disable, pim_vrf_delete);
}
-static void
-pim_vrf_terminate (void)
+static void pim_vrf_terminate(void)
{
- vrf_terminate ();
+ vrf_terminate();
}
/* Key generate for pim->rpf_hash */
-static unsigned int
-pim_rpf_hash_key (void *arg)
+static unsigned int pim_rpf_hash_key(void *arg)
{
- struct pim_nexthop_cache *r = (struct pim_nexthop_cache *) arg;
+ struct pim_nexthop_cache *r = (struct pim_nexthop_cache *)arg;
- return jhash_1word (r->rpf.rpf_addr.u.prefix4.s_addr, 0);
+ return jhash_1word(r->rpf.rpf_addr.u.prefix4.s_addr, 0);
}
/* Compare pim->rpf_hash node data */
-static int
-pim_rpf_equal (const void *arg1, const void *arg2)
+static int pim_rpf_equal(const void *arg1, const void *arg2)
{
- const struct pim_nexthop_cache *r1 =
- (const struct pim_nexthop_cache *) arg1;
- const struct pim_nexthop_cache *r2 =
- (const struct pim_nexthop_cache *) arg2;
+ const struct pim_nexthop_cache *r1 =
+ (const struct pim_nexthop_cache *)arg1;
+ const struct pim_nexthop_cache *r2 =
+ (const struct pim_nexthop_cache *)arg2;
- return prefix_same (&r1->rpf.rpf_addr, &r2->rpf.rpf_addr);
+ return prefix_same(&r1->rpf.rpf_addr, &r2->rpf.rpf_addr);
}
/* Cleanup pim->rpf_hash each node data */
-static void
-pim_rp_list_hash_clean (void *data)
+static void pim_rp_list_hash_clean(void *data)
{
- struct pim_nexthop_cache *pnc;
+ struct pim_nexthop_cache *pnc;
- pnc = (struct pim_nexthop_cache *) data;
- if (pnc->rp_list->count)
- list_delete_all_node (pnc->rp_list);
- if (pnc->upstream_list->count)
- list_delete_all_node (pnc->upstream_list);
+ pnc = (struct pim_nexthop_cache *)data;
+ if (pnc->rp_list->count)
+ list_delete_all_node(pnc->rp_list);
+ if (pnc->upstream_list->count)
+ list_delete_all_node(pnc->upstream_list);
}
-void
-pim_prefix_list_update (struct prefix_list *plist)
+void pim_prefix_list_update(struct prefix_list *plist)
{
- pim_rp_prefix_list_update (plist);
- pim_ssm_prefix_list_update (plist);
- pim_upstream_spt_prefix_list_update (plist);
+ pim_rp_prefix_list_update(plist);
+ pim_ssm_prefix_list_update(plist);
+ pim_upstream_spt_prefix_list_update(plist);
}
-static void
-pim_instance_terminate (void)
+static void pim_instance_terminate(void)
{
- /* Traverse and cleanup rpf_hash */
- if (pimg->rpf_hash)
- {
- hash_clean (pimg->rpf_hash, (void *) pim_rp_list_hash_clean);
- hash_free (pimg->rpf_hash);
- pimg->rpf_hash = NULL;
- }
-
- if (pimg->ssm_info)
- {
- pim_ssm_terminate (pimg->ssm_info);
- pimg->ssm_info = NULL;
- }
-
- XFREE (MTYPE_PIM_PIM_INSTANCE, pimg);
+ /* Traverse and cleanup rpf_hash */
+ if (pimg->rpf_hash) {
+ hash_clean(pimg->rpf_hash, (void *)pim_rp_list_hash_clean);
+ hash_free(pimg->rpf_hash);
+ pimg->rpf_hash = NULL;
+ }
+
+ if (pimg->ssm_info) {
+ pim_ssm_terminate(pimg->ssm_info);
+ pimg->ssm_info = NULL;
+ }
+
+ XFREE(MTYPE_PIM_PIM_INSTANCE, pimg);
}
static void pim_free()
{
- pim_ssmpingd_destroy();
+ pim_ssmpingd_destroy();
- pim_oil_terminate ();
+ pim_oil_terminate();
- pim_upstream_terminate ();
+ pim_upstream_terminate();
- if (qpim_static_route_list)
- list_free(qpim_static_route_list);
+ if (qpim_static_route_list)
+ list_free(qpim_static_route_list);
- pim_if_terminate ();
- pim_rp_free ();
+ pim_if_terminate();
+ pim_rp_free();
- pim_route_map_terminate();
+ pim_route_map_terminate();
- zclient_lookup_free ();
+ zclient_lookup_free();
- zprivs_terminate(&pimd_privs);
+ zprivs_terminate(&pimd_privs);
}
-static struct pim_instance *
-pim_instance_init (vrf_id_t vrf_id, afi_t afi)
+static struct pim_instance *pim_instance_init(vrf_id_t vrf_id, afi_t afi)
{
- struct pim_instance *pim;
+ struct pim_instance *pim;
- pim = XCALLOC (MTYPE_PIM_PIM_INSTANCE, sizeof (struct pim_instance));
- if (!pim)
- return NULL;
+ pim = XCALLOC(MTYPE_PIM_PIM_INSTANCE, sizeof(struct pim_instance));
+ if (!pim)
+ return NULL;
- pim->vrf_id = vrf_id;
- pim->afi = afi;
+ pim->vrf_id = vrf_id;
+ pim->afi = afi;
- pim->spt.switchover = PIM_SPT_IMMEDIATE;
- pim->spt.plist = NULL;
+ pim->spt.switchover = PIM_SPT_IMMEDIATE;
+ pim->spt.plist = NULL;
- pim->rpf_hash = hash_create_size (256, pim_rpf_hash_key, pim_rpf_equal, NULL);
+ pim->rpf_hash =
+ hash_create_size(256, pim_rpf_hash_key, pim_rpf_equal, NULL);
- if (PIM_DEBUG_ZEBRA)
- zlog_debug ("%s: NHT rpf hash init ", __PRETTY_FUNCTION__);
+ if (PIM_DEBUG_ZEBRA)
+ zlog_debug("%s: NHT rpf hash init ", __PRETTY_FUNCTION__);
- pim->ssm_info = pim_ssm_init (vrf_id);
- if (!pim->ssm_info) {
- pim_instance_terminate ();
- return NULL;
- }
+ pim->ssm_info = pim_ssm_init(vrf_id);
+ if (!pim->ssm_info) {
+ pim_instance_terminate();
+ return NULL;
+ }
- return pim;
+ return pim;
}
void pim_init()
{
- qpim_rp_keep_alive_time = PIM_RP_KEEPALIVE_PERIOD;
-
- pim_rp_init ();
-
- if (!inet_aton(PIM_ALL_PIM_ROUTERS, &qpim_all_pim_routers_addr)) {
- zlog_err("%s %s: could not solve %s to group address: errno=%d: %s",
- __FILE__, __PRETTY_FUNCTION__,
- PIM_ALL_PIM_ROUTERS, errno, safe_strerror(errno));
- zassert(0);
- return;
- }
-
- pim_oil_init ();
-
- pim_upstream_init ();
-
- qpim_static_route_list = list_new();
- if (!qpim_static_route_list) {
- zlog_err("%s %s: failure: static_route_list=list_new()",
- __FILE__, __PRETTY_FUNCTION__);
- return;
- }
- qpim_static_route_list->del = (void (*)(void *)) pim_static_route_free;
-
- pim_mroute_socket_enable();
-
-
- /*
- RFC 4601: 4.6.3. Assert Metrics
-
- assert_metric
- infinite_assert_metric() {
- return {1,infinity,infinity,0}
- }
- */
- qpim_infinite_assert_metric.rpt_bit_flag = 1;
- qpim_infinite_assert_metric.metric_preference = PIM_ASSERT_METRIC_PREFERENCE_MAX;
- qpim_infinite_assert_metric.route_metric = PIM_ASSERT_ROUTE_METRIC_MAX;
- qpim_infinite_assert_metric.ip_address.s_addr = INADDR_ANY;
-
- pim_if_init();
- pim_cmd_init();
- pim_ssmpingd_init();
+ qpim_rp_keep_alive_time = PIM_RP_KEEPALIVE_PERIOD;
+
+ pim_rp_init();
+
+ if (!inet_aton(PIM_ALL_PIM_ROUTERS, &qpim_all_pim_routers_addr)) {
+ zlog_err(
+ "%s %s: could not solve %s to group address: errno=%d: %s",
+ __FILE__, __PRETTY_FUNCTION__, PIM_ALL_PIM_ROUTERS,
+ errno, safe_strerror(errno));
+ zassert(0);
+ return;
+ }
+
+ pim_oil_init();
+
+ pim_upstream_init();
+
+ qpim_static_route_list = list_new();
+ if (!qpim_static_route_list) {
+ zlog_err("%s %s: failure: static_route_list=list_new()",
+ __FILE__, __PRETTY_FUNCTION__);
+ return;
+ }
+ qpim_static_route_list->del = (void (*)(void *))pim_static_route_free;
+
+ pim_mroute_socket_enable();
+
+
+ /*
+ RFC 4601: 4.6.3. Assert Metrics
+
+ assert_metric
+ infinite_assert_metric() {
+ return {1,infinity,infinity,0}
+ }
+ */
+ qpim_infinite_assert_metric.rpt_bit_flag = 1;
+ qpim_infinite_assert_metric.metric_preference =
+ PIM_ASSERT_METRIC_PREFERENCE_MAX;
+ qpim_infinite_assert_metric.route_metric = PIM_ASSERT_ROUTE_METRIC_MAX;
+ qpim_infinite_assert_metric.ip_address.s_addr = INADDR_ANY;
+
+ pim_if_init();
+ pim_cmd_init();
+ pim_ssmpingd_init();
}
void pim_terminate()
{
- struct zclient *zclient;
+ struct zclient *zclient;
- pim_free();
+ pim_free();
- /* reverse prefix_list_init */
- prefix_list_add_hook (NULL);
- prefix_list_delete_hook (NULL);
- prefix_list_reset ();
+ /* reverse prefix_list_init */
+ prefix_list_add_hook(NULL);
+ prefix_list_delete_hook(NULL);
+ prefix_list_reset();
- pim_vrf_terminate ();
+ pim_vrf_terminate();
- zclient = pim_zebra_zclient_get ();
- if (zclient)
- {
- zclient_stop (zclient);
- zclient_free (zclient);
- }
+ zclient = pim_zebra_zclient_get();
+ if (zclient) {
+ zclient_stop(zclient);
+ zclient_free(zclient);
+ }
}
diff --git a/pimd/pimd.h b/pimd/pimd.h
index 18520f57e..7934bce2d 100644
--- a/pimd/pimd.h
+++ b/pimd/pimd.h
@@ -65,10 +65,9 @@
* | Number of Joined Sources | Number of Pruned Sources |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
-#define PIM_JP_GROUP_HEADER_SIZE (PIM_ENCODED_IPV4_UCAST_SIZE + \
- 1 + 1 + 2 + \
- PIM_ENCODED_IPV4_GROUP_SIZE + \
- 2 + 2)
+#define PIM_JP_GROUP_HEADER_SIZE \
+ (PIM_ENCODED_IPV4_UCAST_SIZE + 1 + 1 + 2 + PIM_ENCODED_IPV4_GROUP_SIZE \
+ + 2 + 2)
#define PIM_PROTO_VERSION (2)
@@ -108,7 +107,6 @@
#define PIM_MASK_MSDP_PACKETS (1 << 20)
#define PIM_MASK_MSDP_INTERNAL (1 << 21)
-
/* PIM error codes */
#define PIM_SUCCESS 0
#define PIM_MALLOC_FAIL -1
@@ -127,34 +125,34 @@ const char *const PIM_ALL_ROUTERS;
const char *const PIM_ALL_PIM_ROUTERS;
const char *const PIM_ALL_IGMP_ROUTERS;
-extern struct thread_master *master;
+extern struct thread_master *master;
extern struct zebra_privs_t pimd_privs;
-uint32_t qpim_debugs;
-int qpim_mroute_socket_fd;
-int64_t qpim_mroute_socket_creation; /* timestamp of creation */
-struct in_addr qpim_all_pim_routers_addr;
-int qpim_t_periodic; /* Period between Join/Prune Messages */
-struct pim_assert_metric qpim_infinite_assert_metric;
-long qpim_rpf_cache_refresh_delay_msec;
-struct thread *qpim_rpf_cache_refresher;
-int64_t qpim_rpf_cache_refresh_requests;
-int64_t qpim_rpf_cache_refresh_events;
-int64_t qpim_rpf_cache_refresh_last;
-struct list *qpim_ssmpingd_list; /* list of struct ssmpingd_sock */
-struct in_addr qpim_ssmpingd_group_addr;
-int64_t qpim_scan_oil_events;
-int64_t qpim_scan_oil_last;
-int64_t qpim_mroute_add_events;
-int64_t qpim_mroute_add_last;
-int64_t qpim_mroute_del_events;
-int64_t qpim_mroute_del_last;
-int64_t qpim_nexthop_lookups;
-struct list *qpim_static_route_list; /* list of routes added statically */
-extern unsigned int qpim_keep_alive_time;
-extern signed int qpim_rp_keep_alive_time;
-extern int qpim_packet_process;
-extern uint8_t qpim_ecmp_enable;
-extern uint8_t qpim_ecmp_rebalance_enable;
+uint32_t qpim_debugs;
+int qpim_mroute_socket_fd;
+int64_t qpim_mroute_socket_creation; /* timestamp of creation */
+struct in_addr qpim_all_pim_routers_addr;
+int qpim_t_periodic; /* Period between Join/Prune Messages */
+struct pim_assert_metric qpim_infinite_assert_metric;
+long qpim_rpf_cache_refresh_delay_msec;
+struct thread *qpim_rpf_cache_refresher;
+int64_t qpim_rpf_cache_refresh_requests;
+int64_t qpim_rpf_cache_refresh_events;
+int64_t qpim_rpf_cache_refresh_last;
+struct list *qpim_ssmpingd_list; /* list of struct ssmpingd_sock */
+struct in_addr qpim_ssmpingd_group_addr;
+int64_t qpim_scan_oil_events;
+int64_t qpim_scan_oil_last;
+int64_t qpim_mroute_add_events;
+int64_t qpim_mroute_add_last;
+int64_t qpim_mroute_del_events;
+int64_t qpim_mroute_del_last;
+int64_t qpim_nexthop_lookups;
+struct list *qpim_static_route_list; /* list of routes added statically */
+extern unsigned int qpim_keep_alive_time;
+extern signed int qpim_rp_keep_alive_time;
+extern int qpim_packet_process;
+extern uint8_t qpim_ecmp_enable;
+extern uint8_t qpim_ecmp_rebalance_enable;
#define PIM_DEFAULT_PACKET_PROCESS 3
@@ -239,36 +237,35 @@ extern int32_t qpim_register_probe_time;
#define PIM_DONT_DEBUG_MSDP_INTERNAL (qpim_debugs &= ~PIM_MASK_MSDP_INTERNAL)
enum pim_spt_switchover {
- PIM_SPT_IMMEDIATE,
- PIM_SPT_INFINITY,
+ PIM_SPT_IMMEDIATE,
+ PIM_SPT_INFINITY,
};
/* Per VRF PIM DB */
-struct pim_instance
-{
- afi_t afi;
- vrf_id_t vrf_id;
+struct pim_instance {
+ afi_t afi;
+ vrf_id_t vrf_id;
+
+ struct {
+ enum pim_spt_switchover switchover;
+ char *plist;
+ } spt;
- struct {
- enum pim_spt_switchover switchover;
- char *plist;
- } spt;
+ struct hash *rpf_hash;
- struct hash *rpf_hash;
+ void *ssm_info; /* per-vrf SSM configuration */
- void *ssm_info; /* per-vrf SSM configuration */
-
- int send_v6_secondary;
+ int send_v6_secondary;
};
-extern struct pim_instance *pimg; //Pim Global Instance
+extern struct pim_instance *pimg; // Pim Global Instance
void pim_init(void);
void pim_terminate(void);
-extern void pim_route_map_init (void);
+extern void pim_route_map_init(void);
extern void pim_route_map_terminate(void);
-void pim_vrf_init (void);
-void pim_prefix_list_update (struct prefix_list *plist);
+void pim_vrf_init(void);
+void pim_prefix_list_update(struct prefix_list *plist);
#endif /* PIMD_H */
diff --git a/pimd/test_igmpv3_join.c b/pimd/test_igmpv3_join.c
index f363152ad..14ec9fb02 100644
--- a/pimd/test_igmpv3_join.c
+++ b/pimd/test_igmpv3_join.c
@@ -36,114 +36,114 @@ const char *prog_name = 0;
static int iface_solve_index(const char *ifname)
{
- struct if_nameindex *ini;
- ifindex_t ifindex = -1;
- int i;
-
- if (!ifname)
- return -1;
-
- ini = if_nameindex();
- if (!ini) {
- int err = errno;
- fprintf(stderr,
- "%s: interface=%s: failure solving index: errno=%d: %s\n",
- prog_name, ifname, err, strerror(err));
- errno = err;
- return -1;
- }
-
- for (i = 0; ini[i].if_index; ++i) {
+ struct if_nameindex *ini;
+ ifindex_t ifindex = -1;
+ int i;
+
+ if (!ifname)
+ return -1;
+
+ ini = if_nameindex();
+ if (!ini) {
+ int err = errno;
+ fprintf(stderr,
+ "%s: interface=%s: failure solving index: errno=%d: %s\n",
+ prog_name, ifname, err, strerror(err));
+ errno = err;
+ return -1;
+ }
+
+ for (i = 0; ini[i].if_index; ++i) {
#if 0
fprintf(stderr,
"%s: interface=%s matching against local ifname=%s ifindex=%d\n",
prog_name, ifname, ini[i].if_name, ini[i].if_index);
#endif
- if (!strcmp(ini[i].if_name, ifname)) {
- ifindex = ini[i].if_index;
- break;
- }
- }
+ if (!strcmp(ini[i].if_name, ifname)) {
+ ifindex = ini[i].if_index;
+ break;
+ }
+ }
- if_freenameindex(ini);
+ if_freenameindex(ini);
- return ifindex;
+ return ifindex;
}
int main(int argc, const char *argv[])
{
- struct in_addr group_addr;
- struct in_addr source_addr;
- const char *ifname;
- const char *group;
- const char *source;
- ifindex_t ifindex;
- int result;
- int fd;
-
- prog_name = argv[0];
-
- fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (fd < 0) {
- fprintf(stderr,
- "%s: could not create socket: socket(): errno=%d: %s\n",
- prog_name, errno, strerror(errno));
- exit(1);
- }
-
- if (argc != 4) {
- fprintf(stderr,
- "usage: %s interface group source\n"
- "example: %s eth0 232.1.1.1 1.1.1.1\n",
- prog_name, prog_name);
- exit(1);
- }
-
- ifname = argv[1];
- group = argv[2];
- source = argv[3];
-
- ifindex = iface_solve_index(ifname);
- if (ifindex < 0) {
- fprintf(stderr, "%s: could not find interface: %s\n",
- prog_name, ifname);
- exit(1);
- }
-
- result = inet_pton(AF_INET, group, &group_addr);
- if (result <= 0) {
- fprintf(stderr, "%s: bad group address: %s\n",
- prog_name, group);
- exit(1);
- }
-
- result = inet_pton(AF_INET, source, &source_addr);
- if (result <= 0) {
- fprintf(stderr, "%s: bad source address: %s\n",
- prog_name, source);
- exit(1);
- }
-
- result = pim_igmp_join_source(fd, ifindex, group_addr, source_addr);
- if (result) {
- fprintf(stderr,
- "%s: setsockopt(fd=%d) failure for IGMP group %s source %s ifindex %d on interface %s: errno=%d: %s\n",
- prog_name, fd, group, source, ifindex, ifname,
- errno, strerror(errno));
- exit(1);
- }
-
- printf("%s: joined channel (S,G)=(%s,%s) on interface %s\n",
- prog_name, source, group, ifname);
-
- printf("%s: waiting...\n", prog_name);
-
- getchar();
-
- close(fd);
-
- printf("%s: left channel (S,G)=(%s,%s) on interface %s\n",
- prog_name, source, group, ifname);
-
- exit(0);
+ struct in_addr group_addr;
+ struct in_addr source_addr;
+ const char *ifname;
+ const char *group;
+ const char *source;
+ ifindex_t ifindex;
+ int result;
+ int fd;
+
+ prog_name = argv[0];
+
+ fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (fd < 0) {
+ fprintf(stderr,
+ "%s: could not create socket: socket(): errno=%d: %s\n",
+ prog_name, errno, strerror(errno));
+ exit(1);
+ }
+
+ if (argc != 4) {
+ fprintf(stderr,
+ "usage: %s interface group source\n"
+ "example: %s eth0 232.1.1.1 1.1.1.1\n",
+ prog_name, prog_name);
+ exit(1);
+ }
+
+ ifname = argv[1];
+ group = argv[2];
+ source = argv[3];
+
+ ifindex = iface_solve_index(ifname);
+ if (ifindex < 0) {
+ fprintf(stderr, "%s: could not find interface: %s\n", prog_name,
+ ifname);
+ exit(1);
+ }
+
+ result = inet_pton(AF_INET, group, &group_addr);
+ if (result <= 0) {
+ fprintf(stderr, "%s: bad group address: %s\n", prog_name,
+ group);
+ exit(1);
+ }
+
+ result = inet_pton(AF_INET, source, &source_addr);
+ if (result <= 0) {
+ fprintf(stderr, "%s: bad source address: %s\n", prog_name,
+ source);
+ exit(1);
+ }
+
+ result = pim_igmp_join_source(fd, ifindex, group_addr, source_addr);
+ if (result) {
+ fprintf(stderr,
+ "%s: setsockopt(fd=%d) failure for IGMP group %s source %s ifindex %d on interface %s: errno=%d: %s\n",
+ prog_name, fd, group, source, ifindex, ifname, errno,
+ strerror(errno));
+ exit(1);
+ }
+
+ printf("%s: joined channel (S,G)=(%s,%s) on interface %s\n", prog_name,
+ source, group, ifname);
+
+ printf("%s: waiting...\n", prog_name);
+
+ getchar();
+
+ close(fd);
+
+ printf("%s: left channel (S,G)=(%s,%s) on interface %s\n", prog_name,
+ source, group, ifname);
+
+ exit(0);
}