-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pbrd: add vty support for vlan filtering and send to zebra #13514
Changes from all commits
3b146fd
e270175
32cf0c3
f20b116
b21c325
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -114,6 +114,5 @@ refix | |
.kitchen | ||
.emacs.desktop* | ||
|
||
/test-suite.log | ||
pceplib/test/*.log | ||
pceplib/test/*.trs |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
/* Policy Based Routing (PBR) main header | ||
* Copyright (C) 2018 6WIND | ||
* Portions: | ||
* Copyright (c) 2021 The MITRE Corporation. | ||
*/ | ||
|
||
#ifndef _PBR_H | ||
|
@@ -25,30 +27,38 @@ extern "C" { | |
* specified. | ||
*/ | ||
struct pbr_filter { | ||
uint32_t filter_bm; /* not encoded by zapi | ||
*/ | ||
#define PBR_FILTER_SRC_IP (1 << 0) | ||
#define PBR_FILTER_DST_IP (1 << 1) | ||
#define PBR_FILTER_SRC_PORT (1 << 2) | ||
#define PBR_FILTER_DST_PORT (1 << 3) | ||
#define PBR_FILTER_FWMARK (1 << 4) | ||
#define PBR_FILTER_PROTO (1 << 5) | ||
#define PBR_FILTER_SRC_PORT_RANGE (1 << 6) | ||
#define PBR_FILTER_DST_PORT_RANGE (1 << 7) | ||
#define PBR_FILTER_DSFIELD (1 << 8) | ||
#define PBR_FILTER_IP_PROTOCOL (1 << 9) | ||
uint32_t filter_bm; /* not encoded by zapi */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we may need to encode these bits - how can we tell the difference between "not present" and "value is zero" otherwise? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, can you explain a little more in depth what you mean? The comment was only changed in the original MR to be on one line instead of 2. I have reverted it per a ci:cd warning. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see anything related to the issues that Paul and I asked about earlier - the encoding issues? |
||
#define PBR_FILTER_SRC_IP (1 << 0) | ||
#define PBR_FILTER_DST_IP (1 << 1) | ||
#define PBR_FILTER_SRC_PORT (1 << 2) | ||
#define PBR_FILTER_DST_PORT (1 << 3) | ||
#define PBR_FILTER_FWMARK (1 << 4) | ||
#define PBR_FILTER_PROTO (1 << 5) | ||
#define PBR_FILTER_SRC_PORT_RANGE (1 << 6) | ||
#define PBR_FILTER_DST_PORT_RANGE (1 << 7) | ||
#define PBR_FILTER_DSFIELD (1 << 8) | ||
#define PBR_FILTER_IP_PROTOCOL (1 << 9) | ||
#define PBR_FILTER_PCP (1 << 10) | ||
#define PBR_FILTER_VLAN_FLAGS (1 << 11) | ||
#define PBR_FILTER_VLAN_ID (1 << 12) | ||
|
||
#define PBR_DSFIELD_DSCP (0xfc) /* Upper 6 bits of DS field: DSCP */ | ||
#define PBR_DSFIELD_ECN (0x03) /* Lower 2 bits of DS field: BCN */ | ||
#define PBR_PCP (0x07) /* 3-bit value 0..7 for prioritization*/ | ||
|
||
/* Source and Destination IP address with masks. */ | ||
/* Source and Destination IP address with masks */ | ||
struct prefix src_ip; | ||
struct prefix dst_ip; | ||
|
||
/* Source and Destination higher-layer (TCP/UDP) port numbers. */ | ||
/* Source and Destination higher-layer (TCP/UDP) port numbers */ | ||
uint16_t src_port; | ||
uint16_t dst_port; | ||
|
||
/* Filter by VLAN and prioritization */ | ||
uint8_t pcp; | ||
uint16_t vlan_id; | ||
uint16_t vlan_flags; | ||
|
||
/* Filter by Differentiated Services field */ | ||
uint8_t dsfield; /* DSCP (6 bits) & ECN (2 bits) */ | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,8 @@ | |
* PBR-map Code | ||
* Copyright (C) 2018 Cumulus Networks, Inc. | ||
* Donald Sharp | ||
* Portions: | ||
* Copyright (c) 2021 The MITRE Corporation. | ||
*/ | ||
#include <zebra.h> | ||
|
||
|
@@ -101,6 +103,24 @@ static bool pbrms_is_installed(const struct pbr_map_sequence *pbrms, | |
return false; | ||
} | ||
|
||
void pbr_set_match_clause_for_pcp(struct pbr_map_sequence *pbrms, uint8_t pcp) | ||
{ | ||
if (pbrms) { | ||
pbrms->match_pcp = pcp; | ||
pbr_map_check(pbrms, true); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How does this work for matching PCP==0 ? Unless I missed something in the code, there is no use of a separate flag to indicate that PCP should be matched vs. ignored. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe you're right and that currently match pcp zero is simply ignored since there is a check in pbr_vty.c to see if it is non-zero. My initial thought is to set the default value to 8, rather than 0, in the pbrms_get and then handle 8 as a special ignore case and allow 0 as a match case. However, this will be difficult to test since, again per Eli, the default Linux kernel provider does not support matching PCPs, so actually testing this case differential may be difficult. Might be good to have a quick meeting to discuss if you have any availability? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think your proposal could work. It would mean that the check for "are we matching" is something like (pcp != 8) and then the value to match against is (pcp & 7). Another way might be to set the "8" bit for every match and unset for no match. Then the "are we matching check" (e.g., in zapi_msg.c) remains (pcp != 0) and the value to match is (pcp & 7). I don't have a strong opinion either way - please pick whichever seems clearer to you. |
||
} | ||
} | ||
|
||
void pbr_set_match_clause_for_vlan(struct pbr_map_sequence *pbrms, | ||
uint16_t vlan_id, uint16_t vlan_flags) | ||
{ | ||
if (pbrms) { | ||
pbrms->match_vlan_id = vlan_id; | ||
pbrms->match_vlan_flags = vlan_flags; | ||
pbr_map_check(pbrms, true); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same concern as above for PCP: How does the code distinguish between "match VLAN_ID==0" and "ignore VLAN_ID" ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this case, VLAN_ID should only be a value between 1-4094 (see https://datatracker.ietf.org/doc/html/rfc5517). ID 0 is reserved, and handled by the untagged_0 match, so a value of zero is always ignored unless you do match There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks - it's a good explanation and I agree. |
||
} | ||
} | ||
|
||
/* If any sequence is installed on the interface, assume installed */ | ||
static bool | ||
pbr_map_interface_is_installed(const struct pbr_map *pbrm, | ||
|
@@ -486,9 +506,9 @@ uint8_t pbr_map_decode_dscp_enum(const char *name) | |
|
||
struct pbr_map_sequence *pbrms_get(const char *name, uint32_t seqno) | ||
{ | ||
struct pbr_map *pbrm; | ||
struct pbr_map_sequence *pbrms; | ||
struct listnode *node; | ||
struct pbr_map *pbrm = NULL; | ||
struct pbr_map_sequence *pbrms = NULL; | ||
struct listnode *node = NULL; | ||
|
||
pbrm = pbrm_find(name); | ||
if (!pbrm) { | ||
|
@@ -526,6 +546,10 @@ struct pbr_map_sequence *pbrms_get(const char *name, uint32_t seqno) | |
pbrms->ruleno = pbr_nht_get_next_rule(seqno); | ||
pbrms->parent = pbrm; | ||
|
||
pbrms->match_vlan_id = 0; | ||
pbrms->match_vlan_flags = 0; | ||
pbrms->match_pcp = PBR_MAP_IGNORE_PCP; | ||
|
||
pbrms->action_vlan_id = 0; | ||
pbrms->action_vlan_flags = 0; | ||
pbrms->action_pcp = 0; | ||
|
@@ -594,10 +618,11 @@ 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 | ||
&& !pbrms->action_vlan_id && !pbrms->action_vlan_flags | ||
&& !pbrms->action_pcp | ||
&& pbrms->action_queue_id == PBR_MAP_UNDEFINED_QUEUE_ID) | ||
if (!pbrms->src && !pbrms->dst && !pbrms->mark && !pbrms->dsfield && | ||
!pbrms->match_pcp && !pbrms->action_pcp && !pbrms->match_vlan_id && | ||
!pbrms->match_vlan_flags && !pbrms->action_vlan_id && | ||
!pbrms->action_vlan_flags && | ||
pbrms->action_queue_id == PBR_MAP_UNDEFINED_QUEUE_ID) | ||
pbrms->reason |= PBR_MAP_INVALID_EMPTY; | ||
} | ||
|
||
|
@@ -734,7 +759,6 @@ void pbr_map_policy_delete(struct pbr_map *pbrm, struct pbr_map_interface *pmi) | |
struct pbr_map_sequence *pbrms; | ||
bool sent = false; | ||
|
||
|
||
for (ALL_LIST_ELEMENTS_RO(pbrm->seqnumbers, node, pbrms)) | ||
if (pbr_send_pbr_map(pbrms, pmi, false, true)) | ||
sent = true; /* rule removal sent to zebra */ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a duplicated line