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 /zebra/zebra_pbr.c | |
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>
Diffstat (limited to 'zebra/zebra_pbr.c')
-rw-r--r-- | zebra/zebra_pbr.c | 66 |
1 files changed, 64 insertions, 2 deletions
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); |