From 8799b66b94ffcf42ad5660b8863f4341cf30c80d Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 9 Dec 2016 11:05:08 -0500 Subject: [PATCH 01/15] pimd: Start abstraction of zclient data structure for pim_zebra.c Start the abstraction of the zclient data structure out from a global variable for the entire program to a global variable to the pim_zebra.c file. Signed-off-by: Donald Sharp --- pimd/pim_cmd.c | 9 +-------- pimd/pim_zebra.c | 14 ++++++++++++++ pimd/pim_zebra.h | 1 + 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 7e60232bac..7dc1aeccb9 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -2825,15 +2825,8 @@ DEFUN (show_ip_multicast, } vty_out(vty, "%s", VTY_NEWLINE); - vty_out(vty, "Zclient update socket: "); - if (qpim_zclient_update) { - vty_out(vty, "%d failures=%d%s", qpim_zclient_update->sock, - qpim_zclient_update->fail, VTY_NEWLINE); - } - else { - vty_out(vty, "%s", VTY_NEWLINE); - } + pim_zebra_zclient_update (vty); pim_zlookup_show_ip_multicast (vty); vty_out(vty, "%s", VTY_NEWLINE); diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index b21da624d6..e1a23ab4a3 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -1232,3 +1232,17 @@ void pim_forward_stop(struct pim_ifchannel *ch) ch->interface, PIM_OIF_FLAG_PROTO_PIM); } + +void +pim_zebra_zclient_update (struct vty *vty) +{ + vty_out(vty, "Zclient update socket: "); + + if (qpim_zclient_update) { + vty_out(vty, "%d failures=%d%s", qpim_zclient_update->sock, + qpim_zclient_update->fail, VTY_NEWLINE); + } + else { + vty_out(vty, "%s", VTY_NEWLINE); + } +} diff --git a/pimd/pim_zebra.h b/pimd/pim_zebra.h index 0c302efbd5..476185def1 100644 --- a/pimd/pim_zebra.h +++ b/pimd/pim_zebra.h @@ -25,6 +25,7 @@ #include "pim_ifchannel.h" void pim_zebra_init(char *zebra_sock_path); +void pim_zebra_zclient_update (struct vty *vty); void pim_scan_individual_oil (struct channel_oil *c_oil); void pim_scan_oil(void); From 38f4935a5d0868517f949696186e1828cee3ae20 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 9 Dec 2016 11:08:45 -0500 Subject: [PATCH 02/15] pimd: Move qpim_zclient_update -> zclient Rename the qpim_zclient_update variable to zclient. This is to follow the naming conventions in the rest of the code. Additionally move the struct zclient * pointer into pim_zebra.c Signed-off-by: Donald Sharp --- pimd/pim_zebra.c | 40 +++++++++++++++++++++------------------- pimd/pimd.c | 1 - pimd/pimd.h | 1 - 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index e1a23ab4a3..aa09819fbe 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -48,6 +48,8 @@ #undef PIM_DEBUG_IFADDR_DUMP #define PIM_DEBUG_IFADDR_DUMP +static struct zclient *zclient = NULL; + static int fib_lookup_if_vif_index(struct in_addr addr); static int del_oif(struct channel_oil *channel_oil, struct interface *oif, @@ -724,31 +726,31 @@ void pim_zebra_init(char *zebra_sock_path) #endif /* Socket for receiving updates from Zebra daemon */ - qpim_zclient_update = zclient_new (master); + zclient = zclient_new (master); - qpim_zclient_update->zebra_connected = pim_zebra_connected; - qpim_zclient_update->router_id_update = pim_router_id_update_zebra; - qpim_zclient_update->interface_add = pim_zebra_if_add; - qpim_zclient_update->interface_delete = pim_zebra_if_del; - qpim_zclient_update->interface_up = pim_zebra_if_state_up; - qpim_zclient_update->interface_down = pim_zebra_if_state_down; - qpim_zclient_update->interface_address_add = pim_zebra_if_address_add; - qpim_zclient_update->interface_address_delete = pim_zebra_if_address_del; - qpim_zclient_update->redistribute_route_ipv4_add = redist_read_ipv4_route; - qpim_zclient_update->redistribute_route_ipv4_del = redist_read_ipv4_route; + 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->redistribute_route_ipv4_add = redist_read_ipv4_route; + zclient->redistribute_route_ipv4_del = redist_read_ipv4_route; - zclient_init(qpim_zclient_update, ZEBRA_ROUTE_PIM, 0); + zclient_init(zclient, ZEBRA_ROUTE_PIM, 0); if (PIM_DEBUG_PIM_TRACE) { zlog_info("zclient_init cleared redistribution request"); } - zassert(qpim_zclient_update->redist_default == ZEBRA_ROUTE_PIM); + zassert(zclient->redist_default == ZEBRA_ROUTE_PIM); /* Request all redistribution */ for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { - if (i == qpim_zclient_update->redist_default) + if (i == zclient->redist_default) continue; - vrf_bitmap_set (qpim_zclient_update->redist[AFI_IP][i], VRF_DEFAULT);; + 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); @@ -757,7 +759,7 @@ void pim_zebra_init(char *zebra_sock_path) /* Request default information */ zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_ADD, - qpim_zclient_update, VRF_DEFAULT); + zclient, VRF_DEFAULT); if (PIM_DEBUG_PIM_TRACE) { zlog_info("%s: requesting default information redistribution", @@ -1238,9 +1240,9 @@ pim_zebra_zclient_update (struct vty *vty) { vty_out(vty, "Zclient update socket: "); - if (qpim_zclient_update) { - vty_out(vty, "%d failures=%d%s", qpim_zclient_update->sock, - qpim_zclient_update->fail, VTY_NEWLINE); + if (zclient) { + vty_out(vty, "%d failures=%d%s", zclient->sock, + zclient->fail, VTY_NEWLINE); } else { vty_out(vty, "%s", VTY_NEWLINE); diff --git a/pimd/pimd.c b/pimd/pimd.c index 1627c4048d..c000a2364d 100644 --- a/pimd/pimd.c +++ b/pimd/pimd.c @@ -51,7 +51,6 @@ int qpim_mroute_socket_fd = -1; int64_t qpim_mroute_socket_creation = 0; /* timestamp of creation */ int qpim_mroute_oif_highest_vif_index = -1; int qpim_t_periodic = PIM_DEFAULT_T_PERIODIC; /* Period between Join/Prune Messages */ -struct zclient *qpim_zclient_update = NULL; struct pim_assert_metric qpim_infinite_assert_metric; long qpim_rpf_cache_refresh_delay_msec = 50; struct thread *qpim_rpf_cache_refresher = NULL; diff --git a/pimd/pimd.h b/pimd/pimd.h index 20cf3c2dd2..d43b64b0c3 100644 --- a/pimd/pimd.h +++ b/pimd/pimd.h @@ -102,7 +102,6 @@ int64_t qpim_mroute_socket_creation; /* timestamp of creation int qpim_mroute_oif_highest_vif_index; struct in_addr qpim_all_pim_routers_addr; int qpim_t_periodic; /* Period between Join/Prune Messages */ -struct zclient *qpim_zclient_update; struct pim_assert_metric qpim_infinite_assert_metric; long qpim_rpf_cache_refresh_delay_msec; struct thread *qpim_rpf_cache_refresher; From d14b95ce968a44a8278745fc23ac9f37e98629a1 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 9 Dec 2016 12:05:29 -0500 Subject: [PATCH 03/15] bgpd, zebra: Pass distance as part of the ZEBRA_NEXTHOP_UPDATE When zebra calls routing protocols back with either ZEBRA_NEXTHOP_UPDATE or ZEBRA_IMPORT_CHECK_UPDATE pass the distance value too. This is to set us up for nht for pim as that it needs the distance sometimes too. Signed-off-by: Donald Sharp --- bgpd/bgp_nht.c | 1 + zebra/zebra_rnh.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 057e2ace76..aa752280cf 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -377,6 +377,7 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id) bgp_unlock_node (rn); bnc->last_update = bgp_clock(); bnc->change_flags = 0; + stream_getc (s); // Distance but not currently used metric = stream_getl (s); nexthop_num = stream_getc (s); diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 182cfe552d..b180930a0a 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -878,6 +878,7 @@ send_client (struct rnh *rnh, struct zserv *client, rnh_type_t type, vrf_id_t vr } if (rib) { + stream_putc (s, rib->distance); stream_putl (s, rib->metric); num = 0; nump = stream_get_endp(s); @@ -917,8 +918,9 @@ send_client (struct rnh *rnh, struct zserv *client, rnh_type_t type, vrf_id_t vr } else { - stream_putl (s, 0); - stream_putc (s, 0); + stream_putc (s, 0); // distance + stream_putl (s, 0); // metric + stream_putc (s, 0); // nexthops } stream_putw_at (s, 0, stream_get_endp (s)); From b153b0101068dd9fb91386857549cc9f4ed24152 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 12 Dec 2016 09:20:49 -0500 Subject: [PATCH 04/15] zebra: Consolidate nexthop_active_ipv4 and _ipv6 Both of these functions are identical. Consolidate to 1 function. Signed-off-by: Donald Sharp --- zebra/zebra_rib.c | 289 +++++++++++++--------------------------------- 1 file changed, 82 insertions(+), 207 deletions(-) diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 59893b1a0f..1252b007f0 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -347,10 +347,10 @@ nexthop_has_fib_child(struct nexthop *nexthop) /* If force flag is not set, do not modify falgs at all for uninstall the route from FIB. */ static int -nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, - struct route_node *top) +nexthop_active (afi_t afi, struct rib *rib, struct nexthop *nexthop, int set, + struct route_node *top) { - struct prefix_ipv4 p; + struct prefix p; struct route_table *table; struct route_node *rn; struct rib *match; @@ -360,7 +360,7 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, int recursing = 0; struct interface *ifp; - if (nexthop->type == NEXTHOP_TYPE_IPV4) + if ((nexthop->type == NEXTHOP_TYPE_IPV4) || nexthop->type == NEXTHOP_TYPE_IPV6) nexthop->ifindex = 0; if (set) @@ -398,13 +398,25 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, } /* Make lookup prefix. */ - memset (&p, 0, sizeof (struct prefix_ipv4)); - p.family = AF_INET; - p.prefixlen = IPV4_MAX_PREFIXLEN; - p.prefix = nexthop->gate.ipv4; - + memset (&p, 0, sizeof (struct prefix)); + switch (afi) + { + case AFI_IP: + p.family = AF_INET; + p.prefixlen = IPV4_MAX_PREFIXLEN; + p.u.prefix4 = nexthop->gate.ipv4; + break; + case AFI_IP6: + p.family = AF_INET6; + p.prefixlen = IPV6_MAX_PREFIXLEN; + p.u.prefix6 = nexthop->gate.ipv6; + break; + default: + assert (afi != AFI_IP && afi != AFI_IP6); + break; + } /* Lookup table. */ - table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, rib->vrf_id); + table = zebra_vrf_table (afi, SAFI_UNICAST, rib->vrf_id); if (! table) return 0; @@ -457,9 +469,19 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, { /* Directly point connected route. */ newhop = match->nexthop; - if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4) - nexthop->ifindex = newhop->ifindex; - + if (newhop) + { + if (nexthop->type == NEXTHOP_TYPE_IPV4) + { + nexthop->ifindex = newhop->ifindex; + nexthop->type = NEXTHOP_TYPE_IPV4; + } + if (nexthop->type == NEXTHOP_TYPE_IPV6) + { + nexthop->ifindex = newhop->ifindex; + nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX; + } + } return 1; } else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL)) @@ -491,6 +513,18 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; } } + if (newhop->type == NEXTHOP_TYPE_IPV6 + || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX) + { + resolved_hop->type = newhop->type; + resolved_hop->gate.ipv6 = newhop->gate.ipv6; + + if (newhop->ifindex) + { + resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX; + resolved_hop->ifindex = newhop->ifindex; + } + } /* If the resolving route is an interface route, * it means the gateway we are looking up is connected @@ -503,8 +537,16 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, if (newhop->type == NEXTHOP_TYPE_IFINDEX) { resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; - resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX; - resolved_hop->gate.ipv4 = nexthop->gate.ipv4; + if (afi == AFI_IP) + { + resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX; + resolved_hop->gate.ipv4 = nexthop->gate.ipv4; + } + else if (afi == AFI_IP6) + { + resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX; + resolved_hop->gate.ipv6 = nexthop->gate.ipv6; + } resolved_hop->ifindex = newhop->ifindex; } @@ -541,6 +583,18 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; } } + if (newhop->type == NEXTHOP_TYPE_IPV6 + || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX) + { + resolved_hop->type = newhop->type; + resolved_hop->gate.ipv6 = newhop->gate.ipv6; + + if (newhop->ifindex) + { + resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX; + resolved_hop->ifindex = newhop->ifindex; + } + } /* If the resolving route is an interface route, * it means the gateway we are looking up is connected @@ -554,8 +608,16 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, if (newhop->type == NEXTHOP_TYPE_IFINDEX) { resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; - resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX; - resolved_hop->gate.ipv4 = nexthop->gate.ipv4; + if (afi == AFI_IP) + { + resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX; + resolved_hop->gate.ipv4 = nexthop->gate.ipv4; + } + else if (afi == AFI_IP6) + { + resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX; + resolved_hop->gate.ipv6 = nexthop->gate.ipv6; + } resolved_hop->ifindex = newhop->ifindex; } @@ -576,193 +638,6 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, return 0; } -/* If force flag is not set, do not modify falgs at all for uninstall - the route from FIB. */ -static int -nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set, - struct route_node *top) -{ - struct prefix_ipv6 p; - struct route_table *table; - struct route_node *rn; - struct rib *match; - int resolved; - struct nexthop *newhop, *tnewhop; - int recursing = 0; - struct nexthop *resolved_hop; - - if (nexthop->type == NEXTHOP_TYPE_IPV6) - nexthop->ifindex = 0; - - if (set) - { - UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE); - zebra_deregister_rnh_static_nexthops (rib->vrf_id, nexthop->resolved, top); - nexthops_free(nexthop->resolved); - nexthop->resolved = NULL; - } - - /* Skip nexthops that have been filtered out due to route-map */ - /* The nexthops are specific to this route and so the same */ - /* nexthop for a different route may not have this flag set */ - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED)) - return 0; - - /* Make lookup prefix. */ - memset (&p, 0, sizeof (struct prefix_ipv6)); - p.family = AF_INET6; - p.prefixlen = IPV6_MAX_PREFIXLEN; - p.prefix = nexthop->gate.ipv6; - - /* Lookup table. */ - table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, rib->vrf_id); - if (! table) - return 0; - - rn = route_node_match (table, (struct prefix *) &p); - while (rn) - { - route_unlock_node (rn); - - /* If lookup self prefix return immediately. */ - if (rn == top) - return 0; - - /* Pick up selected route. */ - /* However, do not resolve over default route unless explicitly allowed. */ - if (is_default_prefix (&rn->p) && - !nh_resolve_via_default (p.family)) - return 0; - - RNODE_FOREACH_RIB (rn, match) - { - if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED)) - continue; - if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB)) - break; - } - - /* If there is no selected route or matched route is EGP, go up - tree. */ - if (! match) - { - do { - rn = rn->parent; - } while (rn && rn->info == NULL); - if (rn) - route_lock_node (rn); - } - else - { - /* If the longest prefix match for the nexthop yields - * a blackhole, mark it as inactive. */ - if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE) - || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT)) - return 0; - - if (match->type == ZEBRA_ROUTE_CONNECT) - { - /* Directly point connected route. */ - newhop = match->nexthop; - - if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6) - nexthop->ifindex = newhop->ifindex; - - return 1; - } - else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL)) - { - resolved = 0; - for (newhop = match->nexthop; newhop; newhop = newhop->next) - if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB) - && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE)) - { - if (set) - { - SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE); - SET_FLAG(rib->status, RIB_ENTRY_NEXTHOPS_CHANGED); - - resolved_hop = nexthop_new(); - SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE); - /* See nexthop_active_ipv4 for a description how the - * resolved nexthop is constructed. */ - if (newhop->type == NEXTHOP_TYPE_IPV6 - || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX) - { - resolved_hop->type = newhop->type; - resolved_hop->gate.ipv6 = newhop->gate.ipv6; - - if (newhop->ifindex) - { - resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX; - resolved_hop->ifindex = newhop->ifindex; - } - } - - if (newhop->type == NEXTHOP_TYPE_IFINDEX) - { - resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; - resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX; - resolved_hop->gate.ipv6 = nexthop->gate.ipv6; - resolved_hop->ifindex = newhop->ifindex; - } - - nexthop_add(&nexthop->resolved, resolved_hop); - } - resolved = 1; - } - return resolved; - } - else if (rib->type == ZEBRA_ROUTE_STATIC) - { - resolved = 0; - for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing)) - if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)) - { - if (set) - { - SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE); - - resolved_hop = nexthop_new(); - SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE); - /* See nexthop_active_ipv4 for a description how the - * resolved nexthop is constructed. */ - if (newhop->type == NEXTHOP_TYPE_IPV6 - || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX) - { - resolved_hop->type = newhop->type; - resolved_hop->gate.ipv6 = newhop->gate.ipv6; - - if (newhop->ifindex) - { - resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX; - resolved_hop->ifindex = newhop->ifindex; - } - } - - if (newhop->type == NEXTHOP_TYPE_IFINDEX) - { - resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; - resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX; - resolved_hop->gate.ipv6 = nexthop->gate.ipv6; - resolved_hop->ifindex = newhop->ifindex; - } - - nexthop_add(&nexthop->resolved, resolved_hop); - } - resolved = 1; - } - return resolved; - } - else - { - return 0; - } - } - } - return 0; -} - struct rib * rib_match (afi_t afi, safi_t safi, vrf_id_t vrf_id, union g_addr *addr, struct route_node **rn_out) @@ -1075,14 +950,14 @@ nexthop_active_check (struct route_node *rn, struct rib *rib, case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: family = AFI_IP; - if (nexthop_active_ipv4 (rib, nexthop, set, rn)) + if (nexthop_active (AFI_IP, rib, nexthop, set, rn)) SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); else UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); break; case NEXTHOP_TYPE_IPV6: family = AFI_IP6; - if (nexthop_active_ipv6 (rib, nexthop, set, rn)) + if (nexthop_active (AFI_IP6, rib, nexthop, set, rn)) SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); else UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); @@ -1101,7 +976,7 @@ nexthop_active_check (struct route_node *rn, struct rib *rib, } else { - if (nexthop_active_ipv6 (rib, nexthop, set, rn)) + if (nexthop_active (AFI_IP6, rib, nexthop, set, rn)) SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); else UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); From 265d5b9d514f39ec29076e1fc987af9a56f66da5 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 12 Dec 2016 12:11:27 -0500 Subject: [PATCH 05/15] zebra: Cleanup dead code and unused return value We had a large block of #if 0 code. Since it's been that way for like 8 months now, lets go ahead and just remove it. Additionally the rib_delete function was returning a return code that was summarily ignored. Let's clean up the expectation of returning anything. Signed-off-by: Donald Sharp --- zebra/rib.h | 8 +- zebra/zebra_rib.c | 187 ++-------------------------------------------- 2 files changed, 10 insertions(+), 185 deletions(-) diff --git a/zebra/rib.h b/zebra/rib.h index d80ea6cbd8..99903769a2 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -349,10 +349,10 @@ extern int rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, extern int rib_add_multipath (afi_t afi, safi_t safi, struct prefix *, struct rib *); -extern int rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, - u_short instance, int flags, struct prefix *p, - union g_addr *gate, ifindex_t ifindex, - u_int32_t table_id); +extern void rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, + u_short instance, int flags, struct prefix *p, + union g_addr *gate, ifindex_t ifindex, + u_int32_t table_id); extern struct rib *rib_match (afi_t afi, safi_t safi, vrf_id_t, union g_addr *, struct route_node **rn_out); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 1252b007f0..7faf4c7e04 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -1677,181 +1677,6 @@ rib_process (struct route_node *rn) } } -#if 0 - if (select && select == fib) - { - if (IS_ZEBRA_DEBUG_RIB) - rnode_debug (rn, vrf_id, "Updating existing route, select %p, fib %p", - (void *)select, (void *)fib); - if (CHECK_FLAG (select->status, RIB_ENTRY_CHANGED)) - { - if (info->safi == SAFI_UNICAST) - zfpm_trigger_update (rn, "updating existing route"); - - /* Set real nexthop. */ - /* Need to check if any NHs are active to clear the - * the selected flag - */ - if (nexthop_active_update (rn, select, 1)) - { - if (IS_ZEBRA_DEBUG_RIB) - zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d)", - vrf_id, buf, rn->p.prefixlen, rn, select, select->type); - if (! RIB_SYSTEM_ROUTE (select)) - { - /* Clear FIB flag if performing a replace, will get set again - * as part of install. - */ - for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next) - UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); - rib_install_kernel (rn, select, 1); - } - - /* assuming that the receiver knows how to dedup */ - redistribute_update (&rn->p, select, NULL); - } - else - { - if (IS_ZEBRA_DEBUG_RIB) - zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) " - "- nexthop inactive", - vrf_id, buf, rn->p.prefixlen, rn, select, select->type); - - /* Withdraw unreachable redistribute route */ - redistribute_delete(&rn->p, select); - - /* Do the uninstall here, if not done earlier. */ - if (! RIB_SYSTEM_ROUTE (select)) - rib_uninstall_kernel (rn, select); - UNSET_FLAG (select->flags, ZEBRA_FLAG_SELECTED); - } - UNSET_FLAG (select->status, RIB_ENTRY_CHANGED); - } - else if (! RIB_SYSTEM_ROUTE (select)) - { - /* Housekeeping code to deal with - race conditions in kernel with linux - netlink reporting interface up before IPv4 or IPv6 protocol - is ready to add routes. - This makes sure the routes are IN the kernel. - */ - - for (ALL_NEXTHOPS_RO(select->nexthop, nexthop, tnexthop, recursing)) - if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) - { - installed = 1; - break; - } - if (! installed) - rib_install_kernel (rn, select, 0); - } - goto end; - } - - /* At this point we either haven't found the best RIB entry or it is - * different from what we currently intend to flag with SELECTED. In both - * cases, if a RIB block is present in FIB, it should be withdrawn. - */ - if (fib) - { - if (IS_ZEBRA_DEBUG_RIB) - rnode_debug (rn, vrf_id, "Removing existing route, fib %p", (void *)fib); - - if (info->safi == SAFI_UNICAST) - zfpm_trigger_update (rn, "removing existing route"); - - /* If there's no route to replace this with, withdraw redistribute and - * uninstall from kernel. - */ - if (!select) - { - if (IS_ZEBRA_DEBUG_RIB) - zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d)", - vrf_id, buf, rn->p.prefixlen, rn, fib, fib->type); - - redistribute_delete(&rn->p, fib); - if (! RIB_SYSTEM_ROUTE (fib)) - rib_uninstall_kernel (rn, fib); - } - - UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED); - - /* Set real nexthop. */ - nexthop_active_update (rn, fib, 1); - UNSET_FLAG(fib->status, RIB_ENTRY_CHANGED); - } - - /* Regardless of some RIB entry being SELECTED or not before, now we can - * tell, that if a new winner exists, FIB is still not updated with this - * data, but ready to be. - */ - if (select) - { - if (IS_ZEBRA_DEBUG_RIB) - rnode_debug (rn, "Adding route, select %p", (void *)select); - - if (info->safi == SAFI_UNICAST) - zfpm_trigger_update (rn, "new route selected"); - - /* Set real nexthop. */ - if (nexthop_active_update (rn, select, 1)) - { - if (IS_ZEBRA_DEBUG_RIB) - { - if (fib) - zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d) " - "old %p (type %d)", vrf_id, buf, rn->p.prefixlen, rn, - select, select->type, fib, fib->type); - else - zlog_debug ("%u:%s/%d: Adding route rn %p, rib %p (type %d)", - vrf_id, buf, rn->p.prefixlen, rn, select, select->type); - } - - if (! RIB_SYSTEM_ROUTE (select)) - { - /* Clear FIB flag if performing a replace, will get set again - * as part of install. - */ - if (fib) - { - for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next) - UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); - } - rib_install_kernel (rn, select, fib? 1 : 0); - } - else - { - /* Uninstall prior route here, if needed. */ - if (fib && !RIB_SYSTEM_ROUTE (fib)) - rib_uninstall_kernel (rn, fib); - } - - SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED); - /* Unconditionally announce, this part is exercised by new routes */ - /* If we cannot add, for example route added is learnt by the */ - /* protocol we're trying to redistribute to, delete the redist */ - /* This is notified by setting the is_update to 1 */ - redistribute_update (&rn->p, select, fib); - } - else - { - /* Uninstall prior route here and do redist delete, if needed. */ - if (fib) - { - if (IS_ZEBRA_DEBUG_RIB) - zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) " - "- nexthop inactive", - vrf_id, buf, rn->p.prefixlen, rn, fib, fib->type); - - if (!RIB_SYSTEM_ROUTE (fib)) - rib_uninstall_kernel (rn, fib); - redistribute_delete(&rn->p, fib); - } - } - UNSET_FLAG(select->status, RIB_ENTRY_CHANGED); - } -#endif - /* Remove all RIB entries queued for removal */ RNODE_FOREACH_RIB_SAFE (rn, rib, next) { @@ -2547,7 +2372,7 @@ rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p, return ret; } -int +void rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, int flags, struct prefix *p, union g_addr *gate, ifindex_t ifindex, u_int32_t table_id) @@ -2565,7 +2390,7 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, /* Lookup table. */ table = zebra_vrf_table_with_table_id (afi, safi, vrf_id, table_id); if (! table) - return 0; + return; /* Apply mask. */ apply_mask (p); @@ -2577,7 +2402,7 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, if (IS_ZEBRA_DEBUG_RIB) zlog_debug ("%u:%s: doesn't exist in rib", vrf_id, prefix2str (p, buf1, sizeof(buf1))); - return ZEBRA_ERR_RTNOEXIST; + return; } /* Lookup same type route. */ @@ -2603,7 +2428,7 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, rib->refcnt--; route_unlock_node (rn); route_unlock_node (rn); - return 0; + return; } same = rib; break; @@ -2674,7 +2499,7 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, type); } route_unlock_node (rn); - return ZEBRA_ERR_RTNOEXIST; + return; } } @@ -2682,7 +2507,7 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, rib_delnode (rn, same); route_unlock_node (rn); - return 0; + return; } From 94ed344a8f895dd1bc7d8b9cde1b39902744238e Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 12 Dec 2016 12:16:21 -0500 Subject: [PATCH 06/15] zebra: Refactor Error codes to proper place These error codes have ended up only being used for socket type interfaces to the kernel(*bsd), yet we were exposing the #defines to the entirety of the project. Signed-off-by: Donald Sharp --- lib/zebra.h | 8 -------- zebra/kernel_socket.h | 8 ++++++++ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/zebra.h b/lib/zebra.h index bb43d062bc..39f77ce3fe 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -438,14 +438,6 @@ extern const char *zserv_command_string (unsigned int command); #define strmatch(a,b) (!strcmp((a), (b))) -/* Error codes of zebra. */ -#define ZEBRA_ERR_NOERROR 0 -#define ZEBRA_ERR_RTEXIST -1 -#define ZEBRA_ERR_RTUNREACH -2 -#define ZEBRA_ERR_EPERM -3 -#define ZEBRA_ERR_RTNOEXIST -4 -#define ZEBRA_ERR_KERNEL -5 - /* Zebra message flags */ #define ZEBRA_FLAG_INTERNAL 0x01 #define ZEBRA_FLAG_SELFROUTE 0x02 diff --git a/zebra/kernel_socket.h b/zebra/kernel_socket.h index 18d69343a4..04e3054312 100644 --- a/zebra/kernel_socket.h +++ b/zebra/kernel_socket.h @@ -23,6 +23,14 @@ #ifndef __ZEBRA_KERNEL_SOCKET_H #define __ZEBRA_KERNEL_SOCKET_H +/* Error codes of zebra. */ +#define ZEBRA_ERR_NOERROR 0 +#define ZEBRA_ERR_RTEXIST -1 +#define ZEBRA_ERR_RTUNREACH -2 +#define ZEBRA_ERR_EPERM -3 +#define ZEBRA_ERR_RTNOEXIST -4 +#define ZEBRA_ERR_KERNEL -5 + extern void rtm_read (struct rt_msghdr *); extern int ifam_read (struct ifa_msghdr *); extern int ifm_read (struct if_msghdr *); From 8613585e1f5a421cb88cfefa8307f2b3981df378 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 12 Dec 2016 12:47:48 -0500 Subject: [PATCH 07/15] lib: Moved zapi message types to zclient.h Move the data structure used to have knowledge about the zapi message types to zclient.h where it belongs. Signed-off-by: Donald Sharp --- lib/log.c | 1 + lib/zclient.h | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/zebra.h | 56 --------------------------------------------------- 3 files changed, 57 insertions(+), 56 deletions(-) diff --git a/lib/log.c b/lib/log.c index b8e505f347..a421f60443 100644 --- a/lib/log.c +++ b/lib/log.c @@ -24,6 +24,7 @@ #include +#include "zclient.h" #include "log.h" #include "memory.h" #include "command.h" diff --git a/lib/zclient.h b/lib/zclient.h index ccb7b0509d..83b932f20a 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -37,6 +37,62 @@ /* Zebra header size. */ #define ZEBRA_HEADER_SIZE 8 +/* Zebra message types. */ +typedef enum { + ZEBRA_INTERFACE_ADD, + ZEBRA_INTERFACE_DELETE, + ZEBRA_INTERFACE_ADDRESS_ADD, + ZEBRA_INTERFACE_ADDRESS_DELETE, + ZEBRA_INTERFACE_UP, + ZEBRA_INTERFACE_DOWN, + ZEBRA_IPV4_ROUTE_ADD, + ZEBRA_IPV4_ROUTE_DELETE, + ZEBRA_IPV6_ROUTE_ADD, + ZEBRA_IPV6_ROUTE_DELETE, + ZEBRA_REDISTRIBUTE_ADD, + ZEBRA_REDISTRIBUTE_DELETE, + ZEBRA_REDISTRIBUTE_DEFAULT_ADD, + ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, + ZEBRA_ROUTER_ID_ADD, + ZEBRA_ROUTER_ID_DELETE, + ZEBRA_ROUTER_ID_UPDATE, + ZEBRA_HELLO, + ZEBRA_NEXTHOP_REGISTER, + ZEBRA_NEXTHOP_UNREGISTER, + ZEBRA_NEXTHOP_UPDATE, + ZEBRA_INTERFACE_NBR_ADDRESS_ADD, + ZEBRA_INTERFACE_NBR_ADDRESS_DELETE, + ZEBRA_INTERFACE_BFD_DEST_UPDATE, + ZEBRA_IMPORT_ROUTE_REGISTER, + ZEBRA_IMPORT_ROUTE_UNREGISTER, + ZEBRA_IMPORT_CHECK_UPDATE, + ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD, + ZEBRA_BFD_DEST_REGISTER, + ZEBRA_BFD_DEST_DEREGISTER, + ZEBRA_BFD_DEST_UPDATE, + ZEBRA_BFD_DEST_REPLAY, + ZEBRA_REDISTRIBUTE_IPV4_ADD, + ZEBRA_REDISTRIBUTE_IPV4_DEL, + ZEBRA_REDISTRIBUTE_IPV6_ADD, + ZEBRA_REDISTRIBUTE_IPV6_DEL, + ZEBRA_VRF_UNREGISTER, + ZEBRA_VRF_ADD, + ZEBRA_VRF_DELETE, + ZEBRA_INTERFACE_VRF_UPDATE, + ZEBRA_BFD_CLIENT_REGISTER, + ZEBRA_INTERFACE_ENABLE_RADV, + ZEBRA_INTERFACE_DISABLE_RADV, + ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, + ZEBRA_INTERFACE_LINK_PARAMS, + ZEBRA_MPLS_LABELS_ADD, + ZEBRA_MPLS_LABELS_DELETE, + ZEBRA_IPV4_NEXTHOP_ADD, + ZEBRA_IPV4_NEXTHOP_DELETE, + ZEBRA_IPV6_NEXTHOP_ADD, + ZEBRA_IPV6_NEXTHOP_DELETE, + ZEBRA_IPMR_ROUTE_STATS, +} zebra_message_types_t; + struct redist_proto { u_char enabled; diff --git a/lib/zebra.h b/lib/zebra.h index 39f77ce3fe..19a26b5230 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -352,62 +352,6 @@ struct in_pktinfo /* default zebra TCP port for zclient */ #define ZEBRA_PORT 2600 -/* Zebra message types. */ -typedef enum { - ZEBRA_INTERFACE_ADD, - ZEBRA_INTERFACE_DELETE, - ZEBRA_INTERFACE_ADDRESS_ADD, - ZEBRA_INTERFACE_ADDRESS_DELETE, - ZEBRA_INTERFACE_UP, - ZEBRA_INTERFACE_DOWN, - ZEBRA_IPV4_ROUTE_ADD, - ZEBRA_IPV4_ROUTE_DELETE, - ZEBRA_IPV6_ROUTE_ADD, - ZEBRA_IPV6_ROUTE_DELETE, - ZEBRA_REDISTRIBUTE_ADD, - ZEBRA_REDISTRIBUTE_DELETE, - ZEBRA_REDISTRIBUTE_DEFAULT_ADD, - ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, - ZEBRA_ROUTER_ID_ADD, - ZEBRA_ROUTER_ID_DELETE, - ZEBRA_ROUTER_ID_UPDATE, - ZEBRA_HELLO, - ZEBRA_NEXTHOP_REGISTER, - ZEBRA_NEXTHOP_UNREGISTER, - ZEBRA_NEXTHOP_UPDATE, - ZEBRA_INTERFACE_NBR_ADDRESS_ADD, - ZEBRA_INTERFACE_NBR_ADDRESS_DELETE, - ZEBRA_INTERFACE_BFD_DEST_UPDATE, - ZEBRA_IMPORT_ROUTE_REGISTER, - ZEBRA_IMPORT_ROUTE_UNREGISTER, - ZEBRA_IMPORT_CHECK_UPDATE, - ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD, - ZEBRA_BFD_DEST_REGISTER, - ZEBRA_BFD_DEST_DEREGISTER, - ZEBRA_BFD_DEST_UPDATE, - ZEBRA_BFD_DEST_REPLAY, - ZEBRA_REDISTRIBUTE_IPV4_ADD, - ZEBRA_REDISTRIBUTE_IPV4_DEL, - ZEBRA_REDISTRIBUTE_IPV6_ADD, - ZEBRA_REDISTRIBUTE_IPV6_DEL, - ZEBRA_VRF_UNREGISTER, - ZEBRA_VRF_ADD, - ZEBRA_VRF_DELETE, - ZEBRA_INTERFACE_VRF_UPDATE, - ZEBRA_BFD_CLIENT_REGISTER, - ZEBRA_INTERFACE_ENABLE_RADV, - ZEBRA_INTERFACE_DISABLE_RADV, - ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, - ZEBRA_INTERFACE_LINK_PARAMS, - ZEBRA_MPLS_LABELS_ADD, - ZEBRA_MPLS_LABELS_DELETE, - ZEBRA_IPV4_NEXTHOP_ADD, - ZEBRA_IPV4_NEXTHOP_DELETE, - ZEBRA_IPV6_NEXTHOP_ADD, - ZEBRA_IPV6_NEXTHOP_DELETE, - ZEBRA_IPMR_ROUTE_STATS, -} zebra_message_types_t; - /* Marker value used in new Zserv, in the byte location corresponding * the command value in the old zserv header. To allow old and new * Zserv headers to be distinguished from each other. From 781a1745c0908e54e44c761f32b6f7936d6c1a04 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 19 Jan 2017 12:09:26 -0500 Subject: [PATCH 08/15] pimd: Fixup tracking of where we got OIF's from. This commit does these three things: 1) Add code to 'show ip pim state' to show where OIF's got their decision to include that interface 2) Add code in pim_mroute_[add|del] to display what we think we are adding to the kernel 3) Add code to properly track where we got the incoming request from and to appropriately not remove a OIL if we have state still Ticket: CM-14034 Signed-off-by: Donald Sharp Reviewed-by: Don Slice Reviewed-by: Chirag Shah --- pimd/pim_cmd.c | 29 ++++++++++++++++++------ pimd/pim_ifchannel.c | 14 ++++++------ pimd/pim_mroute.c | 23 ++++++++----------- pimd/pim_oil.c | 54 ++++++++++++++++++++++++++++++++------------ pimd/pim_oil.h | 9 ++++++-- pimd/pim_upstream.c | 6 ++++- 6 files changed, 90 insertions(+), 45 deletions(-) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 7dc1aeccb9..8f3e2cb3e0 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -1367,7 +1367,8 @@ pim_show_state(struct vty *vty, const char *src_or_group, const char *group, u_c if (uj) { json = json_object_new_object(); } else { - vty_out(vty, "%sSource Group IIF OIL%s", VTY_NEWLINE, VTY_NEWLINE); + vty_out(vty, "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)"); + vty_out(vty, "%sInstalled Source Group IIF OIL%s", VTY_NEWLINE, VTY_NEWLINE); } for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) { @@ -1379,9 +1380,6 @@ pim_show_state(struct vty *vty, const char *src_or_group, const char *group, u_c struct interface *ifp_in; first_oif = 1; - if (!c_oil->installed) - continue; - pim_inet4_dump("", c_oil->oil.mfcc_mcastgrp, grp_str, sizeof(grp_str)); pim_inet4_dump("", c_oil->oil.mfcc_origin, src_str, sizeof(src_str)); ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent); @@ -1426,7 +1424,8 @@ pim_show_state(struct vty *vty, const char *src_or_group, const char *group, u_c json_object_object_add(json_source, in_ifname, json_ifp_in); } } else { - vty_out(vty, "%-15s %-15s %-5s ", + vty_out(vty, "%-9d %-15s %-15s %-7s ", + c_oil->installed, src_str, grp_str, ifp_in->name); @@ -1455,16 +1454,25 @@ pim_show_state(struct vty *vty, const char *src_or_group, const char *group, u_c 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", out_ifname); + 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", out_ifname); + 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) ? '*' : ' ' ); } } @@ -2963,6 +2971,9 @@ static void show_mroute(struct vty *vty, u_char uj) 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); @@ -2987,6 +2998,10 @@ static void show_mroute(struct vty *vty, u_char uj) 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%s", src_str, grp_str, diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index 07318791e7..8d2de3c878 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -153,7 +153,7 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch) 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_PIM); + pim_channel_del_oif (child->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR); } } @@ -270,7 +270,7 @@ void pim_ifchannel_ifjoin_switch(const char *caller, continue; if (!pim_upstream_evaluate_join_desired (child)) - pim_channel_del_oif (c_oil, ch->interface, PIM_OIF_FLAG_PROTO_PIM); + pim_channel_del_oif (c_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR); /* * If the S,G has no if channel and the c_oil still @@ -278,7 +278,7 @@ void pim_ifchannel_ifjoin_switch(const char *caller, * if channel. So remove 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_PIM); + pim_channel_del_oif (c_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR); } } if (ch->ifjoin_state == PIM_IFJOIN_JOIN) @@ -292,7 +292,7 @@ void pim_ifchannel_ifjoin_switch(const char *caller, if (pim_upstream_evaluate_join_desired (child)) { - pim_channel_add_oif (child->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_PIM); + pim_channel_add_oif (child->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR); pim_upstream_switch (child, PIM_UPSTREAM_JOINED); } } @@ -964,7 +964,7 @@ void pim_ifchannel_local_membership_add(struct interface *ifp, if (pim_upstream_evaluate_join_desired (child)) { - pim_channel_add_oif (child->channel_oil, ifp, PIM_OIF_FLAG_PROTO_PIM); + pim_channel_add_oif (child->channel_oil, ifp, PIM_OIF_FLAG_PROTO_STAR); pim_upstream_switch (child, PIM_UPSTREAM_JOINED); } } @@ -1008,7 +1008,7 @@ void pim_ifchannel_local_membership_del(struct interface *ifp, up->sg_str, ifp->name, child->sg_str); if (c_oil && !pim_upstream_evaluate_join_desired (child)) - pim_channel_del_oif (c_oil, ifp, PIM_OIF_FLAG_PROTO_PIM); + 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 @@ -1016,7 +1016,7 @@ void pim_ifchannel_local_membership_del(struct interface *ifp, * 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_PIM); + pim_channel_del_oif (c_oil, ifp, PIM_OIF_FLAG_PROTO_STAR); } } delete_on_noinfo(ch); diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index dfd22b7022..05d08b6e91 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -812,13 +812,10 @@ int pim_mroute_add(struct channel_oil *c_oil, const char *name) if (PIM_DEBUG_MROUTE) { - struct prefix_sg sg; - - sg.src = c_oil->oil.mfcc_origin; - sg.grp = c_oil->oil.mfcc_mcastgrp; - - zlog_debug("%s(%s), Added Route: %s to mroute table", - __PRETTY_FUNCTION__, name, pim_str_sg_dump(&sg)); + 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; @@ -850,14 +847,12 @@ int pim_mroute_del (struct channel_oil *c_oil, const char *name) if (PIM_DEBUG_MROUTE) { - struct prefix_sg sg; - - sg.src = c_oil->oil.mfcc_origin; - sg.grp = c_oil->oil.mfcc_mcastgrp; - - zlog_debug("%s(%s), Deleted Route: %s from mroute table", - __PRETTY_FUNCTION__, name, pim_str_sg_dump(&sg)); + char buf[1000]; + zlog_debug("%s(%s), Deleted Route: %s", + __PRETTY_FUNCTION__, name, + pim_channel_oil_dump (c_oil, buf, sizeof(buf))); } + c_oil->installed = 0; return 0; diff --git a/pimd/pim_oil.c b/pimd/pim_oil.c index 0cebe47355..4c5eff4883 100644 --- a/pimd/pim_oil.c +++ b/pimd/pim_oil.c @@ -36,6 +36,31 @@ 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) +{ + 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) { @@ -353,25 +378,26 @@ int pim_channel_add_oif(struct channel_oil *channel_oil, } /* Allow other protocol to request subscription of same interface to - channel (S,G) multiple times, by silently ignoring further - requests */ + * 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) { - if (PIM_DEBUG_MROUTE) - { - char group_str[INET_ADDRSTRLEN]; - char source_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); - pim_inet4_dump("", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str)); - zlog_debug("%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); - } + { + char group_str[INET_ADDRSTRLEN]; + char source_str[INET_ADDRSTRLEN]; + pim_inet4_dump("", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); + pim_inet4_dump("", 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; diff --git a/pimd/pim_oil.h b/pimd/pim_oil.h index 143cfb7942..6b96750ad1 100644 --- a/pimd/pim_oil.h +++ b/pimd/pim_oil.h @@ -29,13 +29,16 @@ * IGMP - Learned from IGMP * PIM - Learned from PIM * SOURCE - Learned from Source multicast packet received + * STAR - Inherited */ #define PIM_OIF_FLAG_PROTO_IGMP (1 << 0) #define PIM_OIF_FLAG_PROTO_PIM (1 << 1) -#define PIM_OIF_FLAG_PROTO_SOURCE (2 << 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_SOURCE | \ + PIM_OIF_FLAG_PROTO_STAR) /* * We need a pimreg vif id from the kernel. @@ -96,4 +99,6 @@ int pim_channel_del_oif (struct channel_oil *c_oil, uint32_t proto_mask); 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); #endif /* PIM_OIL_H */ diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index fbb7d84a25..4ae49c0fd4 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -1288,7 +1288,11 @@ pim_upstream_inherited_olist_decide (struct pim_upstream *up) if (pim_upstream_evaluate_join_desired_interface (up, ch)) { - pim_channel_add_oif (up->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_PIM); + int flag = PIM_OIF_FLAG_PROTO_PIM; + + if (ch->sg.src.s_addr == INADDR_ANY && ch->upstream != up) + flag = PIM_OIF_FLAG_PROTO_STAR; + pim_channel_add_oif (up->channel_oil, ch->interface, flag); output_intf++; } } From dc0665f1509725bab4c0c20031a06ff80cfc36f8 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sat, 21 Jan 2017 04:54:10 -0500 Subject: [PATCH 09/15] pimd: Handle assignment of vif index better PIM was handling vif creation deletion poorly for interface down and up events. Fix this issue by keeping track of which vif index'es we have issued and allow the wholes to be filled in. Ticket: CM-14556 Signed-off-by: Donald Sharp --- pimd/pim_cmd.c | 3 --- pimd/pim_iface.c | 57 ++++++++++++++---------------------------------- pimd/pimd.c | 2 -- pimd/pimd.h | 1 - 4 files changed, 16 insertions(+), 47 deletions(-) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 8f3e2cb3e0..7e85253f9a 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -2838,9 +2838,6 @@ DEFUN (show_ip_multicast, pim_zlookup_show_ip_multicast (vty); vty_out(vty, "%s", VTY_NEWLINE); - vty_out(vty, "Current highest VifIndex: %d%s", - qpim_mroute_oif_highest_vif_index, - VTY_NEWLINE); vty_out(vty, "Maximum highest VifIndex: %d%s", PIM_MAX_USABLE_VIFS, VTY_NEWLINE); diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index cc4f4f3dce..e1cc3a97cf 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -44,12 +44,18 @@ struct interface *pim_regiface = NULL; struct list *pim_ifchannel_list = NULL; +static int pim_iface_vif_index[MAXVIFS]; static void pim_if_igmp_join_del_all(struct interface *ifp); void pim_if_init (void) { + int i; + + for (i = 0; i < MAXVIFS; i++) + pim_iface_vif_index[i] = 0; + vrf_iflist_create(VRF_DEFAULT); pim_ifchannel_list = list_new(); pim_ifchannel_list->cmp = (int (*)(void *, void *))pim_ifchannel_compare; @@ -848,11 +854,10 @@ pim_find_primary_addr (struct interface *ifp) return addr; } -static int pim_iface_vif_index = 0; - 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. @@ -860,8 +865,12 @@ pim_iface_next_vif_index (struct interface *ifp) if (ifp->ifindex == PIM_OIF_PIM_REGISTER_VIF) return 0; - pim_iface_vif_index++; - return pim_iface_vif_index; + for (i = 1 ; i < MAXVIFS; i++) + { + if (pim_iface_vif_index[i] == 0) + return i; + } + return MAXVIFS; } /* @@ -921,41 +930,13 @@ int pim_if_add_vif(struct interface *ifp) return -5; } - /* - Update highest vif_index - */ - if (pim_ifp->mroute_vif_index != PIM_OIF_PIM_REGISTER_VIF && - pim_ifp->mroute_vif_index > qpim_mroute_oif_highest_vif_index) { - qpim_mroute_oif_highest_vif_index = pim_ifp->mroute_vif_index; - } - + pim_iface_vif_index[pim_ifp->mroute_vif_index] = 1; return 0; } -static int iflist_find_highest_vif_index() -{ - struct listnode *ifnode; - struct interface *ifp; - struct pim_interface *pim_ifp; - int highest_vif_index = -1; - - for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) { - pim_ifp = ifp->info; - if (!pim_ifp) - continue; - - if (pim_ifp->mroute_vif_index > highest_vif_index) { - highest_vif_index = pim_ifp->mroute_vif_index; - } - } - - return highest_vif_index; -} - int pim_if_del_vif(struct interface *ifp) { struct pim_interface *pim_ifp = ifp->info; - int old_vif_index; if (pim_ifp->mroute_vif_index < 1) { zlog_warn("%s: vif_index=%d < 1 on interface %s ifindex=%d", @@ -970,18 +951,12 @@ int pim_if_del_vif(struct interface *ifp) } /* - Update highest vif_index + Update vif_index */ - - /* save old vif_index in order to compare with highest below */ - old_vif_index = pim_ifp->mroute_vif_index; + pim_iface_vif_index[pim_ifp->mroute_vif_index] = 0; pim_ifp->mroute_vif_index = -1; - if (old_vif_index == qpim_mroute_oif_highest_vif_index) { - qpim_mroute_oif_highest_vif_index = iflist_find_highest_vif_index(); - } - return 0; } diff --git a/pimd/pimd.c b/pimd/pimd.c index c000a2364d..e0788772cb 100644 --- a/pimd/pimd.c +++ b/pimd/pimd.c @@ -49,7 +49,6 @@ 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_mroute_oif_highest_vif_index = -1; 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; @@ -122,7 +121,6 @@ void pim_init() qpim_static_route_list->del = (void (*)(void *)) pim_static_route_free; qpim_mroute_socket_fd = -1; /* mark mroute as disabled */ - qpim_mroute_oif_highest_vif_index = -1; qpim_inaddr_any.s_addr = PIM_NET_INADDR_ANY; diff --git a/pimd/pimd.h b/pimd/pimd.h index d43b64b0c3..2fca09ab6a 100644 --- a/pimd/pimd.h +++ b/pimd/pimd.h @@ -99,7 +99,6 @@ extern struct thread_master *master; uint32_t qpim_debugs; int qpim_mroute_socket_fd; int64_t qpim_mroute_socket_creation; /* timestamp of creation */ -int qpim_mroute_oif_highest_vif_index; 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; From f663aa7ad4028905632fdc4d6801522b8a17f731 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 25 Jan 2017 14:47:04 -0500 Subject: [PATCH 10/15] pimd: Use correct flag to add an oif When we are creating the igmp ifchannel we were creating it with both a P and a I flag. This was causing it to not be cleaned up properly when the interface was shut down. Subsuquently when the interface came back up we would attempt to add it back in but it would fail. Ticket: CM-14586 Signed-off-by: Donald Sharp --- pimd/pim_ifchannel.c | 19 +++++++++++++------ pimd/pim_ifchannel.h | 4 ++-- pimd/pim_zebra.c | 16 ++++++++++++---- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index 8d2de3c878..7056ade501 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -142,7 +142,11 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch) if (ch->upstream->channel_oil) { - pim_channel_del_oif (ch->upstream->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_PIM); + uint32_t mask = PIM_OIF_FLAG_PROTO_PIM; + if (ch->upstream->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP) + mask = PIM_OIF_FLAG_PROTO_IGMP; + + 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. @@ -929,8 +933,9 @@ void pim_ifchannel_prune(struct interface *ifp, } } -void 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; struct pim_interface *pim_ifp; @@ -938,13 +943,13 @@ void pim_ifchannel_local_membership_add(struct interface *ifp, /* PIM enabled on interface? */ pim_ifp = ifp->info; if (!pim_ifp) - return; + return 0; if (!PIM_IF_TEST_PIM(pim_ifp->options)) - return; + return 0; ch = pim_ifchannel_add(ifp, sg, PIM_UPSTREAM_FLAG_MASK_SRC_IGMP); if (!ch) { - return; + return 0; } ifmembership_set(ch, PIM_IFMEMBERSHIP_INCLUDE); @@ -969,6 +974,8 @@ void pim_ifchannel_local_membership_add(struct interface *ifp, } } } + + return 1; } void pim_ifchannel_local_membership_del(struct interface *ifp, diff --git a/pimd/pim_ifchannel.h b/pimd/pim_ifchannel.h index bfe632135c..a3dc0e9d83 100644 --- a/pimd/pim_ifchannel.h +++ b/pimd/pim_ifchannel.h @@ -130,8 +130,8 @@ void pim_ifchannel_prune(struct interface *ifp, struct prefix_sg *sg, uint8_t source_flags, uint16_t holdtime); -void 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); void pim_ifchannel_local_membership_del(struct interface *ifp, struct prefix_sg *sg); diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index aa09819fbe..1bb4852c6b 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -1097,7 +1097,13 @@ void igmp_source_forward_start(struct igmp_source *source) Feed IGMPv3-gathered local membership information into PIM per-interface (S,G) state. */ - pim_ifchannel_local_membership_add(group->group_igmp_sock->interface, &sg); + 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); } @@ -1167,6 +1173,7 @@ void igmp_source_forward_stop(struct igmp_source *source) void pim_forward_start(struct pim_ifchannel *ch) { struct pim_upstream *up = ch->upstream; + uint32_t mask = PIM_OIF_FLAG_PROTO_PIM; if (PIM_DEBUG_PIM_TRACE) { char source_str[INET_ADDRSTRLEN]; @@ -1206,9 +1213,10 @@ void pim_forward_start(struct pim_ifchannel *ch) } } - pim_channel_add_oif(up->channel_oil, - ch->interface, - PIM_OIF_FLAG_PROTO_PIM); + 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) From e34a317acf2addc6d864d238ed41f5977403af43 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 26 Jan 2017 19:14:06 -0500 Subject: [PATCH 11/15] pimd: Modify pimreg creation We were creating the pimreg device with a created ifindex of 255. This was causing issues when a interface was assigned a ifindex of 255 by the kernel. Subsuquently pim would stay in a hosed up state. Modify the ifindex used for the pimreg device to be 0. Ticket: CM-14625 Signed-off-by: Donald Sharp --- pimd/pim_iface.c | 2 +- pimd/pim_oil.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index e1cc3a97cf..7f64c9d5f2 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -893,7 +893,7 @@ int pim_if_add_vif(struct interface *ifp) return -1; } - if (ifp->ifindex < 1) { + if (ifp->ifindex < 0) { zlog_warn("%s: ifindex=%d < 1 on interface %s", __PRETTY_FUNCTION__, ifp->ifindex, ifp->name); diff --git a/pimd/pim_oil.h b/pimd/pim_oil.h index 6b96750ad1..e90cd5fc19 100644 --- a/pimd/pim_oil.h +++ b/pimd/pim_oil.h @@ -48,8 +48,8 @@ * Don't come running to me if this assumption is bad, * fix it. */ -#define PIM_OIF_PIM_REGISTER_VIF (MAXVIFS - 1) -#define PIM_MAX_USABLE_VIFS (MAXVIFS - 2) +#define PIM_OIF_PIM_REGISTER_VIF 0 +#define PIM_MAX_USABLE_VIFS (MAXVIFS - 1) struct channel_counts From 98573e196c0d15c8f753a13327066a62bde77dcd Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sun, 11 Dec 2016 19:28:08 -0500 Subject: [PATCH 12/15] pimd: Cleanup uninitialized memory access Valgrind noticed that we have a read of uninitialized memory: Conditional jump or move depends on uninitialised value(s) ==13749== at 0x428067: pim_ifassert_winner_set (pim_assert.c:57) ==13749== by 0x4266F0: pim_ifchannel_add (pim_ifchannel.c:535) ==13749== by 0x426CC1: pim_ifchannel_join_add (pim_ifchannel.c:730) ==13749== by 0x427B5B: recv_join (pim_join.c:95) ==13749== by 0x427B5B: pim_joinprune_recv (pim_join.c:270) ==13749== by 0x42354F: pim_pim_packet (pim_pim.c:249) ==13749== by 0x4236C0: pim_sock_read (pim_pim.c:349) ==13749== by 0x4E60587: thread_call (thread.c:1462) ==13749== by 0x40C75E: main (pim_main.c:266) ==13749== This commit fixes that issue. Signed-off-by: Donald Sharp --- pimd/pim_ifchannel.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index 7056ade501..0c0c2c4043 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -496,7 +496,7 @@ pim_ifchannel_add(struct interface *ifp, return NULL; } - ch = XMALLOC(MTYPE_PIM_IFCHANNEL, sizeof(*ch)); + 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__, @@ -535,6 +535,7 @@ pim_ifchannel_add(struct interface *ifp, /* 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); From 0b6817c5e7331732877090256492539e0e858fd8 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sun, 11 Dec 2016 19:02:46 -0500 Subject: [PATCH 13/15] pimd: Cleanup shutdown a bit more. Cleanup the shutdown of pim a bit more. Signed-off-by: Donald Sharp --- pimd/pim_mroute.c | 2 -- pimd/pim_msdp_socket.c | 2 -- pimd/pim_rp.c | 3 ++- pimd/pim_sock.c | 1 - pimd/pim_zlookup.c | 11 ++++++++--- pimd/pim_zlookup.h | 1 + pimd/pimd.c | 5 +++++ pimd/pimd.h | 1 + 8 files changed, 17 insertions(+), 9 deletions(-) diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index 05d08b6e91..bd9a1c4605 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -41,8 +41,6 @@ #include "pim_zlookup.h" /* GLOBAL VARS */ -extern struct zebra_privs_t pimd_privs; - static struct thread *qpim_mroute_socket_reader = NULL; static void mroute_read_on(void); diff --git a/pimd/pim_msdp_socket.c b/pimd/pim_msdp_socket.c index bc9720f1f3..805e812cae 100644 --- a/pimd/pim_msdp_socket.c +++ b/pimd/pim_msdp_socket.c @@ -31,8 +31,6 @@ #include "pim_msdp.h" #include "pim_msdp_socket.h" -extern struct zebra_privs_t pimd_privs; - /* increase socket send buffer size */ static void pim_msdp_update_sock_send_buffer_size (int fd) diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index ba464e98c6..dc19002a42 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -126,7 +126,8 @@ void pim_rp_free (void) { if (qpim_rp_list) - list_free (qpim_rp_list); + list_delete (qpim_rp_list); + qpim_rp_list = NULL; } /* diff --git a/pimd/pim_sock.c b/pimd/pim_sock.c index eda81c6571..11cd61b592 100644 --- a/pimd/pim_sock.c +++ b/pimd/pim_sock.c @@ -42,7 +42,6 @@ #include "pim_igmp_join.h" /* GLOBAL VARS */ -extern struct zebra_privs_t pimd_privs; int pim_socket_raw (int protocol) diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c index 61e3e27261..e1a8e820b7 100644 --- a/pimd/pim_zlookup.c +++ b/pimd/pim_zlookup.c @@ -120,6 +120,13 @@ static void zclient_lookup_failed(struct zclient *zlookup) zclient_lookup_reconnect(zlookup); } +void +zclient_lookup_free (void) +{ + zclient_free (zlookup); + zlookup = NULL; +} + void zclient_lookup_new (void) { @@ -131,9 +138,7 @@ zclient_lookup_new (void) } zlookup->sock = -1; - zlookup->ibuf = stream_new(ZEBRA_MAX_PACKET_SIZ); - zlookup->obuf = stream_new(ZEBRA_MAX_PACKET_SIZ); - zlookup->t_connect = 0; + zlookup->t_connect = NULL; zclient_lookup_sched_now(zlookup); diff --git a/pimd/pim_zlookup.h b/pimd/pim_zlookup.h index d8e7ff9e0d..34b1434c66 100644 --- a/pimd/pim_zlookup.h +++ b/pimd/pim_zlookup.h @@ -35,6 +35,7 @@ struct pim_zlookup_nexthop { }; void zclient_lookup_new (void); +void zclient_lookup_free (void); int zclient_lookup_nexthop(struct pim_zlookup_nexthop nexthop_tab[], const int tab_size, diff --git a/pimd/pimd.c b/pimd/pimd.c index e0788772cb..c9fd4d85f2 100644 --- a/pimd/pimd.c +++ b/pimd/pimd.c @@ -39,6 +39,7 @@ #include "pim_ssmpingd.h" #include "pim_static.h" #include "pim_rp.h" +#include "pim_zlookup.h" const char *const PIM_ALL_SYSTEMS = MCAST_ALL_SYSTEMS; const char *const PIM_ALL_ROUTERS = MCAST_ALL_ROUTERS; @@ -90,6 +91,10 @@ static void pim_free() pim_if_terminate (); pim_rp_free (); pim_route_map_terminate(); + + zclient_lookup_free (); + + zprivs_terminate(&pimd_privs); } void pim_init() diff --git a/pimd/pimd.h b/pimd/pimd.h index 2fca09ab6a..1f8dcdfb29 100644 --- a/pimd/pimd.h +++ b/pimd/pimd.h @@ -96,6 +96,7 @@ const char *const PIM_ALL_PIM_ROUTERS; const char *const PIM_ALL_IGMP_ROUTERS; 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 */ From a118e71d0e01e7923522f13e5ddd0f9e2803ec0a Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 24 Jan 2017 16:11:40 -0500 Subject: [PATCH 14/15] pimd: Fix handling of *,G on RP to allow prune of S,G to go out When on the RP we received a prune *,G for an established S,G If join_desired is no longer true we need to prune and reset some timers, in addition to removing the inherited interface from the olist. This was not happening because we were just removing the inherited oif from the *,G. Ticket: CM-14561 Signed-off-by: Donald Sharp --- pimd/pim_ifchannel.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index 0c0c2c4043..f0e4a3a68a 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -274,12 +274,16 @@ void pim_ifchannel_ifjoin_switch(const char *caller, continue; if (!pim_upstream_evaluate_join_desired (child)) - pim_channel_del_oif (c_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR); + { + 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); @@ -297,7 +301,7 @@ void pim_ifchannel_ifjoin_switch(const char *caller, if (pim_upstream_evaluate_join_desired (child)) { pim_channel_add_oif (child->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR); - pim_upstream_switch (child, PIM_UPSTREAM_JOINED); + pim_upstream_update_join_desired (child); } } } From 6bcc7f4b7ed40169802404c22bb619665730d5fa Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 31 Jan 2017 07:36:57 -0500 Subject: [PATCH 15/15] zebra: Do not force NEXTHOP_TYPE to XXX_IFINDEX The original goal of the zebra change was to force all: NEXTHOP_TYPE_IPV4 -> NEXTHOP_TYPE_IPV4_IFINDEX NEXTHOP_TYPE_IPV6 -> NEXTHOP_TYPE_IPV6_IFINDEX This causes issues in routes being installed into the kernel backing this out until I can get time to fully understand what is going wrong. Signed-off-by: Donald Sharp --- zebra/zebra_rib.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 7faf4c7e04..c1c1f897a1 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -471,16 +471,9 @@ nexthop_active (afi_t afi, struct rib *rib, struct nexthop *nexthop, int set, newhop = match->nexthop; if (newhop) { - if (nexthop->type == NEXTHOP_TYPE_IPV4) - { - nexthop->ifindex = newhop->ifindex; - nexthop->type = NEXTHOP_TYPE_IPV4; - } - if (nexthop->type == NEXTHOP_TYPE_IPV6) - { - nexthop->ifindex = newhop->ifindex; - nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX; - } + if (nexthop->type == NEXTHOP_TYPE_IPV4 || + nexthop->type == NEXTHOP_TYPE_IPV6) + nexthop->ifindex = newhop->ifindex; } return 1; }