diff options
Diffstat (limited to 'pimd')
| -rw-r--r-- | pimd/pim_bfd.c | 6 | ||||
| -rw-r--r-- | pimd/pim_bsm.c | 6 | ||||
| -rw-r--r-- | pimd/pim_bsm.h | 3 | ||||
| -rw-r--r-- | pimd/pim_cmd.c | 151 | ||||
| -rw-r--r-- | pimd/pim_hello.c | 16 | ||||
| -rw-r--r-- | pimd/pim_ifchannel.c | 61 | ||||
| -rw-r--r-- | pimd/pim_igmp.c | 4 | ||||
| -rw-r--r-- | pimd/pim_igmpv2.c | 31 | ||||
| -rw-r--r-- | pimd/pim_igmpv2.h | 2 | ||||
| -rw-r--r-- | pimd/pim_instance.c | 8 | ||||
| -rw-r--r-- | pimd/pim_jp_agg.c | 26 | ||||
| -rw-r--r-- | pimd/pim_mroute.c | 9 | ||||
| -rw-r--r-- | pimd/pim_msdp_socket.c | 4 | ||||
| -rw-r--r-- | pimd/pim_nb_config.c | 3 | ||||
| -rw-r--r-- | pimd/pim_rp.c | 4 | ||||
| -rw-r--r-- | pimd/pim_rp.h | 1 | ||||
| -rw-r--r-- | pimd/pim_upstream.c | 7 | ||||
| -rw-r--r-- | pimd/pim_vxlan.c | 22 | ||||
| -rw-r--r-- | pimd/test_igmpv3_join.c | 5 |
19 files changed, 298 insertions, 71 deletions
diff --git a/pimd/pim_bfd.c b/pimd/pim_bfd.c index 1d653cdc3f..5e1b9a69e1 100644 --- a/pimd/pim_bfd.c +++ b/pimd/pim_bfd.c @@ -217,7 +217,7 @@ static int pim_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS) { struct interface *ifp = NULL; struct pim_interface *pim_ifp = NULL; - struct prefix p; + struct prefix p, src_p; int status; char msg[100]; int old_status; @@ -227,8 +227,8 @@ static int pim_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS) struct listnode *neigh_nextnode = NULL; struct pim_neighbor *neigh = NULL; - ifp = bfd_get_peer_info(zclient->ibuf, &p, NULL, &status, - NULL, vrf_id); + ifp = bfd_get_peer_info(zclient->ibuf, &p, &src_p, &status, NULL, + vrf_id); if ((ifp == NULL) || (p.family != AF_INET)) return 0; diff --git a/pimd/pim_bsm.c b/pimd/pim_bsm.c index 1acfece895..e873af5759 100644 --- a/pimd/pim_bsm.c +++ b/pimd/pim_bsm.c @@ -63,7 +63,7 @@ void pim_bsm_write_config(struct vty *vty, struct interface *ifp) } } -static void pim_free_bsgrp_data(struct bsgrp_node *bsgrp_node) +void pim_free_bsgrp_data(struct bsgrp_node *bsgrp_node) { if (bsgrp_node->bsrp_list) list_delete(&bsgrp_node->bsrp_list); @@ -72,7 +72,7 @@ static void pim_free_bsgrp_data(struct bsgrp_node *bsgrp_node) XFREE(MTYPE_PIM_BSGRP_NODE, bsgrp_node); } -static void pim_free_bsgrp_node(struct route_table *rt, struct prefix *grp) +void pim_free_bsgrp_node(struct route_table *rt, struct prefix *grp) { struct route_node *rn; @@ -222,7 +222,7 @@ static int pim_on_bs_timer(struct thread *t) return 0; } -static void pim_bs_timer_stop(struct bsm_scope *scope) +void pim_bs_timer_stop(struct bsm_scope *scope) { if (PIM_DEBUG_BSM) zlog_debug("%s : BS timer being stopped of sz: %d", __func__, diff --git a/pimd/pim_bsm.h b/pimd/pim_bsm.h index 0758c94f19..2829c1e05a 100644 --- a/pimd/pim_bsm.h +++ b/pimd/pim_bsm.h @@ -195,4 +195,7 @@ int pim_bsm_process(struct interface *ifp, bool pim_bsm_new_nbr_fwd(struct pim_neighbor *neigh, struct interface *ifp); struct bsgrp_node *pim_bsm_get_bsgrp_node(struct bsm_scope *scope, struct prefix *grp); +void pim_bs_timer_stop(struct bsm_scope *scope); +void pim_free_bsgrp_data(struct bsgrp_node *bsgrp_node); +void pim_free_bsgrp_node(struct route_table *rt, struct prefix *grp); #endif diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 8e08dc724b..714d6e8e1d 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -4049,6 +4049,152 @@ DEFUN (clear_ip_pim_oil, return CMD_SUCCESS; } +static void clear_pim_bsr_db(struct pim_instance *pim) +{ + struct route_node *rn; + struct route_node *rpnode; + struct bsgrp_node *bsgrp; + struct prefix nht_p; + struct prefix g_all; + struct rp_info *rp_all; + struct pim_upstream *up; + struct rp_info *rp_info; + bool is_bsr_tracking = true; + + /* Remove next hop tracking for the bsr */ + nht_p.family = AF_INET; + nht_p.prefixlen = IPV4_MAX_BITLEN; + nht_p.u.prefix4 = pim->global_scope.current_bsr; + if (PIM_DEBUG_BSM) { + zlog_debug("%s: Deregister BSR addr %pFX with Zebra NHT", + __func__, &nht_p); + } + pim_delete_tracked_nexthop(pim, &nht_p, NULL, NULL, is_bsr_tracking); + + /* Reset scope zone data */ + pim->global_scope.accept_nofwd_bsm = false; + pim->global_scope.state = ACCEPT_ANY; + pim->global_scope.current_bsr.s_addr = INADDR_ANY; + pim->global_scope.current_bsr_prio = 0; + pim->global_scope.current_bsr_first_ts = 0; + pim->global_scope.current_bsr_last_ts = 0; + pim->global_scope.bsm_frag_tag = 0; + list_delete_all_node(pim->global_scope.bsm_list); + + pim_bs_timer_stop(&pim->global_scope); + + for (rn = route_top(pim->global_scope.bsrp_table); rn; + rn = route_next(rn)) { + bsgrp = rn->info; + if (!bsgrp) + continue; + + rpnode = route_node_lookup(pim->rp_table, &bsgrp->group); + + if (!rpnode) { + pim_free_bsgrp_node(bsgrp->scope->bsrp_table, + &bsgrp->group); + pim_free_bsgrp_data(bsgrp); + continue; + } + + rp_info = (struct rp_info *)rpnode->info; + + if ((!rp_info) || (rp_info->rp_src != RP_SRC_BSR)) { + pim_free_bsgrp_node(bsgrp->scope->bsrp_table, + &bsgrp->group); + pim_free_bsgrp_data(bsgrp); + continue; + } + + /* 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_NHT_RP) { + zlog_debug("%s: Deregister RP addr %pFX with Zebra ", + __func__, &nht_p); + } + + pim_delete_tracked_nexthop(pim, &nht_p, NULL, rp_info, false); + + if (!str2prefix("224.0.0.0/4", &g_all)) + return; + + rp_all = pim_rp_find_match_group(pim, &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; + } else { + /* Delete the rp_info from rp-list */ + listnode_delete(pim->rp_list, rp_info); + + /* Delete the rp node from rp_table */ + rpnode->info = NULL; + route_unlock_node(rpnode); + route_unlock_node(rpnode); + } + + XFREE(MTYPE_PIM_RP, rp_info); + + pim_free_bsgrp_node(bsgrp->scope->bsrp_table, &bsgrp->group); + pim_free_bsgrp_data(bsgrp); + } + pim_rp_refresh_group_to_rp_mapping(pim); + + + frr_each (rb_pim_upstream, &pim->upstream_head, up) { + /* Find the upstream (*, G) whose upstream address is same as + * the RP + */ + if (up->sg.src.s_addr != INADDR_ANY) + continue; + + struct prefix grp; + struct rp_info *trp_info; + + grp.family = AF_INET; + grp.prefixlen = IPV4_MAX_BITLEN; + grp.u.prefix4 = up->sg.grp; + + trp_info = pim_rp_find_match_group(pim, &grp); + + /* RP not found for the group grp */ + if (pim_rpf_addr_is_inaddr_none(&trp_info->rp)) { + pim_upstream_rpf_clear(pim, up); + pim_rp_set_upstream_addr(pim, &up->upstream_addr, + up->sg.src, up->sg.grp); + } else { + /* RP found for the group grp */ + pim_upstream_update(pim, up); + } + } +} + + +DEFUN (clear_ip_pim_bsr_db, + clear_ip_pim_bsr_db_cmd, + "clear ip pim [vrf NAME] bsr-data", + CLEAR_STR + IP_STR + CLEAR_IP_PIM_STR + VRF_CMD_HELP_STR + "Reset pim bsr data\n") +{ + int idx = 2; + struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); + + if (!vrf) + return CMD_WARNING; + + clear_pim_bsr_db(vrf->info); + + return CMD_SUCCESS; +} + DEFUN (show_ip_igmp_interface, show_ip_igmp_interface_cmd, "show ip igmp [vrf NAME] interface [detail|WORD] [json]", @@ -10927,9 +11073,9 @@ static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg *vxlan_sg, } } -static void pim_show_vxlan_sg_hash_entry(struct hash_bucket *backet, void *arg) +static void pim_show_vxlan_sg_hash_entry(struct hash_bucket *bucket, void *arg) { - pim_show_vxlan_sg_entry((struct pim_vxlan_sg *)backet->data, + pim_show_vxlan_sg_entry((struct pim_vxlan_sg *)bucket->data, (struct pim_sg_cache_walk_data *)arg); } @@ -11447,6 +11593,7 @@ void pim_cmd_init(void) install_element(ENABLE_NODE, &clear_ip_pim_interface_traffic_cmd); install_element(ENABLE_NODE, &clear_ip_pim_oil_cmd); install_element(ENABLE_NODE, &clear_ip_pim_statistics_cmd); + install_element(ENABLE_NODE, &clear_ip_pim_bsr_db_cmd); install_element(ENABLE_NODE, &show_debugging_pim_cmd); diff --git a/pimd/pim_hello.c b/pimd/pim_hello.c index e50504ec10..6f5c4174e2 100644 --- a/pimd/pim_hello.c +++ b/pimd/pim_hello.c @@ -95,22 +95,6 @@ static void tlv_trace_uint32_hex(const char *label, const char *tlv_name, } } -#if 0 -static void tlv_trace(const char *label, const char *tlv_name, - const char *ifname, struct in_addr src_addr, - int isset) -{ - 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", - label, - src_str, ifname, - tlv_name); - } -} -#endif - 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) diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index e7ff434f4b..cdaf7bcdd4 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -550,8 +550,21 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp, struct pim_upstream *up; ch = pim_ifchannel_find(ifp, sg); - if (ch) + if (ch) { + if (up_flags == PIM_UPSTREAM_FLAG_MASK_SRC_PIM) + PIM_IF_FLAG_SET_PROTO_PIM(ch->flags); + + if (up_flags == PIM_UPSTREAM_FLAG_MASK_SRC_IGMP) + PIM_IF_FLAG_SET_PROTO_IGMP(ch->flags); + + if (ch->upstream) + ch->upstream->flags |= up_flags; + else if (PIM_DEBUG_EVENTS) + zlog_debug("%s:%s No Upstream found", __func__, + pim_str_sg_dump(sg)); + return ch; + } pim_ifp = ifp->info; @@ -642,6 +655,12 @@ static void ifjoin_to_noinfo(struct pim_ifchannel *ch, bool ch_del) { pim_forward_stop(ch, !ch_del); pim_ifchannel_ifjoin_switch(__func__, ch, PIM_IFJOIN_NOINFO); + + if (ch->upstream) + PIM_UPSTREAM_FLAG_UNSET_SRC_PIM(ch->upstream->flags); + + PIM_IF_FLAG_UNSET_PROTO_PIM(ch->flags); + if (ch_del) delete_on_noinfo(ch); } @@ -710,6 +729,21 @@ static int on_ifjoin_prune_pending_timer(struct thread *t) pim_jp_agg_single_upstream_send(&parent->rpf, parent, true); + /* + * SGRpt prune pending expiry has to install + * SG entry with empty olist to drop the SG + * traffic incase no other intf exists. + * On that scenario, SG entry wouldn't have + * got installed until Prune pending timer + * expired. So install now. + */ + pim_channel_del_oif( + ch->upstream->channel_oil, ifp, + PIM_OIF_FLAG_PROTO_STAR, __func__); + if (!ch->upstream->channel_oil->installed) + pim_upstream_mroute_add( + ch->upstream->channel_oil, + __PRETTY_FUNCTION__); } } /* from here ch may have been deleted */ @@ -1094,6 +1128,24 @@ void pim_ifchannel_prune(struct interface *ifp, struct in_addr upstream, case PIM_IFJOIN_PRUNE: if (source_flags & PIM_ENCODE_RPT_BIT) { THREAD_OFF(ch->t_ifjoin_prune_pending_timer); + /* + * While in Prune State, Receive SGRpt Prune. + * RFC 7761 Sec 4.5.3: + * The (S,G,rpt) downstream state machine on interface I + * remains in Prune state. The Expiry Timer (ET) is + * restarted and is then set to the maximum of its + * current value and the HoldTime from the triggering + * Join/Prune message. + */ + if (ch->t_ifjoin_expiry_timer) { + unsigned long rem = thread_timer_remain_second( + ch->t_ifjoin_expiry_timer); + + if (rem > holdtime) + return; + THREAD_OFF(ch->t_ifjoin_expiry_timer); + } + thread_add_timer(router->master, on_ifjoin_expiry_timer, ch, holdtime, &ch->t_ifjoin_expiry_timer); @@ -1272,6 +1324,13 @@ void pim_ifchannel_local_membership_del(struct interface *ifp, * parent' delete_no_info */ } } + + /* Resettng the IGMP flags here */ + if (orig->upstream) + PIM_UPSTREAM_FLAG_UNSET_SRC_IGMP(orig->upstream->flags); + + PIM_IF_FLAG_UNSET_PROTO_IGMP(orig->flags); + delete_on_noinfo(orig); } diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c index 9924e335b0..73e42e9d83 100644 --- a/pimd/pim_igmp.c +++ b/pimd/pim_igmp.c @@ -558,8 +558,8 @@ int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len) 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); + return igmp_v2_recv_leave(igmp, ip_hdr, from_str, igmp_msg, + igmp_msg_len); case PIM_IGMP_MTRACE_RESPONSE: return igmp_mtrace_recv_response(igmp, ip_hdr, ip_hdr->ip_src, diff --git a/pimd/pim_igmpv2.c b/pimd/pim_igmpv2.c index d836c66cbb..7f3c7a0f8c 100644 --- a/pimd/pim_igmpv2.c +++ b/pimd/pim_igmpv2.c @@ -158,12 +158,13 @@ int igmp_v2_recv_report(struct igmp_sock *igmp, struct in_addr from, return 0; } -int igmp_v2_recv_leave(struct igmp_sock *igmp, struct in_addr from, +int igmp_v2_recv_leave(struct igmp_sock *igmp, struct ip *ip_hdr, 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]; + struct in_addr from = ip_hdr->ip_src; on_trace(__func__, igmp->interface, from); @@ -184,8 +185,6 @@ int igmp_v2_recv_leave(struct igmp_sock *igmp, struct in_addr from, return -1; } - /* Collecting IGMP Rx stats */ - igmp->rx_stats.leave_v2++; memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr)); @@ -195,6 +194,32 @@ int igmp_v2_recv_leave(struct igmp_sock *igmp, struct in_addr from, zlog_debug("Recv IGMPv2 LEAVE from %s on %s for %s", from_str, ifp->name, group_str); } + /* + * As per RFC 2236, section 9: + Message Type Destination Group + ------------ ----------------- + General Query ALL-SYSTEMS (224.0.0.1) + Group-Specific Query The group being queried + Membership Report The group being reported + Leave Message ALL-ROUTERS (224.0.0.2) + + Note: in older (i.e., non-standard and now obsolete) versions of + IGMPv2, hosts send Leave Messages to the group being left. A + router SHOULD accept Leave Messages addressed to the group being + left in the interests of backwards compatibility with such hosts. + In all cases, however, hosts MUST send to the ALL-ROUTERS address + to be compliant with this specification. + */ + if ((ntohl(ip_hdr->ip_dst.s_addr) != INADDR_ALLRTRS_GROUP) + && (ip_hdr->ip_dst.s_addr != group_addr.s_addr)) { + if (PIM_DEBUG_IGMP_EVENTS) + zlog_debug( + "IGMPv2 Leave message is ignored since received on address other than ALL-ROUTERS or Group-address"); + return -1; + } + + /* Collecting IGMP Rx stats */ + igmp->rx_stats.leave_v2++; /* * RFC 3376 diff --git a/pimd/pim_igmpv2.h b/pimd/pim_igmpv2.h index f0a6fdc5fb..29591ff16c 100644 --- a/pimd/pim_igmpv2.h +++ b/pimd/pim_igmpv2.h @@ -29,7 +29,7 @@ void igmp_v2_send_query(struct igmp_group *group, int fd, const char *ifname, 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, +int igmp_v2_recv_leave(struct igmp_sock *igmp, struct ip *ip_hdr, const char *from_str, char *igmp_msg, int igmp_msg_len); #endif /* PIM_IGMPV2_H */ diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c index b7e49078ef..019048abf1 100644 --- a/pimd/pim_instance.c +++ b/pimd/pim_instance.c @@ -71,6 +71,8 @@ static void pim_instance_terminate(struct pim_instance *pim) XFREE(MTYPE_PIM_PLIST_NAME, pim->spt.plist); XFREE(MTYPE_PIM_PLIST_NAME, pim->register_plist); + + pim->vrf = NULL; XFREE(MTYPE_PIM_PIM_INSTANCE, pim); } @@ -153,10 +155,16 @@ static int pim_vrf_delete(struct vrf *vrf) { struct pim_instance *pim = vrf->info; + if (!pim) + return 0; + zlog_debug("VRF Deletion: %s(%u)", vrf->name, vrf->vrf_id); pim_ssmpingd_destroy(pim); pim_instance_terminate(pim); + + vrf->info = NULL; + return 0; } diff --git a/pimd/pim_jp_agg.c b/pimd/pim_jp_agg.c index 5279a00855..d95d9dd25d 100644 --- a/pimd/pim_jp_agg.c +++ b/pimd/pim_jp_agg.c @@ -360,11 +360,9 @@ void pim_jp_agg_switch_interface(struct pim_rpf *orpf, struct pim_rpf *nrpf, 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 bool first = true; + struct list groups, sources; + struct pim_jp_agg_group jag; + struct pim_jp_sources js; /* skip JP upstream messages if source is directly connected */ if (!up || !rpf->source_nexthop.interface || @@ -373,19 +371,19 @@ void pim_jp_agg_single_upstream_send(struct pim_rpf *rpf, if_is_loopback_or_vrf(rpf->source_nexthop.interface)) return; - if (first) { - groups = list_new(); - jag.sources = list_new(); - - listnode_add(groups, &jag); - listnode_add(jag.sources, &js); + memset(&groups, 0, sizeof(groups)); + memset(&sources, 0, sizeof(sources)); + jag.sources = &sources; - first = false; - } + listnode_add(&groups, &jag); + listnode_add(jag.sources, &js); 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); + + list_delete_all_node(jag.sources); + list_delete_all_node(&groups); } diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index 0bccba397b..afd38face3 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -628,7 +628,7 @@ static int pim_mroute_msg(struct pim_instance *pim, const char *buf, ifaddr = connected_src->u.prefix4; igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->igmp_socket_list, ifaddr); - if (PIM_DEBUG_MROUTE) { + if (PIM_DEBUG_IGMP_PACKETS) { zlog_debug( "%s(%s): igmp kernel upcall on %s(%p) for %pI4 -> %pI4", __func__, pim->vrf->name, ifp->name, igmp, @@ -1221,10 +1221,9 @@ void pim_mroute_update_counters(struct channel_oil *c_oil) 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)); + zlog_debug( + "Channel%s is not installed no need to collect data from kernel", + pim_str_sg_dump(&sg)); } return; } diff --git a/pimd/pim_msdp_socket.c b/pimd/pim_msdp_socket.c index 7620cd5792..ddd8dc6bf9 100644 --- a/pimd/pim_msdp_socket.c +++ b/pimd/pim_msdp_socket.c @@ -44,7 +44,7 @@ static void pim_msdp_update_sock_send_buffer_size(int fd) if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &optval, &optlen) < 0) { flog_err_sys(EC_LIB_SOCKET, - "getsockopt of SO_SNDBUF failed %s\n", + "getsockopt of SO_SNDBUF failed %s", safe_strerror(errno)); return; } @@ -53,7 +53,7 @@ static void pim_msdp_update_sock_send_buffer_size(int fd) if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) < 0) { flog_err_sys(EC_LIB_SOCKET, - "Couldn't increase send buffer: %s\n", + "Couldn't increase send buffer: %s", safe_strerror(errno)); } } diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c index ba044de2f8..4bc78529a8 100644 --- a/pimd/pim_nb_config.c +++ b/pimd/pim_nb_config.c @@ -545,7 +545,7 @@ static int pim_cmd_igmp_start(struct interface *ifp) pim_ifp = ifp->info; if (!pim_ifp) { - (void)pim_if_new(ifp, true, false, false, false); + pim_ifp = pim_if_new(ifp, true, false, false, false); need_startup = 1; } else { if (!PIM_IF_TEST_IGMP(pim_ifp->options)) { @@ -553,6 +553,7 @@ static int pim_cmd_igmp_start(struct interface *ifp) need_startup = 1; } } + pim_if_create_pimreg(pim_ifp->pim); /* 'ip igmp' executed multiple times, with need_startup * avoid multiple if add all and membership refresh diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index fa5d6f37bf..dbba6b66d8 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -242,7 +242,7 @@ struct rp_info *pim_rp_find_match_group(struct pim_instance *pim, if (!rn) { flog_err( EC_LIB_DEVELOPMENT, - "%s: BUG We should have found default group information\n", + "%s: BUG We should have found default group information", __func__); return best; } @@ -271,7 +271,7 @@ struct rp_info *pim_rp_find_match_group(struct pim_instance *pim, * * This is a placeholder function for now. */ -static void pim_rp_refresh_group_to_rp_mapping(struct pim_instance *pim) +void pim_rp_refresh_group_to_rp_mapping(struct pim_instance *pim) { pim_msdp_i_am_rp_changed(pim); pim_upstream_reeval_use_rpt(pim); diff --git a/pimd/pim_rp.h b/pimd/pim_rp.h index 8a12cb076c..dd7cd5d75e 100644 --- a/pimd/pim_rp.h +++ b/pimd/pim_rp.h @@ -86,4 +86,5 @@ int pim_rp_list_cmp(void *v1, void *v2); struct rp_info *pim_rp_find_match_group(struct pim_instance *pim, const struct prefix *group); void pim_upstream_update(struct pim_instance *pim, struct pim_upstream *up); +void pim_rp_refresh_group_to_rp_mapping(struct pim_instance *pim); #endif diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index d95b092d94..9899172e6c 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -749,6 +749,13 @@ void pim_upstream_switch(struct pim_instance *pim, struct pim_upstream *up, bool send_xg_jp = false; forward_off(up); + /* + * RFC 4601 Sec 4.5.7: + * JoinDesired(S,G) -> False, set SPTbit to false. + */ + if (up->sg.src.s_addr != INADDR_ANY) + up->sptbit = PIM_UPSTREAM_SPTBIT_FALSE; + if (old_state == PIM_UPSTREAM_JOINED) pim_msdp_up_join_state_changed(pim, up); diff --git a/pimd/pim_vxlan.c b/pimd/pim_vxlan.c index 380c97a97c..6a12c7fb13 100644 --- a/pimd/pim_vxlan.c +++ b/pimd/pim_vxlan.c @@ -497,10 +497,10 @@ static void pim_vxlan_orig_mr_del(struct pim_vxlan_sg *vxlan_sg) pim_vxlan_orig_mr_up_del(vxlan_sg); } -static void pim_vxlan_orig_mr_iif_update(struct hash_bucket *backet, void *arg) +static void pim_vxlan_orig_mr_iif_update(struct hash_bucket *bucket, void *arg) { struct interface *ifp; - struct pim_vxlan_sg *vxlan_sg = (struct pim_vxlan_sg *)backet->data; + struct pim_vxlan_sg *vxlan_sg = (struct pim_vxlan_sg *)bucket->data; struct interface *old_iif = vxlan_sg->iif; if (!pim_vxlan_is_orig_mroute(vxlan_sg)) @@ -812,11 +812,11 @@ bool pim_vxlan_do_mlag_reg(void) * to the MLAG peer which may mroute it over the underlay if there are any * interested receivers. */ -static void pim_vxlan_sg_peerlink_oif_update(struct hash_bucket *backet, +static void pim_vxlan_sg_peerlink_oif_update(struct hash_bucket *bucket, void *arg) { struct interface *new_oif = (struct interface *)arg; - struct pim_vxlan_sg *vxlan_sg = (struct pim_vxlan_sg *)backet->data; + struct pim_vxlan_sg *vxlan_sg = (struct pim_vxlan_sg *)bucket->data; if (!pim_vxlan_is_orig_mroute(vxlan_sg)) return; @@ -950,10 +950,10 @@ static void pim_vxlan_up_cost_update(struct pim_instance *pim, } } -static void pim_vxlan_term_mr_cost_update(struct hash_bucket *backet, void *arg) +static void pim_vxlan_term_mr_cost_update(struct hash_bucket *bucket, void *arg) { struct interface *old_peerlink_rif = (struct interface *)arg; - struct pim_vxlan_sg *vxlan_sg = (struct pim_vxlan_sg *)backet->data; + struct pim_vxlan_sg *vxlan_sg = (struct pim_vxlan_sg *)bucket->data; struct pim_upstream *up; struct listnode *listnode; struct pim_upstream *child; @@ -975,11 +975,11 @@ static void pim_vxlan_term_mr_cost_update(struct hash_bucket *backet, void *arg) old_peerlink_rif); } -static void pim_vxlan_sg_peerlink_rif_update(struct hash_bucket *backet, +static void pim_vxlan_sg_peerlink_rif_update(struct hash_bucket *bucket, void *arg) { - pim_vxlan_orig_mr_iif_update(backet, NULL); - pim_vxlan_term_mr_cost_update(backet, arg); + pim_vxlan_orig_mr_iif_update(bucket, NULL); + pim_vxlan_term_mr_cost_update(bucket, arg); } static void pim_vxlan_set_peerlink_rif(struct pim_instance *pim, @@ -1032,10 +1032,10 @@ static void pim_vxlan_set_peerlink_rif(struct pim_instance *pim, } } -static void pim_vxlan_term_mr_oif_update(struct hash_bucket *backet, void *arg) +static void pim_vxlan_term_mr_oif_update(struct hash_bucket *bucket, void *arg) { struct interface *ifp = (struct interface *)arg; - struct pim_vxlan_sg *vxlan_sg = (struct pim_vxlan_sg *)backet->data; + struct pim_vxlan_sg *vxlan_sg = (struct pim_vxlan_sg *)bucket->data; if (pim_vxlan_is_orig_mroute(vxlan_sg)) return; diff --git a/pimd/test_igmpv3_join.c b/pimd/test_igmpv3_join.c index bf44f3c94a..3c26517e88 100644 --- a/pimd/test_igmpv3_join.c +++ b/pimd/test_igmpv3_join.c @@ -54,11 +54,6 @@ static int iface_solve_index(const char *ifname) } 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; |
