summaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--lib/pbr.h13
-rw-r--r--zebra/zapi_msg.c15
-rw-r--r--zebra/zebra_pbr.c66
-rw-r--r--zebra/zebra_pbr.h7
4 files changed, 94 insertions, 7 deletions
diff --git a/lib/pbr.h b/lib/pbr.h
index b49cb562a..401cfb081 100644
--- a/lib/pbr.h
+++ b/lib/pbr.h
@@ -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;