diff options
author | Eli Baum <ebaum@mitre.org> | 2021-10-05 15:06:49 +0200 |
---|---|---|
committer | Eli Baum <ebaum@mitre.org> | 2021-10-07 15:14:59 +0200 |
commit | d70a31a3ef2b60d978b336d5cc9ee5e1ec079dfc (patch) | |
tree | 2fdf320ce338a2078a2d9bac1453e59fcd04ef91 /pbrd | |
parent | Merge pull request #9694 from mjstapp/fix_topo_pim_cmp (diff) | |
download | frr-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.c | 35 | ||||
-rw-r--r-- | pbrd/pbr_map.h | 12 | ||||
-rw-r--r-- | pbrd/pbr_vty.c | 105 | ||||
-rw-r--r-- | pbrd/pbr_zebra.c | 6 |
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) |