summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--zebra/dplane_fpm_nl.c47
-rw-r--r--zebra/rt_netlink.c15
-rw-r--r--zebra/rt_netlink.h3
3 files changed, 53 insertions, 12 deletions
diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c
index 02881a6447..2a87925231 100644
--- a/zebra/dplane_fpm_nl.c
+++ b/zebra/dplane_fpm_nl.c
@@ -65,6 +65,7 @@ struct fpm_nl_ctx {
bool disabled;
bool connecting;
bool use_nhg;
+ bool use_route_replace;
struct sockaddr_storage addr;
/* data plane buffers. */
@@ -282,6 +283,25 @@ DEFUN(no_fpm_use_nhg, no_fpm_use_nhg_cmd,
return CMD_SUCCESS;
}
+DEFUN(fpm_use_route_replace, fpm_use_route_replace_cmd,
+ "fpm use-route-replace",
+ FPM_STR
+ "Use netlink route replace semantics\n")
+{
+ gfnc->use_route_replace = true;
+ return CMD_SUCCESS;
+}
+
+DEFUN(no_fpm_use_route_replace, no_fpm_use_route_replace_cmd,
+ "no fpm use-route-replace",
+ NO_STR
+ FPM_STR
+ "Use netlink route replace semantics\n")
+{
+ gfnc->use_route_replace = false;
+ return CMD_SUCCESS;
+}
+
DEFUN(fpm_reset_counters, fpm_reset_counters_cmd,
"clear fpm counters",
CLEAR_STR
@@ -396,6 +416,11 @@ static int fpm_write_config(struct vty *vty)
written = 1;
}
+ if (!gfnc->use_route_replace) {
+ vty_out(vty, "no fpm use-route-replace\n");
+ written = 1;
+ }
+
return written;
}
@@ -807,12 +832,20 @@ static int fpm_nl_enqueue(struct fpm_nl_ctx *fnc, struct zebra_dplane_ctx *ctx)
frr_mutex_lock_autounlock(&fnc->obuf_mutex);
+ /*
+ * If route replace is enabled then directly encode the install which
+ * is going to use `NLM_F_REPLACE` (instead of delete/add operations).
+ */
+ if (fnc->use_route_replace && op == DPLANE_OP_ROUTE_UPDATE)
+ op = DPLANE_OP_ROUTE_INSTALL;
+
switch (op) {
case DPLANE_OP_ROUTE_UPDATE:
case DPLANE_OP_ROUTE_DELETE:
rv = netlink_route_multipath_msg_encode(RTM_DELROUTE, ctx,
nl_buf, sizeof(nl_buf),
- true, fnc->use_nhg);
+ true, fnc->use_nhg,
+ false);
if (rv <= 0) {
zlog_err(
"%s: netlink_route_multipath_msg_encode failed",
@@ -828,9 +861,12 @@ static int fpm_nl_enqueue(struct fpm_nl_ctx *fnc, struct zebra_dplane_ctx *ctx)
/* FALL THROUGH */
case DPLANE_OP_ROUTE_INSTALL:
- rv = netlink_route_multipath_msg_encode(
- RTM_NEWROUTE, ctx, &nl_buf[nl_buf_len],
- sizeof(nl_buf) - nl_buf_len, true, fnc->use_nhg);
+ rv = netlink_route_multipath_msg_encode(RTM_NEWROUTE, ctx,
+ &nl_buf[nl_buf_len],
+ sizeof(nl_buf) -
+ nl_buf_len,
+ true, fnc->use_nhg,
+ fnc->use_route_replace);
if (rv <= 0) {
zlog_err(
"%s: netlink_route_multipath_msg_encode failed",
@@ -1469,6 +1505,7 @@ static int fpm_nl_start(struct zebra_dplane_provider *prov)
/* Set default values. */
fnc->use_nhg = true;
+ fnc->use_route_replace = true;
return 0;
}
@@ -1609,6 +1646,8 @@ static int fpm_nl_new(struct event_loop *tm)
install_element(CONFIG_NODE, &no_fpm_set_address_cmd);
install_element(CONFIG_NODE, &fpm_use_nhg_cmd);
install_element(CONFIG_NODE, &no_fpm_use_nhg_cmd);
+ install_element(CONFIG_NODE, &fpm_use_route_replace_cmd);
+ install_element(CONFIG_NODE, &no_fpm_use_route_replace_cmd);
return 0;
}
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 2318cd6374..12f8d89de0 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -2060,10 +2060,10 @@ static int netlink_route_nexthop_encap(struct nlmsghdr *n, size_t nlen,
* Returns -1 on failure, 0 when the msg doesn't fit entirely in the buffer
* otherwise the number of bytes written to buf.
*/
-ssize_t netlink_route_multipath_msg_encode(int cmd,
- struct zebra_dplane_ctx *ctx,
+ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx,
uint8_t *data, size_t datalen,
- bool fpm, bool force_nhg)
+ bool fpm, bool force_nhg,
+ bool force_rr)
{
int bytelen;
struct nexthop *nexthop = NULL;
@@ -2097,8 +2097,9 @@ ssize_t netlink_route_multipath_msg_encode(int cmd,
req->n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
req->n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
- if ((cmd == RTM_NEWROUTE) &&
- ((p->family == AF_INET) || v6_rr_semantics))
+ if (((cmd == RTM_NEWROUTE) &&
+ ((p->family == AF_INET) || v6_rr_semantics)) ||
+ force_rr)
req->n.nlmsg_flags |= NLM_F_REPLACE;
req->n.nlmsg_type = cmd;
@@ -2953,14 +2954,14 @@ static ssize_t netlink_newroute_msg_encoder(struct zebra_dplane_ctx *ctx,
void *buf, size_t buflen)
{
return netlink_route_multipath_msg_encode(RTM_NEWROUTE, ctx, buf,
- buflen, false, false);
+ buflen, false, false, false);
}
static ssize_t netlink_delroute_msg_encoder(struct zebra_dplane_ctx *ctx,
void *buf, size_t buflen)
{
return netlink_route_multipath_msg_encode(RTM_DELROUTE, ctx, buf,
- buflen, false, false);
+ buflen, false, false, false);
}
enum netlink_msg_status
diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h
index d9d0ee7624..d51944f1a4 100644
--- a/zebra/rt_netlink.h
+++ b/zebra/rt_netlink.h
@@ -56,7 +56,8 @@ extern ssize_t netlink_mpls_multipath_msg_encode(int cmd,
extern ssize_t netlink_route_multipath_msg_encode(int cmd,
struct zebra_dplane_ctx *ctx,
uint8_t *data, size_t datalen,
- bool fpm, bool force_nhg);
+ bool fpm, bool force_nhg,
+ bool force_rr);
extern ssize_t netlink_macfdb_update_ctx(struct zebra_dplane_ctx *ctx,
void *data, size_t datalen);