mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-16 04:50:29 +00:00
*: add flowspec dscp handling
Only one dscp value is accepted as filtering option. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
parent
9bba145596
commit
4977bd6c19
@ -206,6 +206,7 @@ struct bgp_pbr_filter {
|
||||
struct bgp_pbr_range_port *src_port;
|
||||
struct bgp_pbr_range_port *dst_port;
|
||||
struct bgp_pbr_val_mask *tcp_flags;
|
||||
struct bgp_pbr_val_mask *dscp;
|
||||
};
|
||||
|
||||
/* this structure is used to contain OR instructions
|
||||
@ -394,15 +395,6 @@ static int bgp_pbr_validate_policy_route(struct bgp_pbr_entry_main *api)
|
||||
* - combination src/dst => drop
|
||||
* - combination srcport + @IP
|
||||
*/
|
||||
if (api->match_dscp_num) {
|
||||
if (BGP_DEBUG(pbr, PBR)) {
|
||||
bgp_pbr_print_policy_route(api);
|
||||
zlog_debug("BGP: some SET actions not supported by Zebra. ignoring.");
|
||||
zlog_debug("BGP: case icmp or length or dscp or tcp flags");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (api->match_protocol_num > 1) {
|
||||
if (BGP_DEBUG(pbr, PBR))
|
||||
zlog_debug("BGP: match protocol operations:"
|
||||
@ -481,6 +473,15 @@ static int bgp_pbr_validate_policy_route(struct bgp_pbr_entry_main *api)
|
||||
"too complex. ignoring.");
|
||||
return 0;
|
||||
}
|
||||
if (api->match_dscp_num > 1 ||
|
||||
!bgp_pbr_extract_enumerate(api->dscp,
|
||||
api->match_dscp_num,
|
||||
OPERATOR_UNARY_OR, NULL)) {
|
||||
if (BGP_DEBUG(pbr, PBR))
|
||||
zlog_debug("BGP: match DSCP operations:"
|
||||
"too complex. ignoring.");
|
||||
return 0;
|
||||
}
|
||||
/* no combinations with both src_port and dst_port
|
||||
* or port with src_port and dst_port
|
||||
*/
|
||||
@ -727,6 +728,7 @@ uint32_t bgp_pbr_match_hash_key(void *arg)
|
||||
key = jhash_1word(pbm->pkt_len_max, key);
|
||||
key = jhash_1word(pbm->tcp_flags, key);
|
||||
key = jhash_1word(pbm->tcp_mask_flags, key);
|
||||
key = jhash_1word(pbm->dscp_value, key);
|
||||
return jhash_1word(pbm->type, key);
|
||||
}
|
||||
|
||||
@ -761,6 +763,8 @@ int bgp_pbr_match_hash_equal(const void *arg1, const void *arg2)
|
||||
if (r1->tcp_mask_flags != r2->tcp_mask_flags)
|
||||
return 0;
|
||||
|
||||
if (r1->dscp_value != r2->dscp_value)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1235,6 +1239,13 @@ static void bgp_pbr_policyroute_remove_from_zebra_unit(struct bgp *bgp,
|
||||
temp.tcp_flags = bpf->tcp_flags->val;
|
||||
temp.tcp_mask_flags = bpf->tcp_flags->mask;
|
||||
}
|
||||
if (bpf->dscp) {
|
||||
if (bpf->dscp->mask)
|
||||
temp.flags |= MATCH_DSCP_INVERSE_SET;
|
||||
else
|
||||
temp.flags |= MATCH_DSCP_SET;
|
||||
temp.dscp_value = bpf->dscp->val;
|
||||
}
|
||||
|
||||
if (bpf->src == NULL || bpf->dst == NULL) {
|
||||
if (temp.flags & (MATCH_PORT_DST_SET | MATCH_PORT_SRC_SET))
|
||||
@ -1372,6 +1383,15 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
|
||||
bpf->tcp_flags->val,
|
||||
bpf->tcp_flags->mask);
|
||||
}
|
||||
if (bpf->dscp) {
|
||||
snprintf(buffer + remaining_len,
|
||||
sizeof(buffer)
|
||||
- remaining_len,
|
||||
"%s dscp %d",
|
||||
bpf->dscp->mask
|
||||
? "!" : "",
|
||||
bpf->dscp->val);
|
||||
}
|
||||
zlog_info("BGP: adding FS PBR from %s to %s, %s %s",
|
||||
bpf->src == NULL ? "<all>" :
|
||||
prefix2str(bpf->src, bufsrc, sizeof(bufsrc)),
|
||||
@ -1442,6 +1462,13 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
|
||||
temp.tcp_flags = bpf->tcp_flags->val;
|
||||
temp.tcp_mask_flags = bpf->tcp_flags->mask;
|
||||
}
|
||||
if (bpf->dscp) {
|
||||
if (bpf->dscp->mask)
|
||||
temp.flags |= MATCH_DSCP_INVERSE_SET;
|
||||
else
|
||||
temp.flags |= MATCH_DSCP_SET;
|
||||
temp.dscp_value = bpf->dscp->val;
|
||||
}
|
||||
temp.action = bpa;
|
||||
bpm = hash_get(bgp->pbr_match_hash, &temp,
|
||||
bgp_pbr_match_alloc_intern);
|
||||
@ -1805,6 +1832,11 @@ static void bgp_pbr_handle_entry(struct bgp *bgp,
|
||||
&pkt_len);
|
||||
bpf.pkt_len = &pkt_len;
|
||||
}
|
||||
if (api->match_dscp_num >= 1) {
|
||||
bpf.dscp_presence = true;
|
||||
bpf.dscp_value = api->dscp[0].value;
|
||||
|
||||
}
|
||||
bpf.vrf_id = api->vrf_id;
|
||||
bpf.src = src;
|
||||
bpf.dst = dst;
|
||||
|
@ -184,6 +184,7 @@ struct bgp_pbr_match {
|
||||
uint16_t pkt_len_max;
|
||||
uint16_t tcp_flags;
|
||||
uint16_t tcp_mask_flags;
|
||||
uint8_t dscp_value;
|
||||
|
||||
vrf_id_t vrf_id;
|
||||
|
||||
|
@ -2223,6 +2223,7 @@ static void bgp_encode_pbr_iptable_match(struct stream *s,
|
||||
stream_putw(s, pbm->pkt_len_max);
|
||||
stream_putw(s, pbm->tcp_flags);
|
||||
stream_putw(s, pbm->tcp_mask_flags);
|
||||
stream_putc(s, pbm->dscp_value);
|
||||
}
|
||||
|
||||
/* BGP has established connection with Zebra. */
|
||||
|
@ -112,6 +112,8 @@ struct pbr_rule {
|
||||
#define MATCH_PORT_DST_SET (1 << 3)
|
||||
#define MATCH_PORT_SRC_RANGE_SET (1 << 4)
|
||||
#define MATCH_PORT_DST_RANGE_SET (1 << 5)
|
||||
#define MATCH_DSCP_SET (1 << 6)
|
||||
#define MATCH_DSCP_INVERSE_SET (1 << 7)
|
||||
|
||||
extern int zapi_pbr_rule_encode(uint8_t cmd, struct stream *s,
|
||||
struct pbr_rule *zrule);
|
||||
|
@ -2942,6 +2942,7 @@ static inline void zread_iptable(ZAPI_HANDLER_ARGS)
|
||||
STREAM_GETW(s, zpi.pkt_len_max);
|
||||
STREAM_GETW(s, zpi.tcp_flags);
|
||||
STREAM_GETW(s, zpi.tcp_mask_flags);
|
||||
STREAM_GETC(s, zpi.dscp_value);
|
||||
STREAM_GETL(s, zpi.nb_interface);
|
||||
zebra_pbr_iptable_update_interfacelist(s, &zpi);
|
||||
|
||||
|
@ -375,6 +375,7 @@ uint32_t zebra_pbr_iptable_hash_key(void *arg)
|
||||
key = jhash_1word(iptable->pkt_len_max, key);
|
||||
key = jhash_1word(iptable->tcp_flags, key);
|
||||
key = jhash_1word(iptable->tcp_mask_flags, key);
|
||||
key = jhash_1word(iptable->dscp_value, key);
|
||||
return jhash_3words(iptable->filter_bm, iptable->type,
|
||||
iptable->unique, key);
|
||||
}
|
||||
@ -407,6 +408,8 @@ int zebra_pbr_iptable_hash_equal(const void *arg1, const void *arg2)
|
||||
return 0;
|
||||
if (r1->tcp_mask_flags != r2->tcp_mask_flags)
|
||||
return 0;
|
||||
if (r1->dscp_value != r2->dscp_value)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -137,6 +137,7 @@ struct zebra_pbr_iptable {
|
||||
uint16_t pkt_len_max;
|
||||
uint16_t tcp_flags;
|
||||
uint16_t tcp_mask_flags;
|
||||
uint8_t dscp_value;
|
||||
|
||||
uint32_t nb_interface;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user