diff options
Diffstat (limited to 'zebra/rule_netlink.c')
| -rw-r--r-- | zebra/rule_netlink.c | 85 |
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; } /* |
