diff options
| author | Eli Baum <ebaum@mitre.org> | 2021-10-05 09:06:49 -0400 | 
|---|---|---|
| committer | Eli Baum <ebaum@mitre.org> | 2021-10-07 09:14:59 -0400 | 
| commit | d70a31a3ef2b60d978b336d5cc9ee5e1ec079dfc (patch) | |
| tree | 2fdf320ce338a2078a2d9bac1453e59fcd04ef91 /pbrd | |
| parent | ac32b03f9805df2639d6a62ffd1bef76da15e6f0 (diff) | |
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 053b7363a3..03e6bacf1e 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 694b915f48..3527523fc1 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 d083b9d2b0..8a4132642d 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 28def509d5..47d82950e7 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)  | 
