mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-02 20:27:14 +00:00
pimd: pim_rp.c -> convert pimg to pim
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
25b787a287
commit
fec883d95a
@ -4287,7 +4287,7 @@ static int pim_rp_cmd_worker(struct vty *vty, const char *rp, const char *group,
|
||||
{
|
||||
int result;
|
||||
|
||||
result = pim_rp_new(rp, group, plist);
|
||||
result = pim_rp_new(pimg, rp, group, plist);
|
||||
|
||||
if (result == PIM_MALLOC_FAIL) {
|
||||
vty_out(vty, "%% Out of memory\n");
|
||||
@ -4565,7 +4565,7 @@ DEFUN (ip_pim_rp_prefix_list,
|
||||
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(pimg, rp, group, plist);
|
||||
|
||||
if (result == PIM_GROUP_BAD_ADDRESS) {
|
||||
vty_out(vty, "%% Bad group address specified: %s\n", group);
|
||||
|
@ -829,7 +829,7 @@ void pim_if_addr_add_all(struct interface *ifp)
|
||||
}
|
||||
pim_ifchannel_scan_forward_start(ifp);
|
||||
|
||||
pim_rp_setup();
|
||||
pim_rp_setup(pim_ifp->pim);
|
||||
pim_rp_check_on_if_add(pim_ifp);
|
||||
}
|
||||
|
||||
@ -852,8 +852,8 @@ void pim_if_addr_del_all(struct interface *ifp)
|
||||
pim_if_addr_del(ifc, 1 /* force_prim_as_any=true */);
|
||||
}
|
||||
|
||||
pim_rp_setup();
|
||||
pim_i_am_rp_re_evaluate();
|
||||
pim_rp_setup(pimg);
|
||||
pim_i_am_rp_re_evaluate(pimg);
|
||||
}
|
||||
|
||||
void pim_if_addr_del_all_igmp(struct interface *ifp)
|
||||
@ -940,6 +940,7 @@ struct in_addr pim_find_primary_addr(struct interface *ifp)
|
||||
*/
|
||||
if (!v4_addrs && v6_addrs && !if_is_loopback(ifp)) {
|
||||
struct interface *lo_ifp;
|
||||
// DBS - Come back and check here
|
||||
lo_ifp = if_lookup_by_name("lo", pimg->vrf_id);
|
||||
if (lo_ifp)
|
||||
return pim_find_primary_addr(lo_ifp);
|
||||
|
@ -80,7 +80,7 @@ static void recv_join(struct interface *ifp, struct pim_neighbor *neigh,
|
||||
*/
|
||||
if ((source_flags & PIM_RPT_BIT_MASK)
|
||||
&& (source_flags & PIM_WILDCARD_BIT_MASK)) {
|
||||
struct pim_rpf *rp = RP(sg->grp);
|
||||
struct pim_rpf *rp = RP(pim_ifp->pim, sg->grp);
|
||||
|
||||
/*
|
||||
* If the RP sent in the message is not
|
||||
@ -124,7 +124,7 @@ static void recv_prune(struct interface *ifp, struct pim_neighbor *neigh,
|
||||
|
||||
if ((source_flags & PIM_RPT_BIT_MASK)
|
||||
&& (source_flags & PIM_WILDCARD_BIT_MASK)) {
|
||||
struct pim_rpf *rp = RP(sg->grp);
|
||||
struct pim_rpf *rp = RP(pim_ifp->pim, sg->grp);
|
||||
|
||||
// Ignoring Prune *,G's at the moment.
|
||||
if (sg->src.s_addr != rp->rpf_addr.u.prefix4.s_addr)
|
||||
|
@ -137,7 +137,7 @@ static int pim_mroute_msg_nocache(int fd, struct interface *ifp,
|
||||
struct pim_rpf *rpg;
|
||||
struct prefix_sg sg;
|
||||
|
||||
rpg = RP(msg->im_dst);
|
||||
rpg = RP(pim_ifp->pim, msg->im_dst);
|
||||
/*
|
||||
* If the incoming interface is unknown OR
|
||||
* the Interface type is SSM we don't need to
|
||||
@ -259,7 +259,7 @@ static int pim_mroute_msg_wholepkt(int fd, struct interface *ifp,
|
||||
|
||||
pim_ifp = up->rpf.source_nexthop.interface->info;
|
||||
|
||||
rpg = RP(sg.grp);
|
||||
rpg = RP(pim_ifp->pim, sg.grp);
|
||||
|
||||
if ((pim_rpf_addr_is_inaddr_none(rpg)) || (!pim_ifp)
|
||||
|| (!(PIM_I_am_DR(pim_ifp)))) {
|
||||
@ -405,6 +405,8 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp,
|
||||
struct prefix_sg sg;
|
||||
struct channel_oil *oil;
|
||||
|
||||
pim_ifp = ifp->info;
|
||||
|
||||
memset(&sg, 0, sizeof(struct prefix_sg));
|
||||
sg.src = ip_hdr->ip_src;
|
||||
sg.grp = ip_hdr->ip_dst;
|
||||
@ -435,7 +437,7 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp,
|
||||
if (up) {
|
||||
struct pim_upstream *parent;
|
||||
struct pim_nexthop source;
|
||||
struct pim_rpf *rpf = RP(sg.grp);
|
||||
struct pim_rpf *rpf = RP(pim_ifp->pim, sg.grp);
|
||||
if (!rpf || !rpf->source_nexthop.interface)
|
||||
return 0;
|
||||
|
||||
|
@ -198,7 +198,8 @@ size_t pim_msg_build_jp_groups(struct pim_jp_groups *grp,
|
||||
grp->prunes++;
|
||||
|
||||
if (source->up->sg.src.s_addr == INADDR_ANY) {
|
||||
struct pim_rpf *rpf = pim_rp_g(source->up->sg.grp);
|
||||
struct pim_rpf *rpf =
|
||||
pim_rp_g(pimg, source->up->sg.grp);
|
||||
bits = PIM_ENCODE_SPARSE_BIT | PIM_ENCODE_WC_BIT
|
||||
| PIM_ENCODE_RPT_BIT;
|
||||
stosend = rpf->rpf_addr.u.prefix4;
|
||||
|
@ -553,9 +553,9 @@ pim_neighbor_add(struct interface *ifp, struct in_addr source_addr,
|
||||
Upon PIM neighbor UP, iterate all RPs and update
|
||||
nexthop cache with this neighbor.
|
||||
*/
|
||||
pim_resolve_rp_nh();
|
||||
pim_resolve_rp_nh(pim_ifp->pim);
|
||||
|
||||
pim_rp_setup();
|
||||
pim_rp_setup(pim_ifp->pim);
|
||||
|
||||
pim_neighbor_rpf_update();
|
||||
return neigh;
|
||||
|
@ -270,10 +270,13 @@ int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,
|
||||
int i_am_rp = 0;
|
||||
struct pim_interface *pim_ifp = NULL;
|
||||
|
||||
pim_ifp = ifp->info;
|
||||
|
||||
#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_rp_check_is_my_ip_address(pim_ifp->pim, ip_hdr->ip_dst,
|
||||
dest_addr)) {
|
||||
if (PIM_DEBUG_PIM_REG) {
|
||||
char dest[INET_ADDRSTRLEN];
|
||||
|
||||
@ -285,8 +288,6 @@ int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
pim_ifp = ifp->info;
|
||||
zassert(pim_ifp);
|
||||
++pim_ifp->pim_ifstat_reg_recv;
|
||||
|
||||
/*
|
||||
@ -330,8 +331,9 @@ int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,
|
||||
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))) {
|
||||
if (i_am_rp
|
||||
&& (dest_addr.s_addr
|
||||
== ((RP(pim_ifp->pim, sg.grp))->rpf_addr.u.prefix4.s_addr))) {
|
||||
sentRegisterStop = 0;
|
||||
|
||||
if (*bits & PIM_REGISTER_BORDER_BIT) {
|
||||
|
@ -259,13 +259,14 @@ static int pim_rp_check_interface_addrs(struct rp_info *rp_info,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pim_rp_check_interfaces(struct rp_info *rp_info)
|
||||
static void pim_rp_check_interfaces(struct pim_instance *pim,
|
||||
struct rp_info *rp_info)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct interface *ifp;
|
||||
|
||||
rp_info->i_am_rp = 0;
|
||||
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pimg->vrf_id), node, ifp)) {
|
||||
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), node, ifp)) {
|
||||
struct pim_interface *pim_ifp = ifp->info;
|
||||
|
||||
if (!pim_ifp)
|
||||
@ -277,7 +278,8 @@ static void pim_rp_check_interfaces(struct rp_info *rp_info)
|
||||
}
|
||||
}
|
||||
|
||||
int pim_rp_new(const char *rp, const char *group_range, const char *plist)
|
||||
int pim_rp_new(struct pim_instance *pim, const char *rp,
|
||||
const char *group_range, const char *plist)
|
||||
{
|
||||
int result = 0;
|
||||
struct rp_info *rp_info;
|
||||
@ -339,11 +341,11 @@ int pim_rp_new(const char *rp, const char *group_range, const char *plist)
|
||||
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,
|
||||
pim_rp_del(pim, rp, NULL,
|
||||
tmp_rp_info->plist);
|
||||
else
|
||||
pim_rp_del(
|
||||
rp,
|
||||
pim, rp,
|
||||
prefix2str(&tmp_rp_info->group,
|
||||
buffer, BUFSIZ),
|
||||
NULL);
|
||||
@ -375,7 +377,7 @@ int pim_rp_new(const char *rp, const char *group_range, const char *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);
|
||||
pim_rp_del(pim, rp, NULL, tmp_rp_info->plist);
|
||||
}
|
||||
}
|
||||
|
||||
@ -402,10 +404,10 @@ int pim_rp_new(const char *rp, const char *group_range, const char *plist)
|
||||
__PRETTY_FUNCTION__, buf, buf1);
|
||||
}
|
||||
memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
|
||||
if (pim_find_or_track_nexthop(pimg, &nht_p, NULL,
|
||||
rp_all, &pnc)) {
|
||||
if (pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_all,
|
||||
&pnc)) {
|
||||
if (!pim_ecmp_nexthop_search(
|
||||
pimg, &pnc,
|
||||
pim, &pnc,
|
||||
&rp_all->rp.source_nexthop, &nht_p,
|
||||
&rp_all->group, 1))
|
||||
return PIM_RP_NO_PATH;
|
||||
@ -416,7 +418,7 @@ int pim_rp_new(const char *rp, const char *group_range, const char *plist)
|
||||
!= 0)
|
||||
return PIM_RP_NO_PATH;
|
||||
}
|
||||
pim_rp_check_interfaces(rp_all);
|
||||
pim_rp_check_interfaces(pim, rp_all);
|
||||
pim_rp_refresh_group_to_rp_mapping();
|
||||
return PIM_SUCCESS;
|
||||
}
|
||||
@ -472,8 +474,8 @@ int pim_rp_new(const char *rp, const char *group_range, const char *plist)
|
||||
}
|
||||
|
||||
memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
|
||||
if (pim_find_or_track_nexthop(pimg, &nht_p, NULL, rp_info, &pnc)) {
|
||||
if (!pim_ecmp_nexthop_search(pimg, &pnc,
|
||||
if (pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, &pnc)) {
|
||||
if (!pim_ecmp_nexthop_search(pim, &pnc,
|
||||
&rp_info->rp.source_nexthop,
|
||||
&nht_p, &rp_info->group, 1))
|
||||
return PIM_RP_NO_PATH;
|
||||
@ -484,12 +486,13 @@ int pim_rp_new(const char *rp, const char *group_range, const char *plist)
|
||||
return PIM_RP_NO_PATH;
|
||||
}
|
||||
|
||||
pim_rp_check_interfaces(rp_info);
|
||||
pim_rp_check_interfaces(pim, 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(struct pim_instance *pim, const char *rp,
|
||||
const char *group_range, const char *plist)
|
||||
{
|
||||
struct prefix group;
|
||||
struct in_addr rp_addr;
|
||||
@ -534,7 +537,7 @@ int pim_rp_del(const char *rp, const char *group_range, const char *plist)
|
||||
zlog_debug("%s: Deregister RP addr %s with Zebra ",
|
||||
__PRETTY_FUNCTION__, buf);
|
||||
}
|
||||
pim_delete_tracked_nexthop(pimg, &nht_p, NULL, rp_info);
|
||||
pim_delete_tracked_nexthop(pim, &nht_p, NULL, rp_info);
|
||||
|
||||
str2prefix("224.0.0.0/4", &g_all);
|
||||
rp_all = pim_rp_find_match_group(&g_all);
|
||||
@ -551,7 +554,7 @@ int pim_rp_del(const char *rp, const char *group_range, const char *plist)
|
||||
return PIM_SUCCESS;
|
||||
}
|
||||
|
||||
void pim_rp_setup(void)
|
||||
void pim_rp_setup(struct pim_instance *pim)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct rp_info *rp_info;
|
||||
@ -566,9 +569,8 @@ void pim_rp_setup(void)
|
||||
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(pimg, &nht_p, NULL, rp_info,
|
||||
&pnc))
|
||||
pim_ecmp_nexthop_search(pimg, &pnc,
|
||||
if (pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, &pnc))
|
||||
pim_ecmp_nexthop_search(pim, &pnc,
|
||||
&rp_info->rp.source_nexthop,
|
||||
&nht_p, &rp_info->group, 1);
|
||||
else {
|
||||
@ -634,7 +636,7 @@ void pim_rp_check_on_if_add(struct pim_interface *pim_ifp)
|
||||
/* 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(struct pim_instance *pim)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct rp_info *rp_info;
|
||||
@ -649,7 +651,7 @@ void pim_i_am_rp_re_evaluate(void)
|
||||
continue;
|
||||
|
||||
old_i_am_rp = rp_info->i_am_rp;
|
||||
pim_rp_check_interfaces(rp_info);
|
||||
pim_rp_check_interfaces(pim, rp_info);
|
||||
|
||||
if (old_i_am_rp != rp_info->i_am_rp) {
|
||||
i_am_rp_changed = true;
|
||||
@ -702,7 +704,7 @@ int 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 pim_instance *pim, struct in_addr group)
|
||||
{
|
||||
struct prefix g;
|
||||
struct rp_info *rp_info;
|
||||
@ -731,9 +733,8 @@ struct pim_rpf *pim_rp_g(struct in_addr group)
|
||||
__PRETTY_FUNCTION__, buf, buf1);
|
||||
}
|
||||
memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
|
||||
if (pim_find_or_track_nexthop(pimg, &nht_p, NULL, rp_info,
|
||||
&pnc))
|
||||
pim_ecmp_nexthop_search(pimg, &pnc,
|
||||
if (pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, &pnc))
|
||||
pim_ecmp_nexthop_search(pim, &pnc,
|
||||
&rp_info->rp.source_nexthop,
|
||||
&nht_p, &rp_info->group, 1);
|
||||
else {
|
||||
@ -822,7 +823,8 @@ int pim_rp_config_write(struct vty *vty)
|
||||
return count;
|
||||
}
|
||||
|
||||
int pim_rp_check_is_my_ip_address(struct in_addr group,
|
||||
int pim_rp_check_is_my_ip_address(struct pim_instance *pim,
|
||||
struct in_addr group,
|
||||
struct in_addr dest_addr)
|
||||
{
|
||||
struct rp_info *rp_info;
|
||||
@ -845,7 +847,7 @@ int pim_rp_check_is_my_ip_address(struct in_addr group,
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (if_lookup_exact_address(&dest_addr, AF_INET, pimg->vrf_id))
|
||||
if (if_lookup_exact_address(&dest_addr, AF_INET, pim->vrf_id))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
@ -957,7 +959,7 @@ void pim_rp_show_information(struct vty *vty, u_char uj)
|
||||
}
|
||||
}
|
||||
|
||||
void pim_resolve_rp_nh(void)
|
||||
void pim_resolve_rp_nh(struct pim_instance *pim)
|
||||
{
|
||||
struct listnode *node = NULL;
|
||||
struct rp_info *rp_info = NULL;
|
||||
@ -974,7 +976,7 @@ void pim_resolve_rp_nh(void)
|
||||
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(pimg, &nht_p, NULL, rp_info,
|
||||
if (!pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info,
|
||||
&pnc))
|
||||
continue;
|
||||
|
||||
@ -983,7 +985,7 @@ void pim_resolve_rp_nh(void)
|
||||
continue;
|
||||
|
||||
struct interface *ifp1 = if_lookup_by_index(
|
||||
nh_node->ifindex, pimg->vrf_id);
|
||||
nh_node->ifindex, pim->vrf_id);
|
||||
nbr = pim_neighbor_find_if(ifp1);
|
||||
if (!nbr)
|
||||
continue;
|
||||
|
@ -38,30 +38,33 @@ void pim_rp_init(void);
|
||||
void pim_rp_free(void);
|
||||
void pim_rp_list_hash_clean(void *data);
|
||||
|
||||
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);
|
||||
int pim_rp_new(struct pim_instance *pim, const char *rp, const char *group,
|
||||
const char *plist);
|
||||
int pim_rp_del(struct pim_instance *pim, 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);
|
||||
|
||||
void pim_rp_setup(void);
|
||||
void pim_rp_setup(struct pim_instance *pim);
|
||||
|
||||
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);
|
||||
void pim_i_am_rp_re_evaluate(struct pim_instance *pim);
|
||||
|
||||
int pim_rp_check_is_my_ip_address(struct in_addr group,
|
||||
int pim_rp_check_is_my_ip_address(struct pim_instance *pim,
|
||||
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);
|
||||
|
||||
struct pim_rpf *pim_rp_g(struct in_addr group);
|
||||
struct pim_rpf *pim_rp_g(struct pim_instance *pim, struct in_addr group);
|
||||
|
||||
#define I_am_RP(G) pim_rp_i_am_rp ((G))
|
||||
#define RP(G) pim_rp_g ((G))
|
||||
#define RP(P, G) pim_rp_g ((P), (G))
|
||||
|
||||
void pim_rp_show_information(struct vty *vty, u_char uj);
|
||||
void pim_resolve_rp_nh(void);
|
||||
void pim_resolve_rp_nh(struct pim_instance *pim);
|
||||
int pim_rp_list_cmp(void *v1, void *v2);
|
||||
#endif
|
||||
|
@ -1338,7 +1338,7 @@ static int pim_upstream_register_stop_timer(struct thread *t)
|
||||
__PRETTY_FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
rpg = RP(up->sg.grp);
|
||||
rpg = RP(pimg, up->sg.grp);
|
||||
memset(&ip_hdr, 0, sizeof(struct ip));
|
||||
ip_hdr.ip_p = PIM_IP_PROTO_PIM;
|
||||
ip_hdr.ip_hl = 5;
|
||||
|
@ -307,6 +307,8 @@ static int pim_zebra_if_address_del(int command, struct zclient *client,
|
||||
{
|
||||
struct connected *c;
|
||||
struct prefix *p;
|
||||
struct vrf *vrf = vrf_lookup_by_id(vrf_id);
|
||||
struct pim_instance *pim = vrf->info;
|
||||
|
||||
/*
|
||||
zebra api notifies address adds/dels events by using the same call
|
||||
@ -339,8 +341,8 @@ static int pim_zebra_if_address_del(int command, struct zclient *client,
|
||||
}
|
||||
|
||||
pim_if_addr_del(c, 0);
|
||||
pim_rp_setup();
|
||||
pim_i_am_rp_re_evaluate();
|
||||
pim_rp_setup(pim);
|
||||
pim_i_am_rp_re_evaluate(pim);
|
||||
}
|
||||
|
||||
connected_free(c);
|
||||
|
Loading…
Reference in New Issue
Block a user