mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-12-31 22:30:14 +00:00
zebra: Fix lsp add/del from kernel using SETFLAG
Setup a interface such that the add/del of lsp's from the kernel can have a callback for success/failure. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
0c555cc6a5
commit
4a83e7a04a
20
zebra/rt.h
20
zebra/rt.h
@ -77,9 +77,23 @@ extern int kernel_address_delete_ipv4(struct interface *, struct connected *);
|
||||
extern int kernel_neigh_update(int, int, uint32_t, char *, int);
|
||||
extern int kernel_interface_set_master(struct interface *master,
|
||||
struct interface *slave);
|
||||
extern int kernel_add_lsp(zebra_lsp_t *);
|
||||
extern int kernel_upd_lsp(zebra_lsp_t *);
|
||||
extern int kernel_del_lsp(zebra_lsp_t *);
|
||||
|
||||
extern void kernel_add_lsp(zebra_lsp_t *lsp);
|
||||
extern void kernel_upd_lsp(zebra_lsp_t *lsp);
|
||||
extern void kernel_del_lsp(zebra_lsp_t *lsp);
|
||||
|
||||
/*
|
||||
* Add the ability to pass back up the lsp install/delete
|
||||
* success/failure.
|
||||
*
|
||||
* This functions goal is similiar to kernel_route_rib_pass_fail
|
||||
* in that we are separating out the mechanics for
|
||||
* the install/failure to set/unset flags and to notify
|
||||
* as needed.
|
||||
*/
|
||||
extern void kernel_lsp_pass_fail(zebra_lsp_t *lsp,
|
||||
enum southbound_results res);
|
||||
|
||||
extern int mpls_kernel_init(void);
|
||||
|
||||
extern int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *mroute);
|
||||
|
||||
@ -2432,17 +2432,6 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
|
||||
_netlink_mpls_build_singlepath(routedesc, nhlfe,
|
||||
&req.n, &req.r,
|
||||
sizeof req, cmd);
|
||||
if (cmd == RTM_NEWROUTE) {
|
||||
SET_FLAG(nhlfe->flags,
|
||||
NHLFE_FLAG_INSTALLED);
|
||||
SET_FLAG(nexthop->flags,
|
||||
NEXTHOP_FLAG_FIB);
|
||||
} else {
|
||||
UNSET_FLAG(nhlfe->flags,
|
||||
NHLFE_FLAG_INSTALLED);
|
||||
UNSET_FLAG(nexthop->flags,
|
||||
NEXTHOP_FLAG_FIB);
|
||||
}
|
||||
nexthop_num++;
|
||||
break;
|
||||
}
|
||||
@ -2486,18 +2475,6 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
|
||||
rta, rtnh, &req.r,
|
||||
&src1);
|
||||
rtnh = RTNH_NEXT(rtnh);
|
||||
|
||||
if (cmd == RTM_NEWROUTE) {
|
||||
SET_FLAG(nhlfe->flags,
|
||||
NHLFE_FLAG_INSTALLED);
|
||||
SET_FLAG(nexthop->flags,
|
||||
NEXTHOP_FLAG_FIB);
|
||||
} else {
|
||||
UNSET_FLAG(nhlfe->flags,
|
||||
NHLFE_FLAG_INSTALLED);
|
||||
UNSET_FLAG(nexthop->flags,
|
||||
NEXTHOP_FLAG_FIB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -394,7 +394,7 @@ void kernel_route_rib(struct prefix *p, struct prefix *src_p,
|
||||
|
||||
if (src_p && src_p->prefixlen) {
|
||||
zlog_err("route add: IPv6 sourcedest routes unsupported!");
|
||||
return 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (zserv_privs.change(ZPRIVS_RAISE))
|
||||
@ -413,7 +413,7 @@ void kernel_route_rib(struct prefix *p, struct prefix *src_p,
|
||||
kernel_route_rib_pass_fail(p, new,
|
||||
(!route) ?
|
||||
SOUTHBOUND_INSTALL_SUCCESS :
|
||||
SOUTBHOUND_INSTALL_FAILURE);
|
||||
SOUTHBOUND_INSTALL_FAILURE);
|
||||
} else {
|
||||
kernel_route_rib_pass_fail(p, old,
|
||||
(!route) ?
|
||||
|
||||
@ -839,18 +839,11 @@ static void lsp_select_best_nhlfe(zebra_lsp_t *lsp)
|
||||
*/
|
||||
static void lsp_uninstall_from_kernel(struct hash_backet *backet, void *ctxt)
|
||||
{
|
||||
int ret;
|
||||
zebra_lsp_t *lsp;
|
||||
|
||||
lsp = (zebra_lsp_t *)backet->data;
|
||||
if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) {
|
||||
ret = kernel_del_lsp(lsp);
|
||||
|
||||
if (!ret) {
|
||||
UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
|
||||
clear_nhlfe_installed(lsp);
|
||||
}
|
||||
}
|
||||
if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED))
|
||||
kernel_del_lsp(lsp);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -871,7 +864,6 @@ static void lsp_schedule(struct hash_backet *backet, void *ctxt)
|
||||
*/
|
||||
static wq_item_status lsp_process(struct work_queue *wq, void *data)
|
||||
{
|
||||
int ret = 1;
|
||||
zebra_lsp_t *lsp;
|
||||
zebra_nhlfe_t *oldbest, *newbest;
|
||||
char buf[BUFSIZ], buf2[BUFSIZ];
|
||||
@ -905,12 +897,7 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data)
|
||||
if (newbest) {
|
||||
|
||||
UNSET_FLAG(lsp->flags, LSP_FLAG_CHANGED);
|
||||
ret = kernel_add_lsp(lsp);
|
||||
|
||||
if (!ret)
|
||||
SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
|
||||
else
|
||||
clear_nhlfe_installed(lsp);
|
||||
kernel_add_lsp(lsp);
|
||||
|
||||
zvrf->lsp_installs++;
|
||||
}
|
||||
@ -918,12 +905,7 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data)
|
||||
/* Installed, may need an update and/or delete. */
|
||||
if (!newbest) {
|
||||
|
||||
ret = kernel_del_lsp(lsp);
|
||||
|
||||
if (!ret) {
|
||||
UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
|
||||
clear_nhlfe_installed(lsp);
|
||||
}
|
||||
kernel_del_lsp(lsp);
|
||||
|
||||
zvrf->lsp_removals++;
|
||||
} else if (CHECK_FLAG(lsp->flags, LSP_FLAG_CHANGED)) {
|
||||
@ -931,12 +913,7 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data)
|
||||
UNSET_FLAG(lsp->flags, LSP_FLAG_CHANGED);
|
||||
UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
|
||||
|
||||
ret = kernel_upd_lsp(lsp);
|
||||
|
||||
if (!ret)
|
||||
SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
|
||||
else
|
||||
clear_nhlfe_installed(lsp);
|
||||
kernel_upd_lsp(lsp);
|
||||
|
||||
zvrf->lsp_installs++;
|
||||
}
|
||||
@ -1659,6 +1636,42 @@ static int mpls_processq_init(struct zebra_t *zebra)
|
||||
|
||||
/* Public functions */
|
||||
|
||||
void kernel_lsp_pass_fail(zebra_lsp_t *lsp,
|
||||
enum southbound_results res)
|
||||
{
|
||||
struct nexthop *nexthop;
|
||||
zebra_nhlfe_t *nhlfe;
|
||||
|
||||
if (!lsp)
|
||||
return;
|
||||
|
||||
switch (res) {
|
||||
case SOUTHBOUND_INSTALL_FAILURE:
|
||||
UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
|
||||
clear_nhlfe_installed(lsp);
|
||||
zlog_warn("LSP Install Failure: %u", lsp->ile.in_label);
|
||||
break;
|
||||
case SOUTHBOUND_INSTALL_SUCCESS:
|
||||
SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
|
||||
for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) {
|
||||
nexthop = nhlfe->nexthop;
|
||||
if (!nexthop)
|
||||
continue;
|
||||
|
||||
SET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED);
|
||||
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
|
||||
}
|
||||
break;
|
||||
case SOUTHBOUND_DELETE_SUCCESS:
|
||||
UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
|
||||
clear_nhlfe_installed(lsp);
|
||||
break;
|
||||
case SOUTHBOUND_DELETE_FAILURE:
|
||||
zlog_warn("LSP Deletion Failure: %u", lsp->ile.in_label);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* String to label conversion, labels separated by '/'.
|
||||
*
|
||||
|
||||
@ -29,16 +29,21 @@
|
||||
/*
|
||||
* Install Label Forwarding entry into the kernel.
|
||||
*/
|
||||
int kernel_add_lsp(zebra_lsp_t *lsp)
|
||||
void kernel_add_lsp(zebra_lsp_t *lsp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!lsp || !lsp->best_nhlfe) // unexpected
|
||||
return -1;
|
||||
if (!lsp || !lsp->best_nhlfe) { // unexpected
|
||||
kernel_lsp_pass_fail(lsp, SOUTHBOUND_INSTALL_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = netlink_mpls_multipath(RTM_NEWROUTE, lsp);
|
||||
|
||||
return ret;
|
||||
kernel_lsp_pass_fail(lsp,
|
||||
(!ret) ?
|
||||
SOUTHBOUND_INSTALL_SUCCESS :
|
||||
SOUTHBOUND_INSTALL_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -52,14 +57,16 @@ int kernel_add_lsp(zebra_lsp_t *lsp)
|
||||
* through the metric field (before kernel-MPLS). This shouldn't be an issue
|
||||
* any longer, so REPLACE can be reintroduced.
|
||||
*/
|
||||
int kernel_upd_lsp(zebra_lsp_t *lsp)
|
||||
void kernel_upd_lsp(zebra_lsp_t *lsp)
|
||||
{
|
||||
int ret;
|
||||
zebra_nhlfe_t *nhlfe;
|
||||
struct nexthop *nexthop;
|
||||
|
||||
if (!lsp || !lsp->best_nhlfe) // unexpected
|
||||
return -1;
|
||||
if (!lsp || !lsp->best_nhlfe) { // unexpected
|
||||
kernel_lsp_pass_fail(lsp, SOUTHBOUND_INSTALL_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Any NHLFE that was installed but is not selected now needs to
|
||||
* have its flags updated.
|
||||
@ -78,25 +85,37 @@ int kernel_upd_lsp(zebra_lsp_t *lsp)
|
||||
|
||||
ret = netlink_mpls_multipath(RTM_NEWROUTE, lsp);
|
||||
|
||||
return ret;
|
||||
kernel_lsp_pass_fail(lsp,
|
||||
(!ret) ?
|
||||
SOUTHBOUND_INSTALL_SUCCESS :
|
||||
SOUTHBOUND_INSTALL_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete Label Forwarding entry from the kernel.
|
||||
*/
|
||||
int kernel_del_lsp(zebra_lsp_t *lsp)
|
||||
void kernel_del_lsp(zebra_lsp_t *lsp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!lsp) // unexpected
|
||||
return -1;
|
||||
if (!lsp) { // unexpected
|
||||
kernel_lsp_pass_fail(lsp,
|
||||
SOUTHBOUND_DELETE_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED))
|
||||
return -1;
|
||||
if (!CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) {
|
||||
kernel_lsp_pass_fail(lsp,
|
||||
SOUTHBOUND_DELETE_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = netlink_mpls_multipath(RTM_DELROUTE, lsp);
|
||||
|
||||
return ret;
|
||||
kernel_lsp_pass_fail(lsp,
|
||||
(!ret) ?
|
||||
SOUTHBOUND_DELETE_SUCCESS :
|
||||
SOUTHBOUND_DELETE_FAILURE);
|
||||
}
|
||||
|
||||
int mpls_kernel_init(void)
|
||||
|
||||
@ -24,17 +24,17 @@
|
||||
|
||||
#if !defined(HAVE_NETLINK) && !defined(OPEN_BSD)
|
||||
|
||||
int kernel_add_lsp(zebra_lsp_t *lsp)
|
||||
void kernel_add_lsp(zebra_lsp_t *lsp)
|
||||
{
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
int kernel_upd_lsp(zebra_lsp_t *lsp)
|
||||
void kernel_upd_lsp(zebra_lsp_t *lsp)
|
||||
{
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
int kernel_del_lsp(zebra_lsp_t *lsp)
|
||||
void kernel_del_lsp(zebra_lsp_t *lsp)
|
||||
{
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
int mpls_kernel_init(void)
|
||||
{
|
||||
|
||||
@ -279,56 +279,69 @@ static int kernel_lsp_cmd(int action, zebra_lsp_t *lsp)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (action == RTM_ADD || action == RTM_CHANGE) {
|
||||
SET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED);
|
||||
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
|
||||
} else {
|
||||
UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED);
|
||||
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int kernel_add_lsp(zebra_lsp_t *lsp)
|
||||
void kernel_add_lsp(zebra_lsp_t *lsp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!lsp || !lsp->best_nhlfe) // unexpected
|
||||
return -1;
|
||||
if (!lsp || !lsp->best_nhlfe) { // unexpected
|
||||
kernel_lsp_pass_fail(lsp, SOUTHBOUND_INSTALL_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = kernel_lsp_cmd(RTM_ADD, lsp);
|
||||
|
||||
return ret;
|
||||
kernel_lsp_pass_fail(lsp,
|
||||
(!ret) ?
|
||||
SOUTHBOUND_INSTALL_SUCCESS :
|
||||
SOUTHBOUND_INSTALL_FAILURE);
|
||||
}
|
||||
|
||||
int kernel_upd_lsp(zebra_lsp_t *lsp)
|
||||
void kernel_upd_lsp(zebra_lsp_t *lsp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!lsp || !lsp->best_nhlfe) // unexpected
|
||||
return -1;
|
||||
if (!lsp || !lsp->best_nhlfe) { // unexpected
|
||||
kernel_lsp_pass_fail(lsp, SOUTHBOUND_INSTALL_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = kernel_lsp_cmd(RTM_CHANGE, lsp);
|
||||
|
||||
return ret;
|
||||
kernel_lsp_pass_fail(lsp,
|
||||
(!ret) ?
|
||||
SOUTHBOUND_INSTALL_SUCCESS :
|
||||
SOUTHBOUND_INSTALL_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
int kernel_del_lsp(zebra_lsp_t *lsp)
|
||||
void kernel_del_lsp(zebra_lsp_t *lsp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!lsp) // unexpected
|
||||
return -1;
|
||||
if (!lsp) { // unexpected
|
||||
kernel_lsp_pass_fail(lsp,
|
||||
SOUTHBOUND_DELETE_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED))
|
||||
return -1;
|
||||
if (!CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) {
|
||||
kernel_lsp_pass_fail(lsp,
|
||||
SOUTHBOUND_DELETE_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = kernel_lsp_cmd(RTM_DELETE, lsp);
|
||||
|
||||
return ret;
|
||||
kernel_lsp_pass_fail(lsp,
|
||||
(!ret) ?
|
||||
SOUTHBOUND_DELETE_SUCCESS :
|
||||
SOUTHBOUND_DELETE_FAILURE);
|
||||
}
|
||||
|
||||
static int kmpw_install(struct zebra_pw *pw)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user