forked from Mirror/frr
pbrd: add vlan actions to vty
Signed-off-by: Eli Baum <ebaum@mitre.org>
This commit is contained in:
parent
ac32b03f98
commit
d70a31a3ef
|
@ -154,6 +154,31 @@ end destination.
|
|||
(ECN) field in the IP header; if this value matches then forward the packet
|
||||
according to the nexthop(s) specified.
|
||||
|
||||
|
||||
.. clicmd:: set queue-id (1-65535)
|
||||
|
||||
Set the egress port queue identifier for matched packets. The Linux Kernel
|
||||
provider does not currently support packet mangling, so this field will be
|
||||
ignored unless another provider is used.
|
||||
|
||||
.. clicmd:: set pcp (0-7)
|
||||
|
||||
Set the 802.1Q priority code point (PCP) for matched packets. A PCP of zero
|
||||
is the defaul (nominally, "best effort"). The Linux Kernel provider does not
|
||||
currently support packet mangling, so this field will be ignored unless
|
||||
another provider is used.
|
||||
|
||||
.. clicmd:: set vlan (1-4094)
|
||||
|
||||
Set the VLAN tag for matched packets. Identifiers 0 and 4095 are reserved.
|
||||
The Linux Kernel provider does not currently support packet mangling, so
|
||||
this field will be ignored unless another provider is used.
|
||||
|
||||
.. clicmd:: strip vlan
|
||||
|
||||
Strip inner vlan tags from matched packets. The Linux Kernel provider does not currently support packet mangling, so this field will be ignored unless another provider is used. It is invalid to specify both a `strip` and `set
|
||||
vlan` action.
|
||||
|
||||
.. clicmd:: set nexthop-group NAME
|
||||
|
||||
Use the nexthop-group NAME as the place to forward packets when the match
|
||||
|
|
|
@ -83,6 +83,13 @@ struct pbr_filter {
|
|||
* the user criteria may directly point to a table too.
|
||||
*/
|
||||
struct pbr_action {
|
||||
/* VLAN */
|
||||
uint8_t pcp;
|
||||
uint16_t vlan_id;
|
||||
uint16_t vlan_flags;
|
||||
|
||||
uint32_t queue_id;
|
||||
|
||||
uint32_t table;
|
||||
};
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@ 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",
|
||||
"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);
|
||||
}
|
||||
|
||||
|
|
|
@ -103,6 +103,17 @@ struct pbr_map_sequence {
|
|||
uint8_t dsfield;
|
||||
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
|
||||
*/
|
||||
|
@ -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;
|
||||
|
|
105
pbrd/pbr_vty.c
105
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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -3198,6 +3198,12 @@ static inline void zread_rule(ZAPI_HANDLER_ARGS)
|
|||
STREAM_GETW(s, zpr.rule.filter.dst_port);
|
||||
STREAM_GETC(s, zpr.rule.filter.dsfield);
|
||||
STREAM_GETL(s, zpr.rule.filter.fwmark);
|
||||
|
||||
STREAM_GETL(s, zpr.rule.action.queue_id);
|
||||
STREAM_GETW(s, zpr.rule.action.vlan_id);
|
||||
STREAM_GETW(s, zpr.rule.action.vlan_flags);
|
||||
STREAM_GETW(s, zpr.rule.action.pcp);
|
||||
|
||||
STREAM_GETL(s, zpr.rule.action.table);
|
||||
STREAM_GET(ifname, s, INTERFACE_NAMSIZ);
|
||||
|
||||
|
|
|
@ -261,6 +261,13 @@ struct dplane_ctx_rule {
|
|||
struct prefix src_ip;
|
||||
struct prefix dst_ip;
|
||||
uint8_t ip_proto;
|
||||
|
||||
uint8_t action_pcp;
|
||||
uint16_t action_vlan_id;
|
||||
uint16_t action_vlan_flags;
|
||||
|
||||
uint32_t action_queue_id;
|
||||
|
||||
char ifname[INTERFACE_NAMSIZ + 1];
|
||||
};
|
||||
|
||||
|
@ -2770,6 +2777,12 @@ static void dplane_ctx_rule_init_single(struct dplane_ctx_rule *dplane_rule,
|
|||
dplane_rule->ip_proto = rule->rule.filter.ip_proto;
|
||||
prefix_copy(&(dplane_rule->dst_ip), &rule->rule.filter.dst_ip);
|
||||
prefix_copy(&(dplane_rule->src_ip), &rule->rule.filter.src_ip);
|
||||
|
||||
dplane_rule->action_pcp = rule->rule.action.pcp;
|
||||
dplane_rule->action_vlan_flags = rule->rule.action.vlan_flags;
|
||||
dplane_rule->action_vlan_id = rule->rule.action.vlan_id;
|
||||
dplane_rule->action_queue_id = rule->rule.action.queue_id;
|
||||
|
||||
strlcpy(dplane_rule->ifname, rule->ifname, INTERFACE_NAMSIZ);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue