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
* - 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:"
"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
*/
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);
}
if (r1->tcp_mask_flags != r2->tcp_mask_flags)
return 0;
+ if (r1->dscp_value != r2->dscp_value)
+ return 0;
return 1;
}
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))
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)),
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);
&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;