]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: add 3 fields to ipset_entry : src,dst port, and proto
authorPhilippe Guibert <philippe.guibert@6wind.com>
Fri, 30 Mar 2018 11:01:39 +0000 (13:01 +0200)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Thu, 31 May 2018 15:44:39 +0000 (17:44 +0200)
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>
lib/pbr.h
zebra/zapi_msg.c
zebra/zebra_pbr.c
zebra/zebra_pbr.h

index b49cb562a1b520daff9f01b3a06fe55622e207b0..401cfb08133dcfa2c9be994b5533fd7580f940dc 100644 (file)
--- a/lib/pbr.h
+++ b/lib/pbr.h
 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;
index 41cd1438d3e2f43d12480bd9411f5eff8e76f8ed..dbf1f96b18a69f31acbfac408bc957789d68656d 100644 (file)
@@ -2887,11 +2887,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(
index 3dca072dc1c3ac5e48c46b9b69313262075c9a32..0a6954bc76c04ff48c224dfb8cac540708b66967 100644 (file)
@@ -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;
 }
 
@@ -668,6 +687,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)
 {
@@ -681,25 +721,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);
 
index 5d2e4a08e1b975066fde2e84eb0eeee3a3e5ba27..ea152355596092aa6832f1b9e5b9ab2f830771f4 100644 (file)
@@ -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;