mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-03 20:55:25 +00:00
Addition on hidden command "bfd multihop/singlehop" and "ptm-enable" per interface command
CM-10435 Issue: IBGP BFD sessions are created as multi-hop even though peer is single-hop away. This is causing an interop issue with ICOS. Root Cause: By design all IBGP peers are registered with BFD as multi-hop. Fix: • Changed the default behavior of always treating IBGP BFD sessions as mult-hop. shared_network variable is used to determine whether the IBGP peer is single hop or multi-hop away. The logic for determining whether EBGP peer is single hop or multi-hop has not been changed. • Since the default behavior has been changed, it will cause interop issues between 2.5 and 3.0 IBGP BFD sessions. A new hidden command “bfd multihop/singlehop” has been introduced to overcome the interop issues. dell-s6000-10(config-router)# neighbor 30.0.2.6 bfd <2-255> Detect Multiplier <cr> dell-s6000-10(config-router)# neighbor 30.0.2.6 bfd multihop dell-s6000-10(config-router)# no neighbor 30.0.2.6 bfd multihop dell-s6000-10(config-router)# dell-s6000-10(config-router)# neighbor 30.0.2.6 bfd multihop dell-s6000-10(config-router)# do show running-config ! router bgp 100 neighbor igroup peer-group neighbor igroup bfd 5 500 500 neighbor igroup bfd multihop neighbor 30.0.2.2 remote-as 100 neighbor 30.0.2.2 peer-group igroup neighbor 3101🔤bcad::2 remote-as 100 neighbor 3101🔤bcad::2 peer-group igroup neighbor 30.0.2.6 remote-as 200 neighbor 30.0.2.6 bfd multihop neighbor 3102🔤bcad::6 remote-as 200 neighbor 3102🔤bcad::6 bfd neighbor 3102🔤bcad::6 ebgp-multihop 255 ! CM-10260 Issue: “Unable to connect to socket” message keeps getting logged when ptmd process doesn’t exist. Root Cause: BFD clients (bgpd, ospfd and ospf6d) during initialization try to register with BFD/PTM by default. This results in continuous logging If PTM does not exist since there is no max on number of retries. Fix: • Stop the retries to connect to PTM after max reconnect timer of 5 mins is reached. • Added zebra debug event wrapper to message logging to prevent it from showing by default. CM-4541 Issue: Addition of a new command "ptm-enable" or "no ptm-enable" per interface to enable/disable PTM link status checks for an interface. Fix: Currently there is only one ptm-enable global command that enables/disables PTM status updates for all interfaces. This new command will give the handle to individually stop interface from reacting on the PTM status updates. • by default interface uses the ptm-enable global configuration • "no ptm-enable" on an interface will disable PTM status updates from taking affect for that interface. This can bring the interface up if it was brought down due to PTM status update. • "ptm-enable" on an interface will cause the interface to fallback to the global ptm-enable configuration value and will bring the interface up or down based on the last stored PTM status update if global ptm is enabled. Ticket: CM-10435, CM-10260 and CM-4541 Signed-off-by: Radhika Mahankali Reviewed-by: Donald Sharp, Kanna Rajagopal
This commit is contained in:
parent
9fe88bc7ca
commit
986aa00f94
194
bgpd/bgp_bfd.c
194
bgpd/bgp_bfd.c
@ -65,6 +65,7 @@ bgp_bfd_peer_group2peer_copy(struct peer *conf, struct peer *peer)
|
||||
bfd_info->required_min_rx = conf_bfd_info->required_min_rx;
|
||||
bfd_info->desired_min_tx = conf_bfd_info->desired_min_tx;
|
||||
bfd_info->detect_mult = conf_bfd_info->detect_mult;
|
||||
bfd_info->type = conf_bfd_info->type;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -73,8 +74,16 @@ bgp_bfd_peer_group2peer_copy(struct peer *conf, struct peer *peer)
|
||||
static int
|
||||
bgp_bfd_is_peer_multihop(struct peer *peer)
|
||||
{
|
||||
if((peer->conf_if == NULL) && ((peer->sort == BGP_PEER_IBGP) ||
|
||||
is_ebgp_multihop_configured(peer)))
|
||||
struct bfd_info *bfd_info;
|
||||
|
||||
bfd_info = (struct bfd_info *)peer->bfd_info;
|
||||
|
||||
if (!bfd_info)
|
||||
return 0;
|
||||
|
||||
if((bfd_info->type == BFD_TYPE_MULTIHOP) ||
|
||||
((peer->sort == BGP_PEER_IBGP) && !peer->shared_network) ||
|
||||
is_ebgp_multihop_configured(peer))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
@ -89,24 +98,37 @@ bgp_bfd_peer_sendmsg (struct peer *peer, int command)
|
||||
{
|
||||
struct bfd_info *bfd_info;
|
||||
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||
int multihop;
|
||||
|
||||
bfd_info = (struct bfd_info *)peer->bfd_info;
|
||||
|
||||
if (peer->bgp && (peer->bgp->inst_type == BGP_INSTANCE_TYPE_VRF))
|
||||
vrf_id = peer->bgp->vrf_id;
|
||||
|
||||
if (command == ZEBRA_BFD_DEST_DEREGISTER)
|
||||
{
|
||||
multihop = CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP);
|
||||
UNSET_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP);
|
||||
}
|
||||
else
|
||||
{
|
||||
multihop = bgp_bfd_is_peer_multihop(peer);
|
||||
if ((command == ZEBRA_BFD_DEST_REGISTER) && multihop)
|
||||
SET_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP);
|
||||
}
|
||||
|
||||
if (peer->su.sa.sa_family == AF_INET)
|
||||
bfd_peer_sendmsg (zclient, bfd_info, AF_INET,
|
||||
&peer->su.sin.sin_addr,
|
||||
(peer->su_local) ? &peer->su_local->sin.sin_addr : NULL,
|
||||
(peer->nexthop.ifp) ? peer->nexthop.ifp->name : NULL,
|
||||
peer->ttl, bgp_bfd_is_peer_multihop(peer), command, 1, vrf_id);
|
||||
peer->ttl, multihop, command, 1, vrf_id);
|
||||
else if (peer->su.sa.sa_family == AF_INET6)
|
||||
bfd_peer_sendmsg (zclient, bfd_info, AF_INET6,
|
||||
&peer->su.sin6.sin6_addr,
|
||||
(peer->su_local) ? &peer->su_local->sin6.sin6_addr : NULL,
|
||||
(peer->nexthop.ifp) ? peer->nexthop.ifp->name : NULL,
|
||||
peer->ttl, bgp_bfd_is_peer_multihop(peer), command, 1, vrf_id);
|
||||
peer->ttl, multihop, command, 1, vrf_id);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -170,6 +192,46 @@ bgp_bfd_update_peer (struct peer *peer)
|
||||
bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_UPDATE);
|
||||
}
|
||||
|
||||
/*
|
||||
* bgp_bfd_update_type - update session type with BFD through zebra.
|
||||
*/
|
||||
static void
|
||||
bgp_bfd_update_type (struct peer *peer)
|
||||
{
|
||||
struct bfd_info *bfd_info;
|
||||
int multihop;
|
||||
|
||||
if (!peer->bfd_info)
|
||||
return;
|
||||
bfd_info = (struct bfd_info *)peer->bfd_info;
|
||||
|
||||
/* Check if the peer has been registered with BFD*/
|
||||
if (!CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_REG))
|
||||
return;
|
||||
|
||||
if (bfd_info->type == BFD_TYPE_NOT_CONFIGURED)
|
||||
{
|
||||
multihop = bgp_bfd_is_peer_multihop(peer);
|
||||
if ((multihop && !CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP)) ||
|
||||
(!multihop && CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP)))
|
||||
{
|
||||
bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_DEREGISTER);
|
||||
bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_REGISTER);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((bfd_info->type == BFD_TYPE_MULTIHOP &&
|
||||
!CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP)) ||
|
||||
(bfd_info->type == BFD_TYPE_SINGLEHOP &&
|
||||
CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_TYPE_MULTIHOP)))
|
||||
{
|
||||
bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_DEREGISTER);
|
||||
bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_REGISTER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* bgp_bfd_dest_replay - Replay all the peers that have BFD enabled
|
||||
* to zebra
|
||||
@ -367,7 +429,7 @@ bgp_bfd_peer_param_set (struct peer *peer, u_int32_t min_rx, u_int32_t min_tx,
|
||||
}
|
||||
|
||||
/*
|
||||
* bgp_bfd_peer_param_unset - Unset the configured BFD paramter values for peer.
|
||||
* bgp_bfd_peer_param_unset - Delete the configured BFD paramter values for peer.
|
||||
*/
|
||||
static int
|
||||
bgp_bfd_peer_param_unset (struct peer *peer)
|
||||
@ -396,6 +458,61 @@ bgp_bfd_peer_param_unset (struct peer *peer)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* bgp_bfd_peer_param_type_set - set the BFD session type (multihop or singlehop)
|
||||
*/
|
||||
static int
|
||||
bgp_bfd_peer_param_type_set (struct peer *peer, enum bfd_sess_type type)
|
||||
{
|
||||
struct peer_group *group;
|
||||
struct listnode *node, *nnode;
|
||||
int command = 0;
|
||||
struct bfd_info *bfd_info;
|
||||
|
||||
if (!peer->bfd_info)
|
||||
bfd_set_param((struct bfd_info **)&(peer->bfd_info), BFD_DEF_MIN_RX,
|
||||
BFD_DEF_MIN_TX, BFD_DEF_DETECT_MULT, 1, &command);
|
||||
|
||||
bfd_info = (struct bfd_info *)peer->bfd_info;
|
||||
bfd_info->type = type;
|
||||
|
||||
if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
|
||||
{
|
||||
group = peer->group;
|
||||
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
|
||||
{
|
||||
command = 0;
|
||||
if (!peer->bfd_info)
|
||||
bfd_set_param((struct bfd_info **)&(peer->bfd_info),
|
||||
BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
|
||||
BFD_DEF_DETECT_MULT, 1, &command);
|
||||
|
||||
bfd_info = (struct bfd_info *)peer->bfd_info;
|
||||
bfd_info->type = type;
|
||||
|
||||
if (peer->status == Established)
|
||||
{
|
||||
if (command == ZEBRA_BFD_DEST_REGISTER)
|
||||
bgp_bfd_register_peer(peer);
|
||||
else
|
||||
bgp_bfd_update_type(peer);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (peer->status == Established)
|
||||
{
|
||||
if (command == ZEBRA_BFD_DEST_REGISTER)
|
||||
bgp_bfd_register_peer(peer);
|
||||
else
|
||||
bgp_bfd_update_type(peer);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* bgp_bfd_peer_config_write - Write the peer BFD configuration.
|
||||
*/
|
||||
@ -413,7 +530,14 @@ bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr)
|
||||
vty_out (vty, " neighbor %s bfd %d %d %d%s", addr,
|
||||
bfd_info->detect_mult, bfd_info->required_min_rx,
|
||||
bfd_info->desired_min_tx, VTY_NEWLINE);
|
||||
else
|
||||
|
||||
if (bfd_info->type != BFD_TYPE_NOT_CONFIGURED)
|
||||
vty_out (vty, " neighbor %s bfd %s%s", addr,
|
||||
(bfd_info->type == BFD_TYPE_MULTIHOP) ? "multihop" : "singlehop",
|
||||
VTY_NEWLINE);
|
||||
|
||||
if (!CHECK_FLAG (bfd_info->flags, BFD_FLAG_PARAM_CFG) &&
|
||||
(bfd_info->type == BFD_TYPE_NOT_CONFIGURED))
|
||||
vty_out (vty, " neighbor %s bfd%s", addr, VTY_NEWLINE);
|
||||
}
|
||||
|
||||
@ -482,6 +606,36 @@ DEFUN (neighbor_bfd_param,
|
||||
|
||||
}
|
||||
|
||||
DEFUN_HIDDEN (neighbor_bfd_type,
|
||||
neighbor_bfd_type_cmd,
|
||||
NEIGHBOR_CMD2 "bfd " BFD_CMD_TYPE,
|
||||
NEIGHBOR_STR
|
||||
NEIGHBOR_ADDR_STR2
|
||||
"Enables BFD support\n"
|
||||
"Session type\n")
|
||||
{
|
||||
struct peer *peer;
|
||||
enum bfd_sess_type type;
|
||||
int ret;
|
||||
|
||||
peer = peer_and_group_lookup_vty (vty, argv[0]);
|
||||
if (!peer)
|
||||
return CMD_WARNING;
|
||||
|
||||
if (!strcmp(argv[1], "singlehop"))
|
||||
type = BFD_TYPE_SINGLEHOP;
|
||||
else if (!strcmp(argv[1], "multihop"))
|
||||
type = BFD_TYPE_MULTIHOP;
|
||||
else
|
||||
return CMD_WARNING;
|
||||
|
||||
ret = bgp_bfd_peer_param_type_set (peer, type);
|
||||
if (ret != 0)
|
||||
return bgp_vty_return (vty, ret);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (no_neighbor_bfd,
|
||||
no_neighbor_bfd_cmd,
|
||||
NO_NEIGHBOR_CMD2 "bfd",
|
||||
@ -515,6 +669,32 @@ ALIAS (no_neighbor_bfd,
|
||||
"Required min receive interval\n"
|
||||
"Desired min transmit interval\n")
|
||||
|
||||
DEFUN_HIDDEN (no_neighbor_bfd_type,
|
||||
no_neighbor_bfd_type_cmd,
|
||||
NO_NEIGHBOR_CMD2 "bfd " BFD_CMD_TYPE,
|
||||
NO_STR
|
||||
NEIGHBOR_STR
|
||||
NEIGHBOR_ADDR_STR2
|
||||
"Disables BFD support\n"
|
||||
"Session type\n")
|
||||
{
|
||||
struct peer *peer;
|
||||
int ret;
|
||||
|
||||
peer = peer_and_group_lookup_vty (vty, argv[0]);
|
||||
if (! peer)
|
||||
return CMD_WARNING;
|
||||
|
||||
if (!peer->bfd_info)
|
||||
return 0;
|
||||
|
||||
ret = bgp_bfd_peer_param_type_set(peer, BFD_TYPE_NOT_CONFIGURED);
|
||||
if (ret != 0)
|
||||
return bgp_vty_return (vty, ret);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
bgp_bfd_init(void)
|
||||
{
|
||||
@ -525,8 +705,10 @@ bgp_bfd_init(void)
|
||||
/* "neighbor bfd" commands. */
|
||||
install_element (BGP_NODE, &neighbor_bfd_cmd);
|
||||
install_element (BGP_NODE, &neighbor_bfd_param_cmd);
|
||||
install_element (BGP_NODE, &neighbor_bfd_type_cmd);
|
||||
install_element (BGP_NODE, &no_neighbor_bfd_cmd);
|
||||
install_element (BGP_NODE, &no_neighbor_bfd_val_cmd);
|
||||
install_element (BGP_NODE, &no_neighbor_bfd_type_cmd);
|
||||
|
||||
/* Send the client registration */
|
||||
bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER);
|
||||
|
@ -45,6 +45,7 @@ bfd_info_create(void)
|
||||
assert(bfd_info);
|
||||
|
||||
bfd_info->status = BFD_STATUS_UNKNOWN;
|
||||
bfd_info->type = BFD_TYPE_NOT_CONFIGURED;
|
||||
bfd_info->last_update = 0;
|
||||
return bfd_info;
|
||||
}
|
||||
|
21
lib/bfd.h
21
lib/bfd.h
@ -29,6 +29,7 @@
|
||||
#define BFD_CMD_DETECT_MULT_RANGE "<2-255> "
|
||||
#define BFD_CMD_MIN_RX_RANGE "<50-60000> "
|
||||
#define BFD_CMD_MIN_TX_RANGE "<50-60000>"
|
||||
#define BFD_CMD_TYPE "(multihop|singlehop)"
|
||||
|
||||
#define BFD_DEF_MIN_RX 300
|
||||
#define BFD_MIN_MIN_RX 50
|
||||
@ -42,19 +43,27 @@
|
||||
|
||||
#define BFD_FLAG_PARAM_CFG (1 << 0) /* parameters have been configured */
|
||||
#define BFD_FLAG_BFD_REG (1 << 1) /* Peer registered with BFD */
|
||||
#define BFD_FLAG_BFD_TYPE_MULTIHOP (1 << 2) /* Peer registered with BFD as multihop */
|
||||
|
||||
#define BFD_STATUS_UNKNOWN (1 << 0) /* BFD session status never received */
|
||||
#define BFD_STATUS_DOWN (1 << 1) /* BFD session status is down */
|
||||
#define BFD_STATUS_UP (1 << 2) /* BFD session status is up */
|
||||
|
||||
enum bfd_sess_type {
|
||||
BFD_TYPE_NOT_CONFIGURED,
|
||||
BFD_TYPE_SINGLEHOP,
|
||||
BFD_TYPE_MULTIHOP
|
||||
};
|
||||
|
||||
struct bfd_info
|
||||
{
|
||||
u_int16_t flags;
|
||||
u_int8_t detect_mult;
|
||||
u_int32_t desired_min_tx;
|
||||
u_int32_t required_min_rx;
|
||||
time_t last_update;
|
||||
u_int8_t status;
|
||||
u_int16_t flags;
|
||||
u_int8_t detect_mult;
|
||||
u_int32_t desired_min_tx;
|
||||
u_int32_t required_min_rx;
|
||||
time_t last_update;
|
||||
u_int8_t status;
|
||||
enum bfd_sess_type type;
|
||||
};
|
||||
|
||||
extern struct bfd_info *
|
||||
|
@ -66,6 +66,7 @@ if_zebra_new_hook (struct interface *ifp)
|
||||
|
||||
zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
|
||||
zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
|
||||
zebra_ptm_if_init(zebra_if);
|
||||
|
||||
ifp->ptm_enable = zebra_ptm_get_enable_state();
|
||||
#if defined (HAVE_RTADV)
|
||||
@ -453,6 +454,8 @@ if_add_update (struct interface *ifp)
|
||||
else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
|
||||
if_unset_flags (ifp, IFF_MULTICAST);
|
||||
|
||||
zebra_ptm_if_set_ptm_state(ifp, if_data);
|
||||
|
||||
zebra_interface_add_update (ifp);
|
||||
|
||||
if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
|
||||
@ -1842,6 +1845,7 @@ DEFUN (no_ip_address,
|
||||
return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_NETLINK
|
||||
DEFUN (ip_address_label,
|
||||
ip_address_label_cmd,
|
||||
@ -2085,6 +2089,8 @@ if_config_write (struct vty *vty)
|
||||
{
|
||||
if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
|
||||
vty_out (vty, " shutdown%s", VTY_NEWLINE);
|
||||
|
||||
zebra_ptm_if_write(vty, if_data);
|
||||
}
|
||||
|
||||
if (ifp->desc)
|
||||
|
@ -211,6 +211,9 @@ struct zebra_if
|
||||
*/
|
||||
u_char primary_state;
|
||||
#endif /* SUNOS_5 */
|
||||
|
||||
/* ptm enable configuration */
|
||||
u_char ptm_enable;
|
||||
};
|
||||
|
||||
|
||||
|
@ -227,13 +227,15 @@ zebra_ptm_connect (struct thread *t)
|
||||
}
|
||||
zebra_ptm_send_status_req();
|
||||
ptm_cb.reconnect_time = ZEBRA_PTM_RECONNECT_TIME_INITIAL;
|
||||
} else {
|
||||
} else if (ptm_cb.reconnect_time < ZEBRA_PTM_RECONNECT_TIME_MAX){
|
||||
ptm_cb.reconnect_time *= 2;
|
||||
if (ptm_cb.reconnect_time > ZEBRA_PTM_RECONNECT_TIME_MAX)
|
||||
ptm_cb.reconnect_time = ZEBRA_PTM_RECONNECT_TIME_MAX;
|
||||
|
||||
ptm_cb.t_timer = thread_add_timer (zebrad.master, zebra_ptm_connect, NULL,
|
||||
ptm_cb.reconnect_time);
|
||||
} else if (ptm_cb.reconnect_time >= ZEBRA_PTM_RECONNECT_TIME_MAX){
|
||||
ptm_cb.reconnect_time = ZEBRA_PTM_RECONNECT_TIME_INITIAL;
|
||||
}
|
||||
|
||||
return(errno);
|
||||
@ -246,17 +248,23 @@ DEFUN (zebra_ptm_enable,
|
||||
{
|
||||
struct listnode *i;
|
||||
struct interface *ifp;
|
||||
struct zebra_if *if_data;
|
||||
vrf_iter_t iter;
|
||||
|
||||
ptm_cb.ptm_enable = 1;
|
||||
ptm_cb.ptm_enable = ZEBRA_IF_PTM_ENABLE_ON;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), i, ifp))
|
||||
if (!ifp->ptm_enable)
|
||||
{
|
||||
ifp->ptm_enable = 1;
|
||||
if_data = (struct zebra_if *)ifp->info;
|
||||
if (if_data &&
|
||||
(if_data->ptm_enable == ZEBRA_IF_PTM_ENABLE_UNSPEC))
|
||||
{
|
||||
ifp->ptm_enable = ZEBRA_IF_PTM_ENABLE_ON;
|
||||
}
|
||||
/* Assign a default unknown status */
|
||||
ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN;
|
||||
ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN;
|
||||
}
|
||||
|
||||
zebra_ptm_connect(NULL);
|
||||
@ -270,11 +278,84 @@ DEFUN (no_zebra_ptm_enable,
|
||||
NO_STR
|
||||
"Enable neighbor check with specified topology\n")
|
||||
{
|
||||
ptm_cb.ptm_enable = 0;
|
||||
ptm_cb.ptm_enable = ZEBRA_IF_PTM_ENABLE_OFF;
|
||||
zebra_ptm_reset_status(1);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (zebra_ptm_enable_if,
|
||||
zebra_ptm_enable_if_cmd,
|
||||
"ptm-enable",
|
||||
"Enable neighbor check with specified topology\n")
|
||||
{
|
||||
struct interface *ifp;
|
||||
struct zebra_if *if_data;
|
||||
int old_ptm_enable;
|
||||
int send_linkdown = 0;
|
||||
|
||||
ifp = (struct interface *) vty->index;
|
||||
if (ifp->ifindex == IFINDEX_INTERNAL)
|
||||
{
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
old_ptm_enable = ifp->ptm_enable;
|
||||
ifp->ptm_enable = ptm_cb.ptm_enable;
|
||||
|
||||
if (if_is_no_ptm_operative(ifp))
|
||||
send_linkdown = 1;
|
||||
|
||||
if (!old_ptm_enable && ptm_cb.ptm_enable)
|
||||
{
|
||||
if (!if_is_operative (ifp) && send_linkdown)
|
||||
{
|
||||
if (IS_ZEBRA_DEBUG_EVENT)
|
||||
zlog_debug ("%s: Bringing down interface %s\n", __func__,
|
||||
ifp->name);
|
||||
if_down (ifp);
|
||||
}
|
||||
}
|
||||
|
||||
if_data = ifp->info;
|
||||
if_data->ptm_enable = ZEBRA_IF_PTM_ENABLE_UNSPEC;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (no_zebra_ptm_enable_if,
|
||||
no_zebra_ptm_enable_if_cmd,
|
||||
"no ptm-enable",
|
||||
NO_STR
|
||||
"Enable neighbor check with specified topology\n")
|
||||
{
|
||||
struct interface *ifp;
|
||||
int send_linkup = 0;
|
||||
struct zebra_if *if_data;
|
||||
|
||||
ifp = (struct interface *) vty->index;
|
||||
|
||||
if ((ifp->ifindex != IFINDEX_INTERNAL) && (ifp->ptm_enable))
|
||||
{
|
||||
if (!if_is_operative(ifp))
|
||||
send_linkup = 1;
|
||||
|
||||
ifp->ptm_enable = ZEBRA_IF_PTM_ENABLE_OFF;
|
||||
if (if_is_no_ptm_operative (ifp) && send_linkup)
|
||||
{
|
||||
if (IS_ZEBRA_DEBUG_EVENT)
|
||||
zlog_debug ("%s: Bringing up interface %s\n", __func__,
|
||||
ifp->name);
|
||||
if_up (ifp);
|
||||
}
|
||||
}
|
||||
|
||||
if_data = ifp->info;
|
||||
if_data->ptm_enable = ZEBRA_IF_PTM_ENABLE_OFF;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
zebra_ptm_write (struct vty *vty)
|
||||
{
|
||||
@ -307,7 +388,8 @@ zebra_ptm_socket_init (void)
|
||||
sizeof (addr.sun_family)+sizeof (ZEBRA_PTM_SOCK_NAME)-1);
|
||||
if (ret < 0)
|
||||
{
|
||||
zlog_warn("%s: Unable to connect to socket %s [%s]",
|
||||
if (IS_ZEBRA_DEBUG_EVENT)
|
||||
zlog_debug("%s: Unable to connect to socket %s [%s]",
|
||||
__func__, ZEBRA_PTM_SOCK_NAME, safe_strerror(errno));
|
||||
close (sock);
|
||||
return -1;
|
||||
@ -321,6 +403,8 @@ zebra_ptm_install_commands (void)
|
||||
{
|
||||
install_element (CONFIG_NODE, &zebra_ptm_enable_cmd);
|
||||
install_element (CONFIG_NODE, &no_zebra_ptm_enable_cmd);
|
||||
install_element (INTERFACE_NODE, &zebra_ptm_enable_if_cmd);
|
||||
install_element (INTERFACE_NODE, &no_zebra_ptm_enable_if_cmd);
|
||||
}
|
||||
|
||||
/* BFD session goes down, send message to the protocols. */
|
||||
@ -981,21 +1065,41 @@ zebra_ptm_reset_status(int ptm_disable)
|
||||
{
|
||||
send_linkup = 0;
|
||||
if (ifp->ptm_enable)
|
||||
{
|
||||
if (!if_is_operative(ifp))
|
||||
send_linkup = 1;
|
||||
{
|
||||
if (!if_is_operative(ifp))
|
||||
send_linkup = 1;
|
||||
|
||||
if (ptm_disable)
|
||||
ifp->ptm_enable = 0;
|
||||
ifp->ptm_enable = ZEBRA_IF_PTM_ENABLE_OFF;
|
||||
ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN;
|
||||
|
||||
if (if_is_operative (ifp) && send_linkup)
|
||||
{
|
||||
if (IS_ZEBRA_DEBUG_EVENT)
|
||||
zlog_debug ("%s: Bringing up interface %s", __func__,
|
||||
ifp->name);
|
||||
if_up (ifp);
|
||||
if (if_is_operative (ifp) && send_linkup)
|
||||
{
|
||||
if (IS_ZEBRA_DEBUG_EVENT)
|
||||
zlog_debug ("%s: Bringing up interface %s", __func__,
|
||||
ifp->name);
|
||||
if_up (ifp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
zebra_ptm_if_init(struct zebra_if *zebra_ifp)
|
||||
{
|
||||
zebra_ifp->ptm_enable = ZEBRA_IF_PTM_ENABLE_UNSPEC;
|
||||
}
|
||||
|
||||
void
|
||||
zebra_ptm_if_set_ptm_state(struct interface *ifp, struct zebra_if *zebra_ifp)
|
||||
{
|
||||
if (zebra_ifp && zebra_ifp->ptm_enable != ZEBRA_IF_PTM_ENABLE_UNSPEC)
|
||||
ifp->ptm_enable = zebra_ifp->ptm_enable;
|
||||
}
|
||||
|
||||
void
|
||||
zebra_ptm_if_write (struct vty *vty, struct zebra_if *zebra_ifp)
|
||||
{
|
||||
if (zebra_ifp->ptm_enable == ZEBRA_IF_PTM_ENABLE_OFF)
|
||||
vty_out (vty, " no ptm-enable%s", VTY_NEWLINE);
|
||||
}
|
||||
|
@ -50,6 +50,11 @@ struct zebra_ptm_cb
|
||||
#define ZEBRA_PTM_STATUS_UP 1
|
||||
#define ZEBRA_PTM_STATUS_UNKNOWN 2
|
||||
|
||||
/* For interface ptm-enable configuration. */
|
||||
#define ZEBRA_IF_PTM_ENABLE_OFF 0
|
||||
#define ZEBRA_IF_PTM_ENABLE_ON 1
|
||||
#define ZEBRA_IF_PTM_ENABLE_UNSPEC 2
|
||||
|
||||
void zebra_ptm_init (void);
|
||||
void zebra_ptm_finish(void);
|
||||
int zebra_ptm_connect (struct thread *t);
|
||||
@ -64,4 +69,7 @@ void
|
||||
zebra_ptm_show_status(struct vty *vty, struct interface *ifp);
|
||||
int zebra_ptm_bfd_client_register (struct zserv *client, int sock,
|
||||
u_short length);
|
||||
void zebra_ptm_if_init(struct zebra_if *zebra_ifp);
|
||||
void zebra_ptm_if_set_ptm_state(struct interface *ifp, struct zebra_if *zebra_ifp);
|
||||
void zebra_ptm_if_write (struct vty *vty, struct zebra_if *zebra_ifp);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user