mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-16 08:32:45 +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 *src_port;
|
||||||
struct bgp_pbr_range_port *dst_port;
|
struct bgp_pbr_range_port *dst_port;
|
||||||
struct bgp_pbr_val_mask *tcp_flags;
|
struct bgp_pbr_val_mask *tcp_flags;
|
||||||
|
struct bgp_pbr_val_mask *dscp;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* this structure is used to contain OR instructions
|
/* 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 src/dst => drop
|
||||||
* - combination srcport + @IP
|
* - 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 (api->match_protocol_num > 1) {
|
||||||
if (BGP_DEBUG(pbr, PBR))
|
if (BGP_DEBUG(pbr, PBR))
|
||||||
zlog_debug("BGP: match protocol operations:"
|
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.");
|
"too complex. ignoring.");
|
||||||
return 0;
|
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
|
/* no combinations with both src_port and dst_port
|
||||||
* or port with 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->pkt_len_max, key);
|
||||||
key = jhash_1word(pbm->tcp_flags, key);
|
key = jhash_1word(pbm->tcp_flags, key);
|
||||||
key = jhash_1word(pbm->tcp_mask_flags, key);
|
key = jhash_1word(pbm->tcp_mask_flags, key);
|
||||||
|
key = jhash_1word(pbm->dscp_value, key);
|
||||||
return jhash_1word(pbm->type, 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)
|
if (r1->tcp_mask_flags != r2->tcp_mask_flags)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (r1->dscp_value != r2->dscp_value)
|
||||||
|
return 0;
|
||||||
return 1;
|
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_flags = bpf->tcp_flags->val;
|
||||||
temp.tcp_mask_flags = bpf->tcp_flags->mask;
|
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 (bpf->src == NULL || bpf->dst == NULL) {
|
||||||
if (temp.flags & (MATCH_PORT_DST_SET | MATCH_PORT_SRC_SET))
|
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->val,
|
||||||
bpf->tcp_flags->mask);
|
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",
|
zlog_info("BGP: adding FS PBR from %s to %s, %s %s",
|
||||||
bpf->src == NULL ? "<all>" :
|
bpf->src == NULL ? "<all>" :
|
||||||
prefix2str(bpf->src, bufsrc, sizeof(bufsrc)),
|
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_flags = bpf->tcp_flags->val;
|
||||||
temp.tcp_mask_flags = bpf->tcp_flags->mask;
|
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;
|
temp.action = bpa;
|
||||||
bpm = hash_get(bgp->pbr_match_hash, &temp,
|
bpm = hash_get(bgp->pbr_match_hash, &temp,
|
||||||
bgp_pbr_match_alloc_intern);
|
bgp_pbr_match_alloc_intern);
|
||||||
@ -1805,6 +1832,11 @@ static void bgp_pbr_handle_entry(struct bgp *bgp,
|
|||||||
&pkt_len);
|
&pkt_len);
|
||||||
bpf.pkt_len = &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.vrf_id = api->vrf_id;
|
||||||
bpf.src = src;
|
bpf.src = src;
|
||||||
bpf.dst = dst;
|
bpf.dst = dst;
|
||||||
|
@ -184,6 +184,7 @@ struct bgp_pbr_match {
|
|||||||
uint16_t pkt_len_max;
|
uint16_t pkt_len_max;
|
||||||
uint16_t tcp_flags;
|
uint16_t tcp_flags;
|
||||||
uint16_t tcp_mask_flags;
|
uint16_t tcp_mask_flags;
|
||||||
|
uint8_t dscp_value;
|
||||||
|
|
||||||
vrf_id_t vrf_id;
|
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->pkt_len_max);
|
||||||
stream_putw(s, pbm->tcp_flags);
|
stream_putw(s, pbm->tcp_flags);
|
||||||
stream_putw(s, pbm->tcp_mask_flags);
|
stream_putw(s, pbm->tcp_mask_flags);
|
||||||
|
stream_putc(s, pbm->dscp_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BGP has established connection with Zebra. */
|
/* BGP has established connection with Zebra. */
|
||||||
|
@ -112,6 +112,8 @@ struct pbr_rule {
|
|||||||
#define MATCH_PORT_DST_SET (1 << 3)
|
#define MATCH_PORT_DST_SET (1 << 3)
|
||||||
#define MATCH_PORT_SRC_RANGE_SET (1 << 4)
|
#define MATCH_PORT_SRC_RANGE_SET (1 << 4)
|
||||||
#define MATCH_PORT_DST_RANGE_SET (1 << 5)
|
#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,
|
extern int zapi_pbr_rule_encode(uint8_t cmd, struct stream *s,
|
||||||
struct pbr_rule *zrule);
|
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.pkt_len_max);
|
||||||
STREAM_GETW(s, zpi.tcp_flags);
|
STREAM_GETW(s, zpi.tcp_flags);
|
||||||
STREAM_GETW(s, zpi.tcp_mask_flags);
|
STREAM_GETW(s, zpi.tcp_mask_flags);
|
||||||
|
STREAM_GETC(s, zpi.dscp_value);
|
||||||
STREAM_GETL(s, zpi.nb_interface);
|
STREAM_GETL(s, zpi.nb_interface);
|
||||||
zebra_pbr_iptable_update_interfacelist(s, &zpi);
|
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->pkt_len_max, key);
|
||||||
key = jhash_1word(iptable->tcp_flags, key);
|
key = jhash_1word(iptable->tcp_flags, key);
|
||||||
key = jhash_1word(iptable->tcp_mask_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,
|
return jhash_3words(iptable->filter_bm, iptable->type,
|
||||||
iptable->unique, key);
|
iptable->unique, key);
|
||||||
}
|
}
|
||||||
@ -407,6 +408,8 @@ int zebra_pbr_iptable_hash_equal(const void *arg1, const void *arg2)
|
|||||||
return 0;
|
return 0;
|
||||||
if (r1->tcp_mask_flags != r2->tcp_mask_flags)
|
if (r1->tcp_mask_flags != r2->tcp_mask_flags)
|
||||||
return 0;
|
return 0;
|
||||||
|
if (r1->dscp_value != r2->dscp_value)
|
||||||
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,6 +137,7 @@ struct zebra_pbr_iptable {
|
|||||||
uint16_t pkt_len_max;
|
uint16_t pkt_len_max;
|
||||||
uint16_t tcp_flags;
|
uint16_t tcp_flags;
|
||||||
uint16_t tcp_mask_flags;
|
uint16_t tcp_mask_flags;
|
||||||
|
uint8_t dscp_value;
|
||||||
|
|
||||||
uint32_t nb_interface;
|
uint32_t nb_interface;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user