summaryrefslogtreecommitdiff
path: root/zebra/zebra_pbr.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zebra_pbr.c')
-rw-r--r--zebra/zebra_pbr.c79
1 files changed, 67 insertions, 12 deletions
diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c
index 56cac1342e..7f3635702f 100644
--- a/zebra/zebra_pbr.c
+++ b/zebra/zebra_pbr.c
@@ -1,6 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/* Zebra Policy Based Routing (PBR) main handling.
* Copyright (C) 2018 Cumulus Networks, Inc.
+ * Portions:
+ * Copyright (c) 2021 The MITRE Corporation.
+ * Copyright (c) 2023 LabN Consulting, L.L.C.
*/
#include <zebra.h>
@@ -166,10 +169,16 @@ uint32_t zebra_pbr_rules_hash_key(const void *arg)
key = jhash(rule->ifname, strlen(rule->ifname), key);
- return jhash_3words(rule->rule.filter.src_port,
- rule->rule.filter.dst_port,
- prefix_hash_key(&rule->rule.filter.dst_ip),
- jhash_1word(rule->rule.unique, key));
+ key = jhash_3words(rule->rule.filter.pcp, rule->rule.filter.vlan_id,
+ rule->rule.filter.vlan_flags, key);
+
+ key = jhash_3words(rule->rule.filter.src_port,
+ rule->rule.filter.dst_port,
+ prefix_hash_key(&rule->rule.filter.dst_ip), key);
+
+ key = jhash_2words(rule->rule.unique, rule->sock, key);
+
+ return key;
}
bool zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2)
@@ -185,6 +194,9 @@ bool zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2)
if (r1->rule.priority != r2->rule.priority)
return false;
+ if (r1->sock != r2->sock)
+ return false;
+
if (r1->rule.unique != r2->rule.unique)
return false;
@@ -220,8 +232,9 @@ bool zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2)
struct pbr_rule_unique_lookup {
struct zebra_pbr_rule *rule;
+ int sock;
uint32_t unique;
- char ifname[INTERFACE_NAMSIZ + 1];
+ char ifname[IFNAMSIZ + 1];
vrf_id_t vrf_id;
};
@@ -230,9 +243,9 @@ static int pbr_rule_lookup_unique_walker(struct hash_bucket *b, void *data)
struct pbr_rule_unique_lookup *pul = data;
struct zebra_pbr_rule *rule = b->data;
- if (pul->unique == rule->rule.unique
- && strncmp(pul->ifname, rule->rule.ifname, INTERFACE_NAMSIZ) == 0
- && pul->vrf_id == rule->vrf_id) {
+ if (pul->sock == rule->sock && pul->unique == rule->rule.unique &&
+ strmatch(pul->ifname, rule->rule.ifname) &&
+ pul->vrf_id == rule->vrf_id) {
pul->rule = rule;
return HASHWALK_ABORT;
}
@@ -246,9 +259,10 @@ pbr_rule_lookup_unique(struct zebra_pbr_rule *zrule)
struct pbr_rule_unique_lookup pul;
pul.unique = zrule->rule.unique;
- strlcpy(pul.ifname, zrule->rule.ifname, INTERFACE_NAMSIZ);
+ strlcpy(pul.ifname, zrule->rule.ifname, IFNAMSIZ);
pul.rule = NULL;
pul.vrf_id = zrule->vrf_id;
+ pul.sock = zrule->sock;
hash_walk(zrouter.rules_hash, &pbr_rule_lookup_unique_walker, &pul);
return pul.rule;
@@ -501,6 +515,7 @@ void zebra_pbr_show_rule_unit(struct zebra_pbr_rule *rule, struct vty *vty)
{
struct pbr_rule *prule = &rule->rule;
struct zebra_pbr_action *zaction = &rule->action;
+ struct pbr_action *pa = &prule->action;
vty_out(vty, "Rules if %s\n", rule->ifname);
vty_out(vty, " Seq %u pri %u\n", prule->seq, prule->priority);
@@ -516,15 +531,55 @@ void zebra_pbr_show_rule_unit(struct zebra_pbr_rule *rule, struct vty *vty)
if (prule->filter.filter_bm & PBR_FILTER_DST_PORT)
vty_out(vty, " DST Port Match: %u\n", prule->filter.dst_port);
- if (prule->filter.filter_bm & PBR_FILTER_DSFIELD) {
+ if (prule->filter.filter_bm & PBR_FILTER_DSCP)
vty_out(vty, " DSCP Match: %u\n",
(prule->filter.dsfield & PBR_DSFIELD_DSCP) >> 2);
+ if (prule->filter.filter_bm & PBR_FILTER_ECN)
vty_out(vty, " ECN Match: %u\n",
prule->filter.dsfield & PBR_DSFIELD_ECN);
- }
if (prule->filter.filter_bm & PBR_FILTER_FWMARK)
vty_out(vty, " MARK Match: %u\n", prule->filter.fwmark);
+ if (prule->filter.filter_bm & PBR_FILTER_PCP)
+ vty_out(vty, " PCP Match: %u\n", prule->filter.pcp);
+ if (prule->filter.filter_bm & PBR_FILTER_VLAN_ID)
+ vty_out(vty, " VLAN ID Match: %u\n", prule->filter.vlan_id);
+ if (prule->filter.filter_bm & PBR_FILTER_VLAN_FLAGS) {
+ vty_out(vty, " VLAN Flags Match:");
+ if (CHECK_FLAG(prule->filter.vlan_flags, PBR_VLAN_FLAGS_TAGGED))
+ vty_out(vty, " tagged");
+ if (CHECK_FLAG(prule->filter.vlan_flags,
+ PBR_VLAN_FLAGS_UNTAGGED))
+ vty_out(vty, " untagged");
+ if (CHECK_FLAG(prule->filter.vlan_flags,
+ PBR_VLAN_FLAGS_UNTAGGED_0))
+ vty_out(vty, " untagged-or-zero");
+ vty_out(vty, "\n");
+ }
+
+ if (CHECK_FLAG(pa->flags, PBR_ACTION_ECN))
+ vty_out(vty, " Action: Set ECN: %u\n", pa->ecn);
+ if (CHECK_FLAG(pa->flags, PBR_ACTION_DSCP))
+ vty_out(vty, " Action: Set DSCP: %u\n", pa->dscp >> 2);
+
+ if (CHECK_FLAG(pa->flags, PBR_ACTION_SRC_IP))
+ vty_out(vty, " Action: Set SRC IP: %pSU\n", &pa->src_ip);
+ if (CHECK_FLAG(pa->flags, PBR_ACTION_DST_IP))
+ vty_out(vty, " Action: Set DST IP: %pSU\n", &pa->dst_ip);
+ if (CHECK_FLAG(pa->flags, PBR_ACTION_SRC_PORT))
+ vty_out(vty, " Action: Set SRC PORT: %u\n", pa->src_port);
+ if (CHECK_FLAG(pa->flags, PBR_ACTION_DST_PORT))
+ vty_out(vty, " Action: Set DST PORT: %u\n", pa->dst_port);
+
+ if (CHECK_FLAG(pa->flags, PBR_ACTION_QUEUE_ID))
+ vty_out(vty, " Action: Set Queue ID: %u\n", pa->queue_id);
+
+ if (CHECK_FLAG(pa->flags, PBR_ACTION_PCP))
+ vty_out(vty, " Action: Set PCP: %u\n", pa->pcp);
+ if (CHECK_FLAG(pa->flags, PBR_ACTION_VLAN_ID))
+ vty_out(vty, " Action: Set VLAN ID: %u\n", pa->vlan_id);
+ if (CHECK_FLAG(pa->flags, PBR_ACTION_VLAN_STRIP_INNER_ANY))
+ vty_out(vty, " Action: Strip VLAN ID\n");
vty_out(vty, " Tableid: %u\n", prule->action.table);
if (zaction->afi == AFI_IP)
@@ -1118,7 +1173,7 @@ static void zebra_pbr_display_port(struct vty *vty, uint32_t filter_bm,
uint16_t port_min, uint16_t port_max,
uint8_t proto)
{
- if (!(filter_bm & PBR_FILTER_PROTO)) {
+ if (!(filter_bm & PBR_FILTER_IP_PROTOCOL)) {
if (port_max)
vty_out(vty, ":udp/tcp:%d-%d",
port_min, port_max);