mirror of
https://github.com/pfsense/pfsense.git
synced 2025-10-26 11:38:35 +00:00
Make vips vhid be unique per parent interface!
This commit is contained in:
parent
da664d195d
commit
4d0c032c52
@ -16,14 +16,14 @@ options {
|
||||
notify 100 {
|
||||
match "system" "IFNET";
|
||||
match "type" "LINK_UP";
|
||||
match "subsystem" "vip";
|
||||
match "subsystem" "_vip";
|
||||
action "/etc/rc.carpmaster $subsystem";
|
||||
};
|
||||
|
||||
notify 100 {
|
||||
match "system" "IFNET";
|
||||
match "type" "LINK_DOWN";
|
||||
match "subsystem" "vip";
|
||||
match "subsystem" "_vip";
|
||||
action "/etc/rc.carpbackup $subsystem";
|
||||
};
|
||||
|
||||
|
||||
@ -98,7 +98,7 @@ function does_vip_exist($vip) {
|
||||
switch ($vip['mode']) {
|
||||
case "carp":
|
||||
case "carpdev":
|
||||
$realif = "vip{$vip['vhid']}";
|
||||
$realif = "{$vip['interface']}_vip{$vip['vhid']}";
|
||||
if (!does_interface_exist($realif)) {
|
||||
return false;
|
||||
}
|
||||
@ -743,9 +743,9 @@ function interfaces_gre_configure($checkparent = 0) {
|
||||
foreach ($config['gres']['gre'] as $i => $gre) {
|
||||
if(empty($gre['greif']))
|
||||
$gre['greif'] = "gre{$i}";
|
||||
if ($checkparent == 1 && strstr($gre['if'], "vip"))
|
||||
if ($checkparent == 1 && strstr($gre['if'], "_vip"))
|
||||
continue;
|
||||
if ($checkparent == 2 && !strstr($gre['if'], "vip"))
|
||||
if ($checkparent == 2 && !strstr($gre['if'], "_vip"))
|
||||
continue;
|
||||
/* XXX: Maybe we should report any errors?! */
|
||||
interface_gre_configure($gre);
|
||||
@ -802,9 +802,9 @@ function interfaces_gif_configure($checkparent = 0) {
|
||||
foreach ($config['gifs']['gif'] as $i => $gif) {
|
||||
if(empty($gif['gifif']))
|
||||
$gre['gifif'] = "gif{$i}";
|
||||
if ($checkparent == 1 && strstr($gif['if'], "vip"))
|
||||
if ($checkparent == 1 && strstr($gif['if'], "_vip"))
|
||||
continue;
|
||||
if ($checkparent == 2 && !strstr($gif['if'], "vip"))
|
||||
if ($checkparent == 2 && !strstr($gif['if'], "_vip"))
|
||||
continue;
|
||||
/* XXX: Maybe we should report any errors?! */
|
||||
interface_gif_configure($gif);
|
||||
@ -996,13 +996,9 @@ function interface_vip_bring_down($vip) {
|
||||
pfSense_interface_deladdress($vipif, $vip['subnet']);
|
||||
break;
|
||||
case "carp":
|
||||
$vipif = "vip" . $vip['vhid'];
|
||||
if(does_interface_exist($vipif))
|
||||
pfSense_interface_destroy($vipif);
|
||||
break;
|
||||
case "carpdev-dhcp":
|
||||
$vipif = "vip" . $vip['vhid'];
|
||||
if(does_interface_exist($vipif))
|
||||
$vipif = "{$vip['interface']}_vip{$vip['vhid']}";
|
||||
if (does_interface_exist($vipif))
|
||||
pfSense_interface_destroy($vipif);
|
||||
break;
|
||||
}
|
||||
@ -1881,14 +1877,6 @@ function interface_carp_configure(&$vip) {
|
||||
if ($vip['mode'] != "carp")
|
||||
return;
|
||||
|
||||
$vip_password = $vip['password'];
|
||||
$vip_password = escapeshellarg(addslashes(str_replace(" ", "", $vip_password)));
|
||||
if ($vip['password'] != "")
|
||||
$password = " pass {$vip_password}";
|
||||
|
||||
// set the vip interface to the vhid
|
||||
$vipif = "vip{$vip['vhid']}";
|
||||
|
||||
/*
|
||||
* ensure the interface containing the VIP really exists
|
||||
* prevents a panic if the interface is missing or invalid
|
||||
@ -1899,6 +1887,9 @@ function interface_carp_configure(&$vip) {
|
||||
return;
|
||||
}
|
||||
|
||||
// set the vip interface to the vhid
|
||||
$vipif = "{$vip['interface']}_vip{$vip['vhid']}";
|
||||
|
||||
/* Ensure CARP IP really exists prior to loading up. */
|
||||
$ww_subnet_ip = find_interface_ip($realif);
|
||||
$ww_subnet_bits = find_interface_subnet($realif);
|
||||
@ -1919,14 +1910,20 @@ function interface_carp_configure(&$vip) {
|
||||
/* invalidate interface cache */
|
||||
get_interface_arr(true);
|
||||
|
||||
$vip_password = $vip['password'];
|
||||
$vip_password = escapeshellarg(addslashes(str_replace(" ", "", $vip_password)));
|
||||
if ($vip['password'] != "")
|
||||
$password = " pass {$vip_password}";
|
||||
|
||||
$broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']);
|
||||
$advbase = "";
|
||||
if (!empty($vip['advbase']))
|
||||
$advbase = "advbase {$vip['advbase']}";
|
||||
|
||||
mwexec("/sbin/ifconfig {$vipif} {$vip['subnet']}/{$vip['subnet_bits']} vhid {$vip['vhid']} advskew {$vip['advskew']} {$advbase} {$password}");
|
||||
|
||||
interfaces_bring_up($vipif);
|
||||
|
||||
|
||||
return $vipif;
|
||||
}
|
||||
|
||||
@ -1936,17 +1933,12 @@ function interface_carpdev_configure(&$vip) {
|
||||
if ($vip['mode'] != "carpdev-dhcp")
|
||||
return;
|
||||
|
||||
$vip_password = $vip['password'];
|
||||
$vip_password = str_replace(" ", "", $vip_password);
|
||||
if($vip['password'] != "")
|
||||
$password = " pass \"" . $vip_password . "\"";
|
||||
|
||||
if (empty($vip['interface']))
|
||||
return;
|
||||
|
||||
$vipif = "vip" . $vip['vhid'];
|
||||
$realif = get_real_interface($vip['interface']);
|
||||
interfaces_bring_up($realif);
|
||||
|
||||
/*
|
||||
* ensure the interface containing the VIP really exists
|
||||
* prevents a panic if the interface is missing or invalid
|
||||
@ -1956,6 +1948,7 @@ function interface_carpdev_configure(&$vip) {
|
||||
return;
|
||||
}
|
||||
|
||||
$vipif = "{$vip['interface']}_vip{$vip['vhid']}";
|
||||
if (does_interface_exist($vipif)) {
|
||||
interface_bring_down($vipif);
|
||||
} else {
|
||||
@ -1964,6 +1957,12 @@ function interface_carpdev_configure(&$vip) {
|
||||
pfSense_ngctl_name("{$carpdevif}:", $vipif);
|
||||
}
|
||||
|
||||
$vip_password = $vip['password'];
|
||||
$vip_password = str_replace(" ", "", $vip_password);
|
||||
if ($vip['password'] != "")
|
||||
$password = " pass \"" . $vip_password . "\"";
|
||||
|
||||
|
||||
mwexec("/sbin/ifconfig {$vipif} carpdev {$realif} vhid {$vip['vhid']} advskew {$vip['advskew']} advbase {$vip['advbase']} {$password}");
|
||||
interfaces_bring_up($vipif);
|
||||
|
||||
@ -2925,11 +2924,10 @@ function get_current_wan_address($interface = "wan") {
|
||||
function convert_real_interface_to_friendly_interface_name($interface = "wan") {
|
||||
global $config;
|
||||
|
||||
if (stristr($interface, "vip")) {
|
||||
$index = intval(substr($interface, 3));
|
||||
if (stristr($interface, "_vip")) {
|
||||
foreach ($config['virtualip']['vip'] as $counter => $vip) {
|
||||
if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp") {
|
||||
if ($index == $vip['vhid'])
|
||||
if ($interface == "{$vip['interface']}_vip{$vip['vhid']}")
|
||||
return $vip['interface'];
|
||||
}
|
||||
}
|
||||
@ -2985,11 +2983,11 @@ function convert_friendly_interface_to_friendly_descr($interface) {
|
||||
else
|
||||
$ifdesc = strtoupper($config['interfaces'][$interface]['descr']);
|
||||
break;
|
||||
} else if (substr($interface, 0, 3) == "vip") {
|
||||
} else if (stristr($interface, "_vip")) {
|
||||
if (is_array($config['virtualip']['vip'])) {
|
||||
foreach ($config['virtualip']['vip'] as $counter => $vip) {
|
||||
if ($vip['mode'] == "carpdev-dhcp" || $vip['mode'] == "carp") {
|
||||
if ($interface == "vip{$vip['vhid']}")
|
||||
if ($interface == "{$vip['interface']}_vip{$vip['vhid']}")
|
||||
return "{$vip['subnet']} - {$vip['descr']}";
|
||||
}
|
||||
}
|
||||
@ -2998,8 +2996,8 @@ function convert_friendly_interface_to_friendly_descr($interface) {
|
||||
/* if list */
|
||||
$ifdescrs = get_configured_interface_with_descr(false, true);
|
||||
foreach ($ifdescrs as $if => $ifname) {
|
||||
if ($if == $interface || $ifname == $interface)
|
||||
return $ifname;
|
||||
if ($if == $interface || $ifname == $interface)
|
||||
return $ifname;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -3302,8 +3300,9 @@ function link_ip_to_carp_interface($ip) {
|
||||
$carp_ip = $vip['subnet'];
|
||||
$carp_sn = $vip['subnet_bits'];
|
||||
$carp_nw = gen_subnet($carp_ip, $carp_sn);
|
||||
if (ip_in_subnet($ip, "{$carp_nw}/{$carp_sn}"))
|
||||
$carp_int[] = "vip{$vip['vhid']}";
|
||||
if (ip_in_subnet($ip, "{$carp_nw}/{$carp_sn}")) {
|
||||
$carp_int[] = "{$vip['interface']}_vip{$vip['vhid']}";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($carp_int))
|
||||
@ -3337,14 +3336,9 @@ function link_interface_to_vips($int, $action = "") {
|
||||
if (is_array($config['virtualip']['vip'])) {
|
||||
foreach ($config['virtualip']['vip'] as $vip) {
|
||||
if ($int == $vip['interface']) {
|
||||
if ($action == "update") {
|
||||
if ($vip['mode'] == "carp" && !does_interface_exist("vip{$vip['vhid']}"))
|
||||
interfaces_vips_configure($int);
|
||||
else {
|
||||
interface_vip_bring_down($vip);
|
||||
interfaces_vips_configure($int);
|
||||
}
|
||||
} else
|
||||
if ($action == "update")
|
||||
interfaces_vips_configure($int);
|
||||
else
|
||||
return $vip;
|
||||
}
|
||||
}
|
||||
|
||||
@ -626,7 +626,7 @@ function openvpn_restart($mode, $settings) {
|
||||
return;
|
||||
|
||||
/* Do not start if we are a CARP backup on this vip! */
|
||||
if ((substr($settings['interface'], 0, 3) == "vip") && (get_carp_interface_status($settings['interface']) == "BACKUP"))
|
||||
if ((strstr($settings['interface'], "_vip") && (get_carp_interface_status($settings['interface']) == "BACKUP"))
|
||||
return;
|
||||
|
||||
/* start the new process */
|
||||
@ -1025,4 +1025,4 @@ function openvpn_refresh_crls() {
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
?>
|
||||
|
||||
@ -2639,4 +2639,20 @@ function upgrade_079_to_080() {
|
||||
}
|
||||
}
|
||||
|
||||
function upgrade_080_to_081() {
|
||||
global $config, $g;
|
||||
|
||||
/* XXX: Gross hacks in sight */
|
||||
write_config();
|
||||
if (is_array($config['virtualips']['vip'])) {
|
||||
$vipchg = array();
|
||||
foreach ($config['virtualips']['vip'] as $vip) {
|
||||
$realif = get_real_interface($vip['interface']);
|
||||
file_put_contents("{$g['tmp_path']}/vipreplace", "s/vip{$vip['vhid']}/{$realif}_vip{$vip['vhid']}/g\n");
|
||||
}
|
||||
mwexec("/bin/sh -I \"\" -f {$g['tmp_path']}/vipreplace /conf/config.xml");
|
||||
@unlink("{$g['tmp_path']}/config.cache");
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@ -542,11 +542,11 @@ function get_configured_carp_interface_list() {
|
||||
$viparr = &$config['virtualip']['vip'];
|
||||
foreach ($viparr as $vip) {
|
||||
switch ($vip['mode']) {
|
||||
case "carp":
|
||||
case "carpdev-dhcp":
|
||||
$vipif = "vip" . $vip['vhid'];
|
||||
$iflist[$vipif] = $vip['subnet'];
|
||||
break;
|
||||
case "carp":
|
||||
case "carpdev-dhcp":
|
||||
$vipif = "{$vip['interface']}_vip{$vip['vhid']}";
|
||||
$iflist[$vipif] = $vip['subnet'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ function backup_vip_config_section() {
|
||||
$temp = array();
|
||||
$temp['vip'] = array();
|
||||
foreach($config['virtualip']['vip'] as $section) {
|
||||
if(($section['mode'] == "proxyarp" || $section['mode'] == "ipalias") && substr($section['interface'],0,3) != "vip")
|
||||
if(($section['mode'] == "proxyarp" || $section['mode'] == "ipalias") && !strstr($section['interface'], "_vip")
|
||||
continue;
|
||||
if($section['advskew'] <> "") {
|
||||
$section_val = intval($section['advskew']);
|
||||
|
||||
@ -84,7 +84,7 @@ if($_POST['disablecarp'] <> "") {
|
||||
sleep(1);
|
||||
break;
|
||||
case "ipalias":
|
||||
if (substr($vip['interface'], 0, 3) == "vip")
|
||||
if (strstr($vip['interface'], "_vip"))
|
||||
interface_ipalias_configure($vip);
|
||||
break;
|
||||
}
|
||||
@ -159,7 +159,7 @@ include("head.inc");
|
||||
$vhid = $carp['vhid'];
|
||||
$advskew = $carp['advskew'];
|
||||
$advbase = $carp['advbase'];
|
||||
$carp_int = "vip{$vhid}";
|
||||
$carp_int = "{$carp['interface']}_vip{$vhid}";
|
||||
$status = get_carp_interface_status($carp_int);
|
||||
echo "<tr>";
|
||||
$align = "valign='middle'";
|
||||
|
||||
@ -118,7 +118,7 @@ if ($_GET['act'] == "del") {
|
||||
$input_errors[] = gettext("This entry cannot be deleted because it is still referenced by CARP") . " {$vip['descr']}.";
|
||||
}
|
||||
} else if ($a_vip[$_GET['id']]['mode'] == "carp") {
|
||||
$vipiface = "vip{$a_vip[$_GET['id']]['vhid']}";
|
||||
$vipiface = "{$a_vip[$_GET['id']]['interface']}_vip{$a_vip[$_GET['id']]['vhid']}";
|
||||
foreach ($a_vip as $vip) {
|
||||
if ($vipiface == $vip['interface'] && $vip['mode'] == "ipalias")
|
||||
$input_errors[] = gettext("This entry cannot be deleted because it is still referenced by ip alias entry") . " {$vip['descr']}.";
|
||||
|
||||
@ -141,11 +141,11 @@ if ($_POST) {
|
||||
/* verify against reusage of vhids */
|
||||
$idtracker = 0;
|
||||
foreach($config['virtualip']['vip'] as $vip) {
|
||||
if($vip['vhid'] == $_POST['vhid'] and $idtracker <> $id)
|
||||
$input_errors[] = sprintf(gettext("VHID %s is already in use. Pick a unique number."),$_POST['vhid']);
|
||||
if($vip['vhid'] == $_POST['vhid'] && $vip['interface'] == $_POST['interface'] && $idtracker <> $id)
|
||||
$input_errors[] = sprintf(gettext("VHID %s is already in use on interface %s. Pick a unique number on this interface."),$_POST['vhid'], convert_friendly_interface_to_friendly_descr($_POST['interface']));
|
||||
$idtracker++;
|
||||
}
|
||||
if($_POST['password'] == "")
|
||||
if (empty($_POST['password']))
|
||||
$input_errors[] = gettext("You must specify a CARP password that is shared between the two VHID members.");
|
||||
|
||||
$parent_ip = get_interface_ip($_POST['interface']);
|
||||
@ -154,11 +154,11 @@ if ($_POST) {
|
||||
$cannot_find = $_POST['subnet'] . "/" . $_POST['subnet_bits'] ;
|
||||
$input_errors[] = sprintf(gettext("Sorry, we could not locate an interface with a matching subnet for %s. Please add an IP alias in this subnet on this interface."),$cannot_find);
|
||||
}
|
||||
if (substr($_POST['interface'], 0, 3) == "vip")
|
||||
if (strstr($_POST['interface'], "_vip"))
|
||||
$input_errors[] = gettext("For this type of vip a carp parent is not allowed.");
|
||||
break;
|
||||
case "ipalias":
|
||||
if (substr($_POST['interface'], 0, 3) == "vip") {
|
||||
if (strstr($_POST['interface'], "_vip")) {
|
||||
$parent_ip = get_interface_ip($_POST['interface']);
|
||||
$parent_sn = get_interface_subnet($_POST['interface']);
|
||||
if (!ip_in_subnet($_POST['subnet'], gen_subnet($parent_ip, $parent_sn) . "/" . $parent_sn) && !ip_in_interface_alias_subnet($_POST['interface'], $_POST['subnet'])) {
|
||||
@ -168,28 +168,12 @@ if ($_POST) {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (substr($_POST['interface'], 0, 3) == "vip")
|
||||
if (strstr($_POST['interface'], "_vip"))
|
||||
$input_errors[] = gettext("For this type of VIP, a CARP parent is not allowed.");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* XXX: Seems this code is to draconian and without a real usefulness. Leaving commented out for now and remove later on */
|
||||
if (0 && isset($id) && ($a_vip[$id])) {
|
||||
if ($a_vip[$id]['mode'] != $_POST['mode']) {
|
||||
$bringdown = false;
|
||||
if ($a_vip[$id]['mode'] == "proxyarp") {
|
||||
$vipiface = $a_vip[$id]['interface'];
|
||||
foreach ($a_vip as $vip) {
|
||||
if ($vip['interface'] == $vipiface && $vip['mode'] == "carp") {
|
||||
if (ip_in_subnet($vip['subnet'], gen_subnet($a_vip[$id]['subnet'], $a_vip[$id]['subnet_bits']) . "/" . $a_vip[$id]['subnet_bits']))
|
||||
$input_errors[] = gettext("This entry cannot be modified because it is still referenced by CARP") . " {$vip['descr']}.";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$input_errors) {
|
||||
$vipent = array();
|
||||
|
||||
|
||||
@ -49,7 +49,7 @@ $carp_enabled = get_carp_status();
|
||||
$netmask = $carp['subnet_bits'];
|
||||
$vhid = $carp['vhid'];
|
||||
$advskew = $carp['advskew'];
|
||||
$carp_int = "vip{$vhid}";
|
||||
$carp_int = "{$carp['interface']}_vip{$vhid}";
|
||||
$status = get_carp_interface_status($carp_int);
|
||||
?>
|
||||
<tr>
|
||||
|
||||
@ -186,13 +186,13 @@ function restore_config_section_xmlrpc($raw_params) {
|
||||
$vipbackup = array();
|
||||
$oldvips = array();
|
||||
if (isset($params[0]['virtualip'])) {
|
||||
if(is_array($config['virtualip']['vip'])) {
|
||||
if (is_array($config['virtualip']['vip'])) {
|
||||
foreach ($config['virtualip']['vip'] as $vipindex => $vip) {
|
||||
if ($vip['mode'] == "carp")
|
||||
$oldvips[$vip['vhid']] = "{$vip['password']}{$vip['advskew']}{$vip['subnet']}{$vip['subnet_bits']}{$vip['advbase']}";
|
||||
else if ($vip['mode'] == "ipalias" && substr($vip['interface'], 0, 3) == "vip")
|
||||
$oldvips["{$vip['interface']}_vip{$vip['vhid']}"] = "{$vip['password']}{$vip['advskew']}{$vip['subnet']}{$vip['subnet_bits']}{$vip['advbase']}";
|
||||
else if ($vip['mode'] == "ipalias" && strstr($vip['interface'], "_vip"))
|
||||
$oldvips[$vip['subnet']] = "{$vip['interface']}{$vip['subnet']}{$vip['subnet_bits']}";
|
||||
else if (($vip['mode'] == "ipalias" || $vip['mode'] == 'proxyarp') && substr($vip['interface'], 0, 3) != "vip")
|
||||
else if (($vip['mode'] == "ipalias" || $vip['mode'] == 'proxyarp') && !strstr($vip['interface'], "_vip"))
|
||||
$vipbackup[] = $vip;
|
||||
}
|
||||
}
|
||||
@ -223,15 +223,15 @@ function restore_config_section_xmlrpc($raw_params) {
|
||||
$carp_setuped = false;
|
||||
$anyproxyarp = false;
|
||||
foreach ($config['virtualip']['vip'] as $vip) {
|
||||
if ($vip['mode'] == "carp" && isset($oldvips[$vip['vhid']])) {
|
||||
if ($oldvips[$vip['vhid']] == "{$vip['password']}{$vip['advskew']}{$vip['subnet']}{$vip['subnet_bits']}{$vip['advbase']}") {
|
||||
if ($vip['mode'] == "carp" && isset($oldvips["{$vip['interface']}_vip{$vip['vhid']}"])) {
|
||||
if ($oldvips["{$vip['interface']}_vip{$vip['vhid']}"] == "{$vip['password']}{$vip['advskew']}{$vip['subnet']}{$vip['subnet_bits']}{$vip['advbase']}") {
|
||||
if (does_vip_exist($vip)) {
|
||||
unset($oldvips[$vip['vhid']]);
|
||||
unset($oldvips["{$vip['interface']}_vip{$vip['vhid']}"]);
|
||||
continue; // Skip reconfiguring this vips since nothing has changed.
|
||||
}
|
||||
}
|
||||
unset($oldvips[$vip['vhid']]);
|
||||
} else if ($vip['mode'] == "ipalias" && substr($vip['interface'], 0, 3) == "vip" && isset($oldvips[$vip['subnet']])) {
|
||||
unset($oldvips["{$vip['interface']}_vip{$vip['vhid']}"]);
|
||||
} else if ($vip['mode'] == "ipalias" && strstr($vip['interface'], "_vip") && isset($oldvips[$vip['subnet']])) {
|
||||
if ($oldvips[$vip['subnet']] = "{$vip['interface']}{$vip['subnet']}{$vip['subnet_bits']}") {
|
||||
if (does_vip_exist($vip)) {
|
||||
unset($oldvips[$vip['subnet']]);
|
||||
@ -260,8 +260,8 @@ function restore_config_section_xmlrpc($raw_params) {
|
||||
}
|
||||
/* Cleanup remaining old carps */
|
||||
foreach ($oldvips as $oldvipif => $oldvippar) {
|
||||
if (!is_ipaddr($oldvipif) && does_interface_exist("vip{$oldvipif}"))
|
||||
pfSense_interface_destroy("vip{$oldvipif}");
|
||||
if (!is_ipaddr($oldvipif) && does_interface_exist($oldvipif))
|
||||
pfSense_interface_destroy($oldvipif);
|
||||
}
|
||||
if ($carp_setuped == true)
|
||||
interfaces_carp_setup();
|
||||
@ -518,4 +518,4 @@ unlock($xmlrpclockkey);
|
||||
return $a1;
|
||||
}
|
||||
|
||||
?>
|
||||
?>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user