summaryrefslogtreecommitdiffstats
path: root/pbrd
diff options
context:
space:
mode:
authorEli Baum <ebaum@mitre.org>2021-10-05 15:06:49 +0200
committerEli Baum <ebaum@mitre.org>2021-10-07 15:14:59 +0200
commitd70a31a3ef2b60d978b336d5cc9ee5e1ec079dfc (patch)
tree2fdf320ce338a2078a2d9bac1453e59fcd04ef91 /pbrd
parentMerge pull request #9694 from mjstapp/fix_topo_pim_cmp (diff)
downloadfrr-d70a31a3ef2b60d978b336d5cc9ee5e1ec079dfc.tar.xz
frr-d70a31a3ef2b60d978b336d5cc9ee5e1ec079dfc.zip
pbrd: add vlan actions to vty
Signed-off-by: Eli Baum <ebaum@mitre.org>
Diffstat (limited to 'pbrd')
-rw-r--r--pbrd/pbr_map.c35
-rw-r--r--pbrd/pbr_map.h12
-rw-r--r--pbrd/pbr_vty.c105
-rw-r--r--pbrd/pbr_zebra.c6
4 files changed, 153 insertions, 5 deletions
diff --git a/pbrd/pbr_map.c b/pbrd/pbr_map.c
index 053b7363a..03e6bacf1 100644
--- a/pbrd/pbr_map.c
+++ b/pbrd/pbr_map.c
@@ -178,9 +178,9 @@ static void pbr_map_pbrms_uninstall(struct pbr_map_sequence *pbrms)
}
static const char *const pbr_map_reason_str[] = {
- "Invalid NH-group", "Invalid NH", "No Nexthops",
- "Both NH and NH-Group", "Invalid Src or Dst", "Invalid VRF",
- "Deleting Sequence",
+ "Invalid NH-group", "Invalid NH", "No Nexthops",
+ "Both NH and NH-Group", "Invalid Src or Dst", "Invalid VRF",
+ "Both VLAN Set and Strip", "Deleting Sequence",
};
void pbr_map_reason_string(unsigned int reason, char *buf, int size)
@@ -539,6 +539,13 @@ struct pbr_map_sequence *pbrms_get(const char *name, uint32_t seqno)
pbrms->seqno = seqno;
pbrms->ruleno = pbr_nht_get_next_rule(seqno);
pbrms->parent = pbrm;
+
+ pbrms->action_vlan_id = 0;
+ pbrms->action_vlan_flags = 0;
+ pbrms->action_pcp = 0;
+
+ pbrms->action_queue_id = PBR_MAP_UNDEFINED_QUEUE_ID;
+
pbrms->reason =
PBR_MAP_INVALID_EMPTY |
PBR_MAP_INVALID_NO_NEXTHOPS;
@@ -601,10 +608,28 @@ pbr_map_sequence_check_nexthops_valid(struct pbr_map_sequence *pbrms)
static void pbr_map_sequence_check_not_empty(struct pbr_map_sequence *pbrms)
{
- if (!pbrms->src && !pbrms->dst && !pbrms->mark && !pbrms->dsfield)
+ if (!pbrms->src && !pbrms->dst && !pbrms->mark && !pbrms->dsfield
+ && !pbrms->action_vlan_id && !pbrms->action_vlan_flags
+ && !pbrms->action_pcp
+ && pbrms->action_queue_id == PBR_MAP_UNDEFINED_QUEUE_ID)
pbrms->reason |= PBR_MAP_INVALID_EMPTY;
}
+static void pbr_map_sequence_check_vlan_actions(struct pbr_map_sequence *pbrms)
+{
+ /* The set vlan tag action does the following:
+ * 1. If the frame is untagged, it tags the frame with the
+ * configured VLAN ID.
+ * 2. If the frame is tagged, if replaces the tag.
+ *
+ * The strip vlan action removes any inner tag, so it is invalid to
+ * specify both a set and strip action.
+ */
+ if ((pbrms->action_vlan_id != 0) && (pbrms->action_vlan_flags != 0))
+ pbrms->reason |= PBR_MAP_INVALID_SET_STRIP_VLAN;
+}
+
+
/*
* Checks to see if we think that the pbmrs is valid. If we think
* the config is valid return true.
@@ -612,7 +637,7 @@ static void pbr_map_sequence_check_not_empty(struct pbr_map_sequence *pbrms)
static void pbr_map_sequence_check_valid(struct pbr_map_sequence *pbrms)
{
pbr_map_sequence_check_nexthops_valid(pbrms);
-
+ pbr_map_sequence_check_vlan_actions(pbrms);
pbr_map_sequence_check_not_empty(pbrms);
}
diff --git a/pbrd/pbr_map.h b/pbrd/pbr_map.h
index 694b915f4..3527523fc 100644
--- a/pbrd/pbr_map.h
+++ b/pbrd/pbr_map.h
@@ -104,6 +104,17 @@ struct pbr_map_sequence {
uint32_t mark;
/*
+ * Actions
+ */
+ uint8_t action_pcp;
+ uint8_t action_vlan_id;
+#define PBR_MAP_STRIP_INNER_ANY (1 << 0)
+ uint8_t action_vlan_flags;
+
+#define PBR_MAP_UNDEFINED_QUEUE_ID 0
+ uint32_t action_queue_id;
+
+ /*
* Family of the src/dst. Needed when deleting since we clear them
*/
unsigned char family;
@@ -158,6 +169,7 @@ struct pbr_map_sequence {
#define PBR_MAP_INVALID_BOTH_NHANDGRP (1 << 3)
#define PBR_MAP_INVALID_EMPTY (1 << 4)
#define PBR_MAP_INVALID_VRF (1 << 5)
+#define PBR_MAP_INVALID_SET_STRIP_VLAN (1 << 6)
uint64_t reason;
QOBJ_FIELDS;
diff --git a/pbrd/pbr_vty.c b/pbrd/pbr_vty.c
index d083b9d2b..8a4132642 100644
--- a/pbrd/pbr_vty.c
+++ b/pbrd/pbr_vty.c
@@ -407,6 +407,82 @@ static void pbrms_clear_set_config(struct pbr_map_sequence *pbrms)
pbrms->nhs_installed = false;
}
+
+DEFPY(pbr_map_action_queue_id, pbr_map_action_queue_id_cmd,
+ "[no] set queue-id <(1-65535)$queue_id>",
+ NO_STR
+ "Set the rest of the command\n"
+ "Set based on egress port queue id\n"
+ "A valid value in range 1..65535 \n")
+{
+ struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
+
+ if (!no)
+ pbrms->action_queue_id = queue_id;
+ else if ((uint32_t)queue_id == pbrms->action_queue_id)
+ pbrms->action_queue_id = PBR_MAP_UNDEFINED_QUEUE_ID;
+
+ pbr_map_check(pbrms, true);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY(pbr_map_action_pcp, pbr_map_action_pcp_cmd, "[no] set pcp <(0-7)$pcp>",
+ NO_STR
+ "Set the rest of the command\n"
+ "Set based on 802.1p Priority Code Point (PCP) value\n"
+ "A valid value in range 0..7\n")
+{
+ struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
+
+ if (!no)
+ pbrms->action_pcp = pcp;
+ else if (pcp == pbrms->action_pcp)
+ pbrms->action_pcp = 0;
+
+ pbr_map_check(pbrms, true);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY(pbr_map_action_vlan_id, pbr_map_action_vlan_id_cmd,
+ "[no] set vlan <(1-4094)$vlan_id>",
+ NO_STR
+ "Set the rest of the command\n"
+ "Set action for VLAN tagging\n"
+ "A valid value in range 1..4094\n")
+{
+ struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
+
+ if (!no)
+ pbrms->action_vlan_id = vlan_id;
+ else if (pbrms->action_vlan_id == vlan_id)
+ pbrms->action_vlan_id = 0;
+
+ pbr_map_check(pbrms, true);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY(pbr_map_action_strip_vlan, pbr_map_action_strip_vlan_cmd,
+ "[no] strip vlan",
+ NO_STR
+ "Strip the vlan tags from frame\n"
+ "Strip any inner vlan tag \n")
+{
+ struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
+
+ if (!no)
+ pbrms->action_vlan_flags = PBR_MAP_STRIP_INNER_ANY;
+ else
+ pbrms->action_vlan_flags = 0;
+
+ pbr_map_check(pbrms, true);
+
+ return CMD_SUCCESS;
+}
+
+
DEFPY(pbr_map_nexthop_group, pbr_map_nexthop_group_cmd,
"set nexthop-group NHGNAME$name",
"Set for the PBR-MAP\n"
@@ -764,6 +840,18 @@ static void vty_show_pbrms(struct vty *vty,
if (pbrms->mark)
vty_out(vty, " MARK Match: %u\n", pbrms->mark);
+ if (pbrms->action_queue_id != PBR_MAP_UNDEFINED_QUEUE_ID)
+ vty_out(vty, " Set Queue ID %u\n",
+ pbrms->action_queue_id);
+
+ if (pbrms->action_vlan_id != 0)
+ vty_out(vty, " Set VLAN ID %u\n", pbrms->action_vlan_id);
+ if (pbrms->action_vlan_flags == PBR_MAP_STRIP_INNER_ANY)
+ vty_out(vty, " Strip VLAN ID\n");
+ if (pbrms->action_pcp)
+ vty_out(vty, " Set PCP %u\n", pbrms->action_pcp);
+
+
if (pbrms->nhgrp_name) {
vty_out(vty, " Nexthop-Group: %s\n", pbrms->nhgrp_name);
@@ -1170,6 +1258,19 @@ static int pbr_vty_map_config_write_sequence(struct vty *vty,
if (pbrms->mark)
vty_out(vty, " match mark %u\n", pbrms->mark);
+
+ if (pbrms->action_queue_id != PBR_MAP_UNDEFINED_QUEUE_ID)
+ vty_out(vty, " set queue-id %d\n", pbrms->action_queue_id);
+
+ if (pbrms->action_pcp)
+ vty_out(vty, " set pcp %d\n", pbrms->action_pcp);
+
+ if (pbrms->action_vlan_id)
+ vty_out(vty, " set vlan %u\n", pbrms->action_vlan_id);
+
+ if (pbrms->action_vlan_flags == PBR_MAP_STRIP_INNER_ANY)
+ vty_out(vty, " strip vlan any\n");
+
if (pbrms->vrf_unchanged)
vty_out(vty, " set vrf unchanged\n");
@@ -1257,6 +1358,10 @@ void pbr_vty_init(void)
install_element(PBRMAP_NODE, &pbr_map_match_dscp_cmd);
install_element(PBRMAP_NODE, &pbr_map_match_ecn_cmd);
install_element(PBRMAP_NODE, &pbr_map_match_mark_cmd);
+ install_element(PBRMAP_NODE, &pbr_map_action_queue_id_cmd);
+ install_element(PBRMAP_NODE, &pbr_map_action_strip_vlan_cmd);
+ install_element(PBRMAP_NODE, &pbr_map_action_vlan_id_cmd);
+ install_element(PBRMAP_NODE, &pbr_map_action_pcp_cmd);
install_element(PBRMAP_NODE, &pbr_map_nexthop_group_cmd);
install_element(PBRMAP_NODE, &no_pbr_map_nexthop_group_cmd);
install_element(PBRMAP_NODE, &pbr_map_nexthop_cmd);
diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c
index 28def509d..47d82950e 100644
--- a/pbrd/pbr_zebra.c
+++ b/pbrd/pbr_zebra.c
@@ -542,6 +542,12 @@ static void pbr_encode_pbr_map_sequence(struct stream *s,
stream_putc(s, pbrms->dsfield);
stream_putl(s, pbrms->mark);
+ stream_putl(s, pbrms->action_queue_id);
+
+ stream_putw(s, pbrms->action_vlan_id);
+ stream_putw(s, pbrms->action_vlan_flags);
+ stream_putw(s, pbrms->action_pcp);
+
if (pbrms->vrf_unchanged || pbrms->vrf_lookup)
pbr_encode_pbr_map_sequence_vrf(s, pbrms, ifp);
else if (pbrms->nhgrp_name)