#include "zebra/zebra_mpls.h"
#include "zebra/debug.h"
#include "zebra/zebra_errors.h"
+#include "zebra/zebra_router.h"
#include "privs.h"
#include "prefix.h"
} kr_state;
static int kernel_send_rtmsg_v4(int action, mpls_label_t in_label,
- zebra_nhlfe_t *nhlfe)
+ const zebra_nhlfe_t *nhlfe)
{
struct iovec iov[5];
struct rt_msghdr hdr;
#endif
static int kernel_send_rtmsg_v6(int action, mpls_label_t in_label,
- zebra_nhlfe_t *nhlfe)
+ const zebra_nhlfe_t *nhlfe)
{
struct iovec iov[5];
struct rt_msghdr hdr;
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;
+ const 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;
- if (nexthop_num >= multipath_num)
+ if (nexthop_num >= zrouter.multipath_num)
break;
if (((action == RTM_ADD || action == RTM_CHANGE)
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;
return (0);
}
-enum dp_req_result kernel_add_lsp(zebra_lsp_t *lsp)
-{
- int ret;
-
- if (!lsp || !lsp->best_nhlfe) { // unexpected
- kernel_lsp_pass_fail(lsp, DP_INSTALL_FAILURE);
- return DP_REQUEST_FAILURE;
- }
-
- ret = kernel_lsp_cmd(RTM_ADD, lsp);
-
- kernel_lsp_pass_fail(lsp,
- (!ret) ? DP_INSTALL_SUCCESS
- : DP_INSTALL_FAILURE);
-
- return DP_REQUEST_SUCCESS;
-}
-
-enum dp_req_result kernel_upd_lsp(zebra_lsp_t *lsp)
-{
- int ret;
-
- if (!lsp || !lsp->best_nhlfe) { // unexpected
- kernel_lsp_pass_fail(lsp, DP_INSTALL_FAILURE);
- return DP_REQUEST_FAILURE;
- }
-
- ret = kernel_lsp_cmd(RTM_CHANGE, lsp);
-
- kernel_lsp_pass_fail(lsp,
- (!ret) ? DP_INSTALL_SUCCESS
- : DP_INSTALL_FAILURE);
- return DP_REQUEST_SUCCESS;
-}
-
-enum dp_req_result kernel_del_lsp(zebra_lsp_t *lsp)
+enum zebra_dplane_result kernel_lsp_update(struct zebra_dplane_ctx *ctx)
{
int ret;
- if (!lsp) { // unexpected
- kernel_lsp_pass_fail(lsp, DP_DELETE_FAILURE);
- return DP_REQUEST_FAILURE;
- }
-
- if (!CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) {
- kernel_lsp_pass_fail(lsp, DP_DELETE_FAILURE);
- return DP_REQUEST_FAILURE;
- }
+ ret = kernel_lsp_cmd(ctx);
- ret = kernel_lsp_cmd(RTM_DELETE, lsp);
-
- kernel_lsp_pass_fail(lsp,
- (!ret) ? DP_DELETE_SUCCESS
- : DP_DELETE_FAILURE);
-
- return DP_REQUEST_SUCCESS;
+ return (ret == 0 ?
+ ZEBRA_DPLANE_REQUEST_SUCCESS : ZEBRA_DPLANE_REQUEST_FAILURE);
}
-static int kmpw_install(struct zebra_pw *pw)
+static enum zebra_dplane_result kmpw_install(struct zebra_dplane_ctx *ctx)
{
struct ifreq ifr;
struct ifmpwreq imr;
struct sockaddr_storage ss;
struct sockaddr_in *sa_in = (struct sockaddr_in *)&ss;
struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)&ss;
+ const union g_addr *gaddr;
memset(&imr, 0, sizeof(imr));
- switch (pw->type) {
+ switch (dplane_ctx_get_pw_type(ctx)) {
case PW_TYPE_ETHERNET:
imr.imr_type = IMR_TYPE_ETHERNET;
break;
break;
default:
zlog_debug("%s: unhandled pseudowire type (%#X)", __func__,
- pw->type);
- return -1;
+ dplane_ctx_get_pw_type(ctx));
+ return ZEBRA_DPLANE_REQUEST_FAILURE;
}
- if (pw->flags & F_PSEUDOWIRE_CWORD)
+ if (dplane_ctx_get_pw_flags(ctx) & F_PSEUDOWIRE_CWORD)
imr.imr_flags |= IMR_FLAG_CONTROLWORD;
/* pseudowire nexthop */
memset(&ss, 0, sizeof(ss));
- switch (pw->af) {
+ gaddr = dplane_ctx_get_pw_dest(ctx);
+ switch (dplane_ctx_get_pw_af(ctx)) {
case AF_INET:
sa_in->sin_family = AF_INET;
sa_in->sin_len = sizeof(struct sockaddr_in);
- sa_in->sin_addr = pw->nexthop.ipv4;
+ sa_in->sin_addr = gaddr->ipv4;
break;
case AF_INET6:
sa_in6->sin6_family = AF_INET6;
sa_in6->sin6_len = sizeof(struct sockaddr_in6);
- sa_in6->sin6_addr = pw->nexthop.ipv6;
+ sa_in6->sin6_addr = gaddr->ipv6;
break;
default:
zlog_debug("%s: unhandled pseudowire address-family (%u)",
- __func__, pw->af);
- return -1;
+ __func__, dplane_ctx_get_pw_af(ctx));
+ return ZEBRA_DPLANE_REQUEST_FAILURE;
}
memcpy(&imr.imr_nexthop, (struct sockaddr *)&ss,
sizeof(imr.imr_nexthop));
/* pseudowire local/remote labels */
- imr.imr_lshim.shim_label = pw->local_label;
- imr.imr_rshim.shim_label = pw->remote_label;
+ imr.imr_lshim.shim_label = dplane_ctx_get_pw_local_label(ctx);
+ imr.imr_rshim.shim_label = dplane_ctx_get_pw_remote_label(ctx);
/* ioctl */
memset(&ifr, 0, sizeof(ifr));
- strlcpy(ifr.ifr_name, pw->ifname, sizeof(ifr.ifr_name));
+ strlcpy(ifr.ifr_name, dplane_ctx_get_pw_ifname(ctx),
+ sizeof(ifr.ifr_name));
ifr.ifr_data = (caddr_t)&imr;
if (ioctl(kr_state.ioctl_fd, SIOCSETMPWCFG, &ifr) == -1) {
flog_err_sys(EC_LIB_SYSTEM_CALL, "ioctl SIOCSETMPWCFG: %s",
safe_strerror(errno));
- return -1;
+ return ZEBRA_DPLANE_REQUEST_FAILURE;
}
- return 0;
+ return ZEBRA_DPLANE_REQUEST_SUCCESS;
}
-static int kmpw_uninstall(struct zebra_pw *pw)
+static enum zebra_dplane_result kmpw_uninstall(struct zebra_dplane_ctx *ctx)
{
struct ifreq ifr;
struct ifmpwreq imr;
memset(&ifr, 0, sizeof(ifr));
memset(&imr, 0, sizeof(imr));
- strlcpy(ifr.ifr_name, pw->ifname, sizeof(ifr.ifr_name));
+ strlcpy(ifr.ifr_name, dplane_ctx_get_pw_ifname(ctx),
+ sizeof(ifr.ifr_name));
ifr.ifr_data = (caddr_t)&imr;
if (ioctl(kr_state.ioctl_fd, SIOCSETMPWCFG, &ifr) == -1) {
flog_err_sys(EC_LIB_SYSTEM_CALL, "ioctl SIOCSETMPWCFG: %s",
safe_strerror(errno));
- return -1;
+ return ZEBRA_DPLANE_REQUEST_FAILURE;
}
- return 0;
+ return ZEBRA_DPLANE_REQUEST_SUCCESS;
+}
+
+/*
+ * Pseudowire update api for openbsd.
+ */
+enum zebra_dplane_result kernel_pw_update(struct zebra_dplane_ctx *ctx)
+{
+ enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE;
+
+ switch (dplane_ctx_get_op(ctx)) {
+ case DPLANE_OP_PW_INSTALL:
+ result = kmpw_install(ctx);
+ break;
+ case DPLANE_OP_PW_UNINSTALL:
+ result = kmpw_uninstall(ctx);
+ break;
+ default:
+ break;
+ }
+
+ return result;
}
#define MAX_RTSOCK_BUF 128 * 1024
kr_state.rtseq = 1;
- /* register hook to install/uninstall pseudowires */
- hook_register(pw_install, kmpw_install);
- hook_register(pw_uninstall, kmpw_uninstall);
-
return 0;
}