diff options
Diffstat (limited to 'zebra/rule_netlink.c')
| -rw-r--r-- | zebra/rule_netlink.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/zebra/rule_netlink.c b/zebra/rule_netlink.c index c7832992ea..05282793d7 100644 --- a/zebra/rule_netlink.c +++ b/zebra/rule_netlink.c @@ -9,6 +9,9 @@ #ifdef HAVE_NETLINK +#include <linux/netlink.h> +#include <linux/rtnetlink.h> + #include "if.h" #include "prefix.h" #include "vrf.h" @@ -116,9 +119,9 @@ static ssize_t netlink_rule_msg_encode( return 0; } - /* dsfield, if specified */ - if (filter_bm & PBR_FILTER_DSFIELD) - req->frh.tos = dsfield; + /* dsfield, if specified; mask off the ECN bits */ + if (filter_bm & PBR_FILTER_DSCP) + req->frh.tos = dsfield & PBR_DSFIELD_DSCP; /* protocol to match on */ if (filter_bm & PBR_FILTER_IP_PROTOCOL) @@ -174,6 +177,17 @@ static ssize_t netlink_oldrule_msg_encoder(struct zebra_dplane_ctx *ctx, dplane_ctx_rule_get_old_ipproto(ctx), buf, buflen); } +/* + * Identify valid rule actions for netlink - other actions can't be installed + */ +static bool nl_rule_valid_action(uint32_t action) +{ + if (action == PBR_ACTION_TABLE) + return true; + else + return false; +} + /* Public functions */ enum netlink_msg_status @@ -181,6 +195,7 @@ netlink_put_rule_update_msg(struct nl_batch *bth, struct zebra_dplane_ctx *ctx) { enum dplane_op_e op; enum netlink_msg_status ret; + struct pbr_rule rule = {}; op = dplane_ctx_get_op(ctx); if (!(op == DPLANE_OP_RULE_ADD || op == DPLANE_OP_RULE_UPDATE @@ -192,6 +207,18 @@ netlink_put_rule_update_msg(struct nl_batch *bth, struct zebra_dplane_ctx *ctx) return FRR_NETLINK_ERROR; } + /* TODO -- special handling for rules that include actions that + * netlink cannot install. Some of the rule attributes are not + * available in netlink: only try to install valid actions. + */ + dplane_ctx_rule_get(ctx, &rule, NULL); + if (!nl_rule_valid_action(rule.action.flags)) { + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("%s: skip invalid action %#x", __func__, + rule.action.flags); + return 0; + } + ret = netlink_batch_add_msg(bth, ctx, netlink_rule_msg_encoder, false); /** @@ -400,6 +427,7 @@ int netlink_rules_read(struct zebra_ns *zns) ret = netlink_parse_info(netlink_rule_change, &zns->netlink_cmd, &dp_info, 0, true); + return ret; } |
