diff options
author | Philippe Guibert <philippe.guibert@6wind.com> | 2018-03-30 13:01:39 +0200 |
---|---|---|
committer | Philippe Guibert <philippe.guibert@6wind.com> | 2018-05-25 15:49:38 +0200 |
commit | 25d760c5518ab49a7fc1e9812112a4f529d8630e (patch) | |
tree | 3eaad408c646823a4a832c57837cb783eb34e4f6 | |
parent | zebra: pbr vty show command for ipset and iptables (diff) | |
download | frr-25d760c5518ab49a7fc1e9812112a4f529d8630e.tar.xz frr-25d760c5518ab49a7fc1e9812112a4f529d8630e.zip |
zebra: add 3 fields to ipset_entry : src,dst port, and proto
Those 3 fields are read and written between zebra and bgpd.
This permits extending the ipset_entry structure.
Combinatories will be possible:
- filtering with one of the src/dst port.
- filtering with one of the range src/ range dst port
usage of src or dst is exclusive in a FS entry.
- filtering a port or a port range based on either src or dst port.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
-rw-r--r-- | lib/pbr.h | 13 | ||||
-rw-r--r-- | zebra/zapi_msg.c | 15 | ||||
-rw-r--r-- | zebra/zebra_pbr.c | 66 | ||||
-rw-r--r-- | zebra/zebra_pbr.h | 7 |
4 files changed, 94 insertions, 7 deletions
@@ -31,11 +31,14 @@ 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_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) /* Source and Destination IP address with masks. */ struct prefix src_ip; diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index ae6ccf9f5..c721ddd0d 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -2886,11 +2886,26 @@ static inline void zread_ipset_entry(ZAPI_HANDLER_ARGS) STREAM_GETC(s, zpi.dst.prefixlen); STREAM_GET(&zpi.dst.u.prefix, s, prefix_blen(&zpi.dst)); + STREAM_GETW(s, zpi.src_port_min); + STREAM_GETW(s, zpi.src_port_max); + STREAM_GETW(s, zpi.dst_port_min); + STREAM_GETW(s, zpi.dst_port_max); + STREAM_GETC(s, zpi.proto); if (!is_default_prefix(&zpi.src)) zpi.filter_bm |= PBR_FILTER_SRC_IP; if (!is_default_prefix(&zpi.dst)) zpi.filter_bm |= PBR_FILTER_DST_IP; + if (zpi.dst_port_min != 0) + zpi.filter_bm |= PBR_FILTER_DST_PORT; + if (zpi.src_port_min != 0) + zpi.filter_bm |= PBR_FILTER_SRC_PORT; + if (zpi.dst_port_max != 0) + zpi.filter_bm |= PBR_FILTER_DST_PORT_RANGE; + if (zpi.src_port_max != 0) + zpi.filter_bm |= PBR_FILTER_SRC_PORT_RANGE; + if (zpi.proto != 0) + zpi.filter_bm |= PBR_FILTER_PROTO; /* calculate backpointer */ zpi.backpointer = zebra_pbr_lookup_ipset_pername( diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c index 3473c5ea4..863ee8a67 100644 --- a/zebra/zebra_pbr.c +++ b/zebra/zebra_pbr.c @@ -201,6 +201,11 @@ uint32_t zebra_pbr_ipset_entry_hash_key(void *arg) key = prefix_hash_key(&ipset->src); key = jhash_1word(ipset->unique, key); key = jhash_1word(prefix_hash_key(&ipset->dst), key); + key = jhash(&ipset->dst_port_min, 2, key); + key = jhash(&ipset->dst_port_max, 2, key); + key = jhash(&ipset->src_port_min, 2, key); + key = jhash(&ipset->src_port_max, 2, key); + key = jhash(&ipset->proto, 1, key); return key; } @@ -221,6 +226,20 @@ int zebra_pbr_ipset_entry_hash_equal(const void *arg1, const void *arg2) if (!prefix_same(&r1->dst, &r2->dst)) return 0; + if (r1->src_port_min != r2->src_port_min) + return 0; + + if (r1->src_port_max != r2->src_port_max) + return 0; + + if (r1->dst_port_min != r2->dst_port_min) + return 0; + + if (r1->dst_port_max != r2->dst_port_max) + return 0; + + if (r1->proto != r2->proto) + return 0; return 1; } @@ -670,6 +689,27 @@ static const char *zebra_pbr_prefix2str(union prefixconstptr pu, return prefix2str(pu, str, size); } +static void zebra_pbr_display_port(struct vty *vty, uint32_t filter_bm, + uint16_t port_min, uint16_t port_max, + uint8_t proto) +{ + if (!(filter_bm & PBR_FILTER_PROTO)) { + if (port_max) + vty_out(vty, ":udp/tcp:%d-%d", + port_min, port_max); + else + vty_out(vty, ":udp/tcp:%d", + port_min); + } else { + if (port_max) + vty_out(vty, ":proto %d:%d-%d", + proto, port_min, port_max); + else + vty_out(vty, ":proto %d:%d", + proto, port_min); + } +} + static int zebra_pbr_show_ipset_entry_walkcb(struct hash_backet *backet, void *arg) { @@ -683,25 +723,47 @@ static int zebra_pbr_show_ipset_entry_walkcb(struct hash_backet *backet, if (zpie->backpointer != zpi) return HASHWALK_CONTINUE; - if (zpi->type == IPSET_NET_NET) { + if ((zpi->type == IPSET_NET_NET) || + (zpi->type == IPSET_NET_PORT_NET)) { char buf[PREFIX_STRLEN]; zebra_pbr_prefix2str(&(zpie->src), buf, sizeof(buf)); vty_out(vty, "\tfrom %s", buf); + if (zpie->filter_bm & PBR_FILTER_SRC_PORT) + zebra_pbr_display_port(vty, zpie->filter_bm, + zpie->src_port_min, + zpie->src_port_max, + zpie->proto); vty_out(vty, " to "); zebra_pbr_prefix2str(&(zpie->dst), buf, sizeof(buf)); vty_out(vty, "%s", buf); - } else if (zpi->type == IPSET_NET) { + if (zpie->filter_bm & PBR_FILTER_DST_PORT) + zebra_pbr_display_port(vty, zpie->filter_bm, + zpie->dst_port_min, + zpie->dst_port_max, + zpie->proto); + } else if ((zpi->type == IPSET_NET) || + (zpi->type == IPSET_NET_PORT)) { char buf[PREFIX_STRLEN]; if (zpie->filter_bm & PBR_FILTER_SRC_IP) { zebra_pbr_prefix2str(&(zpie->src), buf, sizeof(buf)); vty_out(vty, "\tfrom %s", buf); } + if (zpie->filter_bm & PBR_FILTER_SRC_PORT) + zebra_pbr_display_port(vty, zpie->filter_bm, + zpie->src_port_min, + zpie->src_port_max, + zpie->proto); if (zpie->filter_bm & PBR_FILTER_DST_IP) { zebra_pbr_prefix2str(&(zpie->dst), buf, sizeof(buf)); vty_out(vty, "\tto %s", buf); } + if (zpie->filter_bm & PBR_FILTER_DST_PORT) + zebra_pbr_display_port(vty, zpie->filter_bm, + zpie->dst_port_min, + zpie->dst_port_max, + zpie->proto); } vty_out(vty, " (%u)\n", zpie->unique); diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h index 5d2e4a08e..ea1523555 100644 --- a/zebra/zebra_pbr.h +++ b/zebra/zebra_pbr.h @@ -91,6 +91,13 @@ struct zebra_pbr_ipset_entry { struct prefix src; struct prefix dst; + uint16_t src_port_min; + uint16_t src_port_max; + uint16_t dst_port_min; + uint16_t dst_port_max; + + uint8_t proto; + uint32_t filter_bm; struct zebra_pbr_ipset *backpointer; |