summaryrefslogtreecommitdiff
path: root/zebra/rule_netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/rule_netlink.c')
-rw-r--r--zebra/rule_netlink.c85
1 files changed, 40 insertions, 45 deletions
diff --git a/zebra/rule_netlink.c b/zebra/rule_netlink.c
index 648e9eabe1..3a3baab4ca 100644
--- a/zebra/rule_netlink.c
+++ b/zebra/rule_netlink.c
@@ -78,6 +78,8 @@ netlink_rule_msg_encode(int cmd, const struct zebra_dplane_ctx *ctx,
char buf1[PREFIX_STRLEN];
char buf2[PREFIX_STRLEN];
+ if (buflen < sizeof(*req))
+ return 0;
memset(req, 0, sizeof(*req));
family = PREFIX_FAMILY(src_ip);
bytelen = (family == AF_INET ? 4 : 16);
@@ -148,53 +150,55 @@ netlink_rule_msg_encode(int cmd, const struct zebra_dplane_ctx *ctx,
return NLMSG_ALIGN(req->n.nlmsg_len);
}
-/* Install or uninstall specified rule for a specific interface.
- * Form netlink message and ship it.
- */
-static int netlink_rule_update_internal(
- int cmd, const struct zebra_dplane_ctx *ctx, uint32_t filter_bm,
- uint32_t priority, uint32_t table, const struct prefix *src_ip,
- const struct prefix *dst_ip, uint32_t fwmark, uint8_t dsfield)
+static ssize_t netlink_rule_msg_encoder(struct zebra_dplane_ctx *ctx, void *buf,
+ size_t buflen)
{
- char buf[NL_PKT_BUF_SIZE];
+ int cmd = RTM_NEWRULE;
+
+ if (dplane_ctx_get_op(ctx) == DPLANE_OP_RULE_DELETE)
+ cmd = RTM_DELRULE;
- netlink_rule_msg_encode(cmd, ctx, filter_bm, priority, table, src_ip,
- dst_ip, fwmark, dsfield, buf, sizeof(buf));
- return netlink_talk_info(netlink_talk_filter, (void *)&buf,
- dplane_ctx_get_ns(ctx), 0);
+ return netlink_rule_msg_encode(
+ cmd, ctx, dplane_ctx_rule_get_filter_bm(ctx),
+ dplane_ctx_rule_get_priority(ctx),
+ dplane_ctx_rule_get_table(ctx), dplane_ctx_rule_get_src_ip(ctx),
+ dplane_ctx_rule_get_dst_ip(ctx),
+ dplane_ctx_rule_get_fwmark(ctx),
+ dplane_ctx_rule_get_dsfield(ctx), buf, buflen);
+}
+
+static ssize_t netlink_oldrule_msg_encoder(struct zebra_dplane_ctx *ctx,
+ void *buf, size_t buflen)
+{
+ return netlink_rule_msg_encode(
+ RTM_DELRULE, ctx, dplane_ctx_rule_get_old_filter_bm(ctx),
+ dplane_ctx_rule_get_old_priority(ctx),
+ dplane_ctx_rule_get_old_table(ctx),
+ dplane_ctx_rule_get_old_src_ip(ctx),
+ dplane_ctx_rule_get_old_dst_ip(ctx),
+ dplane_ctx_rule_get_old_fwmark(ctx),
+ dplane_ctx_rule_get_old_dsfield(ctx), buf, buflen);
}
+
/* Public functions */
-/*
- * Add, update or delete a rule from the
- * kernel, using info from a dataplane context.
- */
-enum zebra_dplane_result kernel_pbr_rule_update(struct zebra_dplane_ctx *ctx)
+enum netlink_msg_status
+netlink_put_rule_update_msg(struct nl_batch *bth, struct zebra_dplane_ctx *ctx)
{
enum dplane_op_e op;
- int cmd;
- int ret;
+ enum netlink_msg_status ret;
op = dplane_ctx_get_op(ctx);
- if (op == DPLANE_OP_RULE_ADD || op == DPLANE_OP_RULE_UPDATE)
- cmd = RTM_NEWRULE;
- else if (op == DPLANE_OP_RULE_DELETE)
- cmd = RTM_DELRULE;
- else {
+ if (!(op == DPLANE_OP_RULE_ADD || op == DPLANE_OP_RULE_UPDATE
+ || op == DPLANE_OP_RULE_DELETE)) {
flog_err(
EC_ZEBRA_PBR_RULE_UPDATE,
"Context received for kernel rule update with incorrect OP code (%u)",
op);
- return ZEBRA_DPLANE_REQUEST_FAILURE;
+ return FRR_NETLINK_ERROR;
}
- ret = netlink_rule_update_internal(
- cmd, ctx, dplane_ctx_rule_get_filter_bm(ctx),
- dplane_ctx_rule_get_priority(ctx),
- dplane_ctx_rule_get_table(ctx), dplane_ctx_rule_get_src_ip(ctx),
- dplane_ctx_rule_get_dst_ip(ctx),
- dplane_ctx_rule_get_fwmark(ctx),
- dplane_ctx_rule_get_dsfield(ctx));
+ ret = netlink_batch_add_msg(bth, ctx, netlink_rule_msg_encoder, false);
/**
* Delete the old one.
@@ -202,19 +206,10 @@ enum zebra_dplane_result kernel_pbr_rule_update(struct zebra_dplane_ctx *ctx)
* Don't care about this result right?
*/
if (op == DPLANE_OP_RULE_UPDATE)
- netlink_rule_update_internal(
- RTM_DELRULE, ctx,
- dplane_ctx_rule_get_old_filter_bm(ctx),
- dplane_ctx_rule_get_old_priority(ctx),
- dplane_ctx_rule_get_old_table(ctx),
- dplane_ctx_rule_get_old_src_ip(ctx),
- dplane_ctx_rule_get_old_dst_ip(ctx),
- dplane_ctx_rule_get_old_fwmark(ctx),
- dplane_ctx_rule_get_old_dsfield(ctx));
-
-
- return (ret == 0 ? ZEBRA_DPLANE_REQUEST_SUCCESS
- : ZEBRA_DPLANE_REQUEST_FAILURE);
+ netlink_batch_add_msg(bth, ctx, netlink_oldrule_msg_encoder,
+ true);
+
+ return ret;
}
/*