mirror of
https://git.proxmox.com/git/mirror_frr
synced 2026-01-06 23:40:35 +00:00
zebra: openbsd LSP update code
Finish the LSP update code for the async dataplane for the openbsd platform. Remove synch apis now that we've converted to the async code path. Signed-off-by: Mark Stapp <mjs@voltanet.io>
This commit is contained in:
parent
8a6423a372
commit
fc60837278
15
zebra/rt.h
15
zebra/rt.h
@ -50,21 +50,6 @@ extern int kernel_neigh_update(int cmd, int ifindex, uint32_t addr, char *lla,
|
||||
extern int kernel_interface_set_master(struct interface *master,
|
||||
struct interface *slave);
|
||||
|
||||
extern enum zebra_dplane_result kernel_add_lsp(zebra_lsp_t *lsp);
|
||||
extern enum zebra_dplane_result kernel_upd_lsp(zebra_lsp_t *lsp);
|
||||
extern enum zebra_dplane_result 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 zebra_dplane_status res);
|
||||
|
||||
extern int mpls_kernel_init(void);
|
||||
|
||||
extern uint32_t kernel_get_speed(struct interface *ifp);
|
||||
|
||||
@ -2615,162 +2615,11 @@ int kernel_del_neigh(struct interface *ifp, struct ipaddr *ip)
|
||||
return netlink_neigh_update2(ifp, ip, NULL, 0, 0, RTM_DELNEIGH);
|
||||
}
|
||||
|
||||
/*
|
||||
* MPLS label forwarding table change via netlink interface.
|
||||
*/
|
||||
int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
|
||||
{
|
||||
mpls_lse_t lse;
|
||||
zebra_nhlfe_t *nhlfe;
|
||||
struct nexthop *nexthop = NULL;
|
||||
unsigned int nexthop_num;
|
||||
const char *routedesc;
|
||||
struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT);
|
||||
int route_type;
|
||||
|
||||
struct {
|
||||
struct nlmsghdr n;
|
||||
struct rtmsg r;
|
||||
char buf[NL_PKT_BUF_SIZE];
|
||||
} req;
|
||||
|
||||
memset(&req, 0, sizeof req - NL_PKT_BUF_SIZE);
|
||||
|
||||
/*
|
||||
* Count # nexthops so we can decide whether to use singlepath
|
||||
* or multipath case.
|
||||
*/
|
||||
nexthop_num = 0;
|
||||
for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) {
|
||||
nexthop = nhlfe->nexthop;
|
||||
if (!nexthop)
|
||||
continue;
|
||||
if (cmd == RTM_NEWROUTE) {
|
||||
/* Count all selected NHLFEs */
|
||||
if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED)
|
||||
&& CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
|
||||
nexthop_num++;
|
||||
} else /* DEL */
|
||||
{
|
||||
/* Count all installed NHLFEs */
|
||||
if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED)
|
||||
&& CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
|
||||
nexthop_num++;
|
||||
}
|
||||
}
|
||||
|
||||
if ((nexthop_num == 0) || (!lsp->best_nhlfe && (cmd != RTM_DELROUTE)))
|
||||
return 0;
|
||||
|
||||
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
|
||||
req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
|
||||
req.n.nlmsg_type = cmd;
|
||||
req.n.nlmsg_pid = zns->netlink_cmd.snl.nl_pid;
|
||||
|
||||
req.r.rtm_family = AF_MPLS;
|
||||
req.r.rtm_table = RT_TABLE_MAIN;
|
||||
req.r.rtm_dst_len = MPLS_LABEL_LEN_BITS;
|
||||
req.r.rtm_scope = RT_SCOPE_UNIVERSE;
|
||||
req.r.rtm_type = RTN_UNICAST;
|
||||
|
||||
if (cmd == RTM_NEWROUTE) {
|
||||
/* We do a replace to handle update. */
|
||||
req.n.nlmsg_flags |= NLM_F_REPLACE;
|
||||
|
||||
/* set the protocol value if installing */
|
||||
route_type = re_type_from_lsp_type(lsp->best_nhlfe->type);
|
||||
req.r.rtm_protocol = zebra2proto(route_type);
|
||||
}
|
||||
|
||||
/* Fill destination */
|
||||
lse = mpls_lse_encode(lsp->ile.in_label, 0, 0, 1);
|
||||
addattr_l(&req.n, sizeof req, RTA_DST, &lse, sizeof(mpls_lse_t));
|
||||
|
||||
/* Fill nexthops (paths) based on single-path or multipath. The paths
|
||||
* chosen depend on the operation.
|
||||
*/
|
||||
if (nexthop_num == 1) {
|
||||
routedesc = "single-path";
|
||||
_netlink_mpls_debug(cmd, lsp->ile.in_label, routedesc);
|
||||
|
||||
nexthop_num = 0;
|
||||
for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) {
|
||||
nexthop = nhlfe->nexthop;
|
||||
if (!nexthop)
|
||||
continue;
|
||||
|
||||
if ((cmd == RTM_NEWROUTE
|
||||
&& (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED)
|
||||
&& CHECK_FLAG(nexthop->flags,
|
||||
NEXTHOP_FLAG_ACTIVE)))
|
||||
|| (cmd == RTM_DELROUTE
|
||||
&& (CHECK_FLAG(nhlfe->flags,
|
||||
NHLFE_FLAG_INSTALLED)
|
||||
&& CHECK_FLAG(nexthop->flags,
|
||||
NEXTHOP_FLAG_FIB)))) {
|
||||
/* Add the gateway */
|
||||
_netlink_mpls_build_singlepath(routedesc, nhlfe,
|
||||
&req.n, &req.r,
|
||||
sizeof req, cmd);
|
||||
nexthop_num++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else /* Multipath case */
|
||||
{
|
||||
char buf[NL_PKT_BUF_SIZE];
|
||||
struct rtattr *rta = (void *)buf;
|
||||
struct rtnexthop *rtnh;
|
||||
union g_addr *src1 = NULL;
|
||||
|
||||
rta->rta_type = RTA_MULTIPATH;
|
||||
rta->rta_len = RTA_LENGTH(0);
|
||||
rtnh = RTA_DATA(rta);
|
||||
|
||||
routedesc = "multipath";
|
||||
_netlink_mpls_debug(cmd, lsp->ile.in_label, routedesc);
|
||||
|
||||
nexthop_num = 0;
|
||||
for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) {
|
||||
nexthop = nhlfe->nexthop;
|
||||
if (!nexthop)
|
||||
continue;
|
||||
|
||||
if ((cmd == RTM_NEWROUTE
|
||||
&& (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED)
|
||||
&& CHECK_FLAG(nexthop->flags,
|
||||
NEXTHOP_FLAG_ACTIVE)))
|
||||
|| (cmd == RTM_DELROUTE
|
||||
&& (CHECK_FLAG(nhlfe->flags,
|
||||
NHLFE_FLAG_INSTALLED)
|
||||
&& CHECK_FLAG(nexthop->flags,
|
||||
NEXTHOP_FLAG_FIB)))) {
|
||||
nexthop_num++;
|
||||
|
||||
/* Build the multipath */
|
||||
_netlink_mpls_build_multipath(routedesc, nhlfe,
|
||||
rta, rtnh, &req.r,
|
||||
&src1);
|
||||
rtnh = RTNH_NEXT(rtnh);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the multipath */
|
||||
if (rta->rta_len > RTA_LENGTH(0))
|
||||
addattr_l(&req.n, NL_PKT_BUF_SIZE, RTA_MULTIPATH,
|
||||
RTA_DATA(rta), RTA_PAYLOAD(rta));
|
||||
}
|
||||
|
||||
/* Talk to netlink socket. */
|
||||
return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns,
|
||||
0);
|
||||
}
|
||||
|
||||
/*
|
||||
* MPLS label forwarding table change via netlink interface, using dataplane
|
||||
* context information.
|
||||
*/
|
||||
int netlink_mpls_multipath_ctx(int cmd, struct zebra_dplane_ctx *ctx)
|
||||
int netlink_mpls_multipath(int cmd, struct zebra_dplane_ctx *ctx)
|
||||
{
|
||||
mpls_lse_t lse;
|
||||
zebra_nhlfe_t *nhlfe;
|
||||
@ -2841,7 +2690,7 @@ int netlink_mpls_multipath_ctx(int cmd, struct zebra_dplane_ctx *ctx)
|
||||
/* Fill nexthops (paths) based on single-path or multipath. The paths
|
||||
* chosen depend on the operation.
|
||||
*/
|
||||
if (nexthop_num == 1 || multipath_num == 1) {
|
||||
if (nexthop_num == 1) {
|
||||
routedesc = "single-path";
|
||||
_netlink_mpls_debug(cmd, dplane_ctx_get_in_label(ctx),
|
||||
routedesc);
|
||||
@ -2893,9 +2742,6 @@ int netlink_mpls_multipath_ctx(int cmd, struct zebra_dplane_ctx *ctx)
|
||||
if (!nexthop)
|
||||
continue;
|
||||
|
||||
if (nexthop_num >= multipath_num)
|
||||
break;
|
||||
|
||||
if ((cmd == RTM_NEWROUTE
|
||||
&& (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED)
|
||||
&& CHECK_FLAG(nexthop->flags,
|
||||
|
||||
@ -59,10 +59,8 @@
|
||||
|
||||
void rt_netlink_init(void);
|
||||
|
||||
extern int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp);
|
||||
|
||||
/* MPLS label forwarding table change, using dataplane context information. */
|
||||
extern int netlink_mpls_multipath_ctx(int cmd, struct zebra_dplane_ctx *ctx);
|
||||
extern int netlink_mpls_multipath(int cmd, struct zebra_dplane_ctx *ctx);
|
||||
|
||||
extern int netlink_route_change(struct nlmsghdr *h, ns_id_t ns_id, int startup);
|
||||
extern int netlink_route_read(struct zebra_ns *zns);
|
||||
|
||||
@ -1736,45 +1736,6 @@ static int mpls_processq_init(struct zebra_t *zebra)
|
||||
|
||||
/* Public functions */
|
||||
|
||||
void kernel_lsp_pass_fail(zebra_lsp_t *lsp, enum zebra_dplane_status res)
|
||||
{
|
||||
struct nexthop *nexthop;
|
||||
zebra_nhlfe_t *nhlfe;
|
||||
|
||||
if (!lsp)
|
||||
return;
|
||||
|
||||
switch (res) {
|
||||
case ZEBRA_DPLANE_INSTALL_FAILURE:
|
||||
UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
|
||||
clear_nhlfe_installed(lsp);
|
||||
flog_warn(EC_ZEBRA_LSP_INSTALL_FAILURE,
|
||||
"LSP Install Failure: %u", lsp->ile.in_label);
|
||||
break;
|
||||
case ZEBRA_DPLANE_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 ZEBRA_DPLANE_DELETE_SUCCESS:
|
||||
UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
|
||||
clear_nhlfe_installed(lsp);
|
||||
break;
|
||||
case ZEBRA_DPLANE_DELETE_FAILURE:
|
||||
flog_warn(EC_ZEBRA_LSP_DELETE_FAILURE,
|
||||
"LSP Deletion Failure: %u", lsp->ile.in_label);
|
||||
break;
|
||||
case ZEBRA_DPLANE_STATUS_NONE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Process LSP update results from zebra dataplane.
|
||||
*/
|
||||
|
||||
@ -27,78 +27,6 @@
|
||||
#include "zebra/rt_netlink.h"
|
||||
#include "zebra/zebra_mpls.h"
|
||||
|
||||
/*
|
||||
* Install Label Forwarding entry into the kernel.
|
||||
*/
|
||||
enum zebra_dplane_result kernel_add_lsp(zebra_lsp_t *lsp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!lsp || !lsp->best_nhlfe) { // unexpected
|
||||
kernel_lsp_pass_fail(lsp, ZEBRA_DPLANE_INSTALL_FAILURE);
|
||||
return ZEBRA_DPLANE_REQUEST_FAILURE;
|
||||
}
|
||||
|
||||
ret = netlink_mpls_multipath(RTM_NEWROUTE, lsp);
|
||||
|
||||
kernel_lsp_pass_fail(lsp,
|
||||
(!ret) ? ZEBRA_DPLANE_INSTALL_SUCCESS
|
||||
: ZEBRA_DPLANE_INSTALL_FAILURE);
|
||||
|
||||
return ZEBRA_DPLANE_REQUEST_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update Label Forwarding entry in the kernel. This means that the Label
|
||||
* forwarding entry is already installed and needs an update - either a new
|
||||
* path is to be added, an installed path has changed (e.g., outgoing label)
|
||||
* or an installed path (but not all paths) has to be removed. This performs
|
||||
* a REPLACE operation, internally.
|
||||
*/
|
||||
enum zebra_dplane_result kernel_upd_lsp(zebra_lsp_t *lsp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!lsp || !lsp->best_nhlfe) { // unexpected
|
||||
kernel_lsp_pass_fail(lsp, ZEBRA_DPLANE_INSTALL_FAILURE);
|
||||
return ZEBRA_DPLANE_REQUEST_FAILURE;
|
||||
}
|
||||
|
||||
ret = netlink_mpls_multipath(RTM_NEWROUTE, lsp);
|
||||
|
||||
kernel_lsp_pass_fail(lsp,
|
||||
(!ret) ? ZEBRA_DPLANE_INSTALL_SUCCESS
|
||||
: ZEBRA_DPLANE_INSTALL_FAILURE);
|
||||
|
||||
return ZEBRA_DPLANE_REQUEST_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete Label Forwarding entry from the kernel.
|
||||
*/
|
||||
enum zebra_dplane_result kernel_del_lsp(zebra_lsp_t *lsp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!lsp) { // unexpected
|
||||
kernel_lsp_pass_fail(lsp, ZEBRA_DPLANE_DELETE_FAILURE);
|
||||
return ZEBRA_DPLANE_REQUEST_FAILURE;
|
||||
}
|
||||
|
||||
if (!CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) {
|
||||
kernel_lsp_pass_fail(lsp, ZEBRA_DPLANE_DELETE_FAILURE);
|
||||
return ZEBRA_DPLANE_REQUEST_FAILURE;
|
||||
}
|
||||
|
||||
ret = netlink_mpls_multipath(RTM_DELROUTE, lsp);
|
||||
|
||||
kernel_lsp_pass_fail(lsp,
|
||||
(!ret) ? ZEBRA_DPLANE_DELETE_SUCCESS
|
||||
: ZEBRA_DPLANE_DELETE_FAILURE);
|
||||
|
||||
return ZEBRA_DPLANE_REQUEST_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* LSP forwarding update using dataplane context information.
|
||||
*/
|
||||
@ -125,7 +53,7 @@ enum zebra_dplane_result kernel_lsp_update(struct zebra_dplane_ctx *ctx)
|
||||
/* Invalid op? */
|
||||
goto done;
|
||||
|
||||
ret = netlink_mpls_multipath_ctx(cmd, ctx);
|
||||
ret = netlink_mpls_multipath(cmd, ctx);
|
||||
|
||||
done:
|
||||
|
||||
|
||||
@ -236,13 +236,28 @@ static int kernel_send_rtmsg_v6(int action, mpls_label_t in_label,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int kernel_lsp_cmd(int action, zebra_lsp_t *lsp)
|
||||
static int kernel_lsp_cmd(struct zebra_dplane_ctx *ctx)
|
||||
{
|
||||
zebra_nhlfe_t *nhlfe;
|
||||
struct nexthop *nexthop = NULL;
|
||||
unsigned int nexthop_num = 0;
|
||||
int action;
|
||||
|
||||
for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) {
|
||||
switch (dplane_ctx_get_op(ctx)) {
|
||||
case DPLANE_OP_LSP_DELETE:
|
||||
action = RTM_DELETE;
|
||||
break;
|
||||
case DPLANE_OP_LSP_INSTALL:
|
||||
action = RTM_ADD;
|
||||
break;
|
||||
case DPLANE_OP_LSP_UPDATE:
|
||||
action = RTM_CHANGE;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (nhlfe = dplane_ctx_get_nhlfe(ctx); nhlfe; nhlfe = nhlfe->next) {
|
||||
nexthop = nhlfe->nexthop;
|
||||
if (!nexthop)
|
||||
continue;
|
||||
@ -269,12 +284,16 @@ static int kernel_lsp_cmd(int action, zebra_lsp_t *lsp)
|
||||
|
||||
switch (NHLFE_FAMILY(nhlfe)) {
|
||||
case AF_INET:
|
||||
kernel_send_rtmsg_v4(action, lsp->ile.in_label,
|
||||
nhlfe);
|
||||
kernel_send_rtmsg_v4(
|
||||
action,
|
||||
dplane_ctx_get_in_label(ctx),
|
||||
nhlfe);
|
||||
break;
|
||||
case AF_INET6:
|
||||
kernel_send_rtmsg_v6(action, lsp->ile.in_label,
|
||||
nhlfe);
|
||||
kernel_send_rtmsg_v6(
|
||||
action,
|
||||
dplane_ctx_get_in_label(ctx),
|
||||
nhlfe);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -285,67 +304,14 @@ static int kernel_lsp_cmd(int action, zebra_lsp_t *lsp)
|
||||
return (0);
|
||||
}
|
||||
|
||||
enum zebra_dplane_result kernel_add_lsp(zebra_lsp_t *lsp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!lsp || !lsp->best_nhlfe) { // unexpected
|
||||
kernel_lsp_pass_fail(lsp, ZEBRA_DPLANE_INSTALL_FAILURE);
|
||||
return ZEBRA_DPLANE_REQUEST_FAILURE;
|
||||
}
|
||||
|
||||
ret = kernel_lsp_cmd(RTM_ADD, lsp);
|
||||
|
||||
kernel_lsp_pass_fail(lsp,
|
||||
(!ret) ? ZEBRA_DPLANE_INSTALL_SUCCESS
|
||||
: ZEBRA_DPLANE_INSTALL_FAILURE);
|
||||
|
||||
return ZEBRA_DPLANE_REQUEST_SUCCESS;
|
||||
}
|
||||
|
||||
enum zebra_dplane_result kernel_upd_lsp(zebra_lsp_t *lsp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!lsp || !lsp->best_nhlfe) { // unexpected
|
||||
kernel_lsp_pass_fail(lsp, ZEBRA_DPLANE_INSTALL_FAILURE);
|
||||
return ZEBRA_DPLANE_REQUEST_FAILURE;
|
||||
}
|
||||
|
||||
ret = kernel_lsp_cmd(RTM_CHANGE, lsp);
|
||||
|
||||
kernel_lsp_pass_fail(lsp,
|
||||
(!ret) ? ZEBRA_DPLANE_INSTALL_SUCCESS
|
||||
: ZEBRA_DPLANE_INSTALL_FAILURE);
|
||||
return ZEBRA_DPLANE_REQUEST_SUCCESS;
|
||||
}
|
||||
|
||||
enum zebra_dplane_result kernel_del_lsp(zebra_lsp_t *lsp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!lsp) { // unexpected
|
||||
kernel_lsp_pass_fail(lsp, ZEBRA_DPLANE_DELETE_FAILURE);
|
||||
return ZEBRA_DPLANE_REQUEST_FAILURE;
|
||||
}
|
||||
|
||||
if (!CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) {
|
||||
kernel_lsp_pass_fail(lsp, ZEBRA_DPLANE_DELETE_FAILURE);
|
||||
return ZEBRA_DPLANE_REQUEST_FAILURE;
|
||||
}
|
||||
|
||||
ret = kernel_lsp_cmd(RTM_DELETE, lsp);
|
||||
|
||||
kernel_lsp_pass_fail(lsp,
|
||||
(!ret) ? ZEBRA_DPLANE_DELETE_SUCCESS
|
||||
: ZEBRA_DPLANE_DELETE_FAILURE);
|
||||
|
||||
return ZEBRA_DPLANE_REQUEST_SUCCESS;
|
||||
}
|
||||
|
||||
enum zebra_dplane_result kernel_lsp_update(struct zebra_dplane_ctx *ctx)
|
||||
{
|
||||
return ZEBRA_DPLANE_REQUEST_FAILURE;
|
||||
int ret;
|
||||
|
||||
ret = kernel_lsp_cmd(ctx);
|
||||
|
||||
return (ret == 0 ?
|
||||
ZEBRA_DPLANE_REQUEST_SUCCESS : ZEBRA_DPLANE_REQUEST_FAILURE);
|
||||
}
|
||||
|
||||
static int kmpw_install(struct zebra_pw *pw)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user