summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2018-06-21 12:29:18 +0200
committerPhilippe Guibert <philippe.guibert@6wind.com>2018-06-28 11:08:59 +0200
commit3bed23633855b8944f75ca869b0ac060ee271bb7 (patch)
treef74cd6a2f4498eec51f3b5e44c4960db220d7cab
parentda3fa38394adad5b892f74fd9009bd7cde76404c (diff)
bgpd: add an icmp flag for flowspec icmp entries
Some values for icmp type/code can not be encoded like port source or port destination. This is the case of 0 value that is authorized for icmp. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
-rw-r--r--bgpd/bgp_pbr.c43
-rw-r--r--lib/pbr.h1
2 files changed, 27 insertions, 17 deletions
diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c
index 615b5723c4..43ff78d38e 100644
--- a/bgpd/bgp_pbr.c
+++ b/bgpd/bgp_pbr.c
@@ -1310,7 +1310,9 @@ static void bgp_pbr_policyroute_remove_from_zebra_unit(struct bgp *bgp,
prefix_copy(&temp2.dst, bpf->dst);
} else
temp2.dst.family = AF_INET;
- if (src_port && src_port->min_port) {
+ if (src_port && (src_port->min_port || bpf->protocol == IPPROTO_ICMP)) {
+ if (bpf->protocol == IPPROTO_ICMP)
+ temp.flags |= MATCH_ICMP_SET;
temp.flags |= MATCH_PORT_SRC_SET;
temp2.src_port_min = src_port->min_port;
if (src_port->max_port) {
@@ -1318,7 +1320,9 @@ static void bgp_pbr_policyroute_remove_from_zebra_unit(struct bgp *bgp,
temp2.src_port_max = src_port->max_port;
}
}
- if (dst_port && dst_port->min_port) {
+ if (dst_port && (dst_port->min_port || bpf->protocol == IPPROTO_ICMP)) {
+ if (bpf->protocol == IPPROTO_ICMP)
+ temp.flags |= MATCH_ICMP_SET;
temp.flags |= MATCH_PORT_DST_SET;
temp2.dst_port_min = dst_port->min_port;
if (dst_port->max_port) {
@@ -1692,33 +1696,38 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
/* then look for bpm */
memset(&temp, 0, sizeof(temp));
- if (bpf->src == NULL || bpf->dst == NULL) {
- if ((src_port && src_port->min_port) ||
- (dst_port && dst_port->min_port))
- temp.type = IPSET_NET_PORT;
- else
- temp.type = IPSET_NET;
- } else {
- if ((src_port && src_port->min_port) ||
- (dst_port && dst_port->min_port))
- temp.type = IPSET_NET_PORT_NET;
- else
- temp.type = IPSET_NET_NET;
- }
temp.vrf_id = bpf->vrf_id;
if (bpf->src)
temp.flags |= MATCH_IP_SRC_SET;
if (bpf->dst)
temp.flags |= MATCH_IP_DST_SET;
- if (src_port && src_port->min_port)
+ if (src_port && (src_port->min_port || bpf->protocol == IPPROTO_ICMP)) {
+ if (bpf->protocol == IPPROTO_ICMP)
+ temp.flags |= MATCH_ICMP_SET;
temp.flags |= MATCH_PORT_SRC_SET;
- if (dst_port && dst_port->min_port)
+ }
+ if (dst_port && (dst_port->min_port || bpf->protocol == IPPROTO_ICMP)) {
+ if (bpf->protocol == IPPROTO_ICMP)
+ temp.flags |= MATCH_ICMP_SET;
temp.flags |= MATCH_PORT_DST_SET;
+ }
if (src_port && src_port->max_port)
temp.flags |= MATCH_PORT_SRC_RANGE_SET;
if (dst_port && dst_port->max_port)
temp.flags |= MATCH_PORT_DST_RANGE_SET;
+
+ if (bpf->src == NULL || bpf->dst == NULL) {
+ if (temp.flags & (MATCH_PORT_DST_SET | MATCH_PORT_SRC_SET))
+ temp.type = IPSET_NET_PORT;
+ else
+ temp.type = IPSET_NET;
+ } else {
+ if (temp.flags & (MATCH_PORT_DST_SET | MATCH_PORT_SRC_SET))
+ temp.type = IPSET_NET_PORT_NET;
+ else
+ temp.type = IPSET_NET_NET;
+ }
if (pkt_len) {
temp.pkt_len_min = pkt_len->min_port;
if (pkt_len->max_port)
diff --git a/lib/pbr.h b/lib/pbr.h
index f0c6285e04..90997348cf 100644
--- a/lib/pbr.h
+++ b/lib/pbr.h
@@ -116,6 +116,7 @@ struct pbr_rule {
#define MATCH_DSCP_INVERSE_SET (1 << 7)
#define MATCH_PKT_LEN_INVERSE_SET (1 << 8)
#define MATCH_FRAGMENT_INVERSE_SET (1 << 9)
+#define MATCH_ICMP_SET (1 << 10)
extern int zapi_pbr_rule_encode(uint8_t cmd, struct stream *s,
struct pbr_rule *zrule);