summaryrefslogtreecommitdiffstats
path: root/zebra/zebra_pbr.c
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2018-03-30 13:01:39 +0200
committerPhilippe Guibert <philippe.guibert@6wind.com>2018-05-25 15:49:38 +0200
commit25d760c5518ab49a7fc1e9812112a4f529d8630e (patch)
tree3eaad408c646823a4a832c57837cb783eb34e4f6 /zebra/zebra_pbr.c
parentzebra: pbr vty show command for ipset and iptables (diff)
downloadfrr-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.c66
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);