]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: handle entry pointfs for ipset creation/destruction
authorPhilippe Guibert <philippe.guibert@6wind.com>
Wed, 7 Mar 2018 11:54:16 +0000 (12:54 +0100)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 16 Apr 2018 12:40:16 +0000 (14:40 +0200)
IPset and IPset entries structures are introduced. Those entries reflect
the ipset structures and ipset hash sets that will be created on the
kernel.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
lib/zclient.h
zebra/zebra_ns.c
zebra/zebra_ns.h
zebra/zebra_pbr.c
zebra/zebra_pbr.h

index e85eac73fb322b57b020f4693ea02047142d2074..a77b1c1f9495bc3555d05bdbbdc8666b8402b8b6 100644 (file)
  */
 #define ZAPI_TCP_PATHNAME             "@tcp"
 
+/* IPset size name stands for the name of the ipset entry
+ * that can be created by using some zapi interfaces
+ */
+#define ZEBRA_IPSET_NAME_SIZE   32
+
 extern struct sockaddr_storage zclient_addr;
 extern socklen_t zclient_addr_len;
 
@@ -367,6 +372,13 @@ enum zapi_route_notify_owner {
        ZAPI_ROUTE_REMOVE_FAIL,
 };
 
+enum ipset_type {
+       IPSET_NET_NET = 1,
+       IPSET_NET_PORT_NET,
+       IPSET_NET_PORT,
+       IPSET_NET
+};
+
 enum zapi_rule_notify_owner {
        ZAPI_RULE_FAIL_INSTALL,
        ZAPI_RULE_INSTALLED,
index 52cf4351bc43374b615545315defffc2759cacb9..f2a459cbb5d195a50c933b4ff4a5bf90de8c08ad 100644 (file)
@@ -140,6 +140,14 @@ int zebra_ns_enable(ns_id_t ns_id, void **info)
                hash_create_size(8, zebra_pbr_rules_hash_key,
                                 zebra_pbr_rules_hash_equal, "Rules Hash");
 
+       zns->ipset_hash =
+               hash_create_size(8, zebra_pbr_ipset_hash_key,
+                                zebra_pbr_ipset_hash_equal, "IPset Hash");
+
+       zns->ipset_entry_hash =
+               hash_create_size(8, zebra_pbr_ipset_entry_hash_key,
+                                zebra_pbr_ipset_entry_hash_equal,
+                                "IPset Hash Entry");
 #if defined(HAVE_RTADV)
        rtadv_init(zns);
 #endif
@@ -248,6 +256,12 @@ int zebra_ns_disable(ns_id_t ns_id, void **info)
 
        hash_clean(zns->rules_hash, zebra_pbr_rules_free);
        hash_free(zns->rules_hash);
+       hash_clean(zns->ipset_hash, zebra_pbr_ipset_free);
+       hash_free(zns->ipset_hash);
+       hash_clean(zns->ipset_entry_hash,
+                  zebra_pbr_ipset_entry_free),
+       hash_free(zns->ipset_entry_hash);
+
        while (!RB_EMPTY(zebra_ns_table_head, &zns->ns_tables)) {
                znst = RB_ROOT(zebra_ns_table_head, &zns->ns_tables);
 
index 66b73148d2111f283943518ecc01d2bbfb691662..c3701010533364591f415ef0512169f875f17293 100644 (file)
@@ -73,6 +73,10 @@ struct zebra_ns {
 
        struct hash *rules_hash;
 
+       struct hash *ipset_hash;
+
+       struct hash *ipset_entry_hash;
+
        /* Back pointer */
        struct ns *ns;
 };
index 4b931688468c6b1947eb8efdb12b1f45b3ccaf01..1855b543719dbef1a502b5bad5fa86b90b97a9c2 100644 (file)
@@ -129,6 +129,81 @@ static struct zebra_pbr_rule *pbr_rule_lookup_unique(struct zebra_ns *zns,
        return pul.rule;
 }
 
+void zebra_pbr_ipset_free(void *arg)
+{
+       struct zebra_pbr_ipset *ipset;
+
+       ipset = (struct zebra_pbr_ipset *)arg;
+
+       XFREE(MTYPE_TMP, ipset);
+}
+
+uint32_t zebra_pbr_ipset_hash_key(void *arg)
+{
+       struct zebra_pbr_ipset *ipset = (struct zebra_pbr_ipset *)arg;
+       uint32_t *pnt = (uint32_t *)ipset->ipset_name;
+
+       return jhash2(pnt, ZEBRA_IPSET_NAME_SIZE, 0x63ab42de);
+}
+
+int zebra_pbr_ipset_hash_equal(const void *arg1, const void *arg2)
+{
+       const struct zebra_pbr_ipset *r1, *r2;
+
+       r1 = (const struct zebra_pbr_ipset *)arg1;
+       r2 = (const struct zebra_pbr_ipset *)arg2;
+
+       if (r1->type != r2->type)
+               return 0;
+       if (r1->unique != r2->unique)
+               return 0;
+       if (strncmp(r1->ipset_name, r2->ipset_name,
+                   ZEBRA_IPSET_NAME_SIZE))
+               return 0;
+       return 1;
+}
+
+void zebra_pbr_ipset_entry_free(void *arg)
+{
+       struct zebra_pbr_ipset_entry *ipset;
+
+       ipset = (struct zebra_pbr_ipset_entry *)arg;
+
+       XFREE(MTYPE_TMP, ipset);
+}
+
+uint32_t zebra_pbr_ipset_entry_hash_key(void *arg)
+{
+       struct zebra_pbr_ipset_entry *ipset;
+       uint32_t key;
+
+       ipset = (struct zebra_pbr_ipset_entry *)arg;
+       key = prefix_hash_key(&ipset->src);
+       key = jhash_1word(ipset->unique, key);
+       key = jhash_1word(prefix_hash_key(&ipset->dst), key);
+
+       return key;
+}
+
+int zebra_pbr_ipset_entry_hash_equal(const void *arg1, const void *arg2)
+{
+       const struct zebra_pbr_ipset_entry *r1, *r2;
+
+       r1 = (const struct zebra_pbr_ipset_entry *)arg1;
+       r2 = (const struct zebra_pbr_ipset_entry *)arg2;
+
+       if (r1->unique != r2->unique)
+               return 0;
+
+       if (!prefix_same(&r1->src, &r2->src))
+               return 0;
+
+       if (!prefix_same(&r1->dst, &r2->dst))
+               return 0;
+
+       return 1;
+}
+
 static void *pbr_rule_alloc_intern(void *arg)
 {
        struct zebra_pbr_rule *zpr;
@@ -194,6 +269,89 @@ void zebra_pbr_client_close_cleanup(int sock)
        hash_iterate(zns->rules_hash, zebra_pbr_cleanup_rules, &sock);
 }
 
+static void *pbr_ipset_alloc_intern(void *arg)
+{
+       struct zebra_pbr_ipset *zpi;
+       struct zebra_pbr_ipset *new;
+
+       zpi = (struct zebra_pbr_ipset *)arg;
+
+       new = XCALLOC(MTYPE_TMP, sizeof(struct zebra_pbr_ipset));
+
+       memcpy(new, zpi, sizeof(*zpi));
+
+       return new;
+}
+
+void zebra_pbr_create_ipset(struct zebra_ns *zns,
+                           struct zebra_pbr_ipset *ipset)
+{
+       (void)hash_get(zns->ipset_hash, ipset, pbr_ipset_alloc_intern);
+       /* TODO:
+        * - Netlink call
+        */
+}
+
+void zebra_pbr_destroy_ipset(struct zebra_ns *zns,
+                            struct zebra_pbr_ipset *ipset)
+{
+       struct zebra_pbr_ipset *lookup;
+
+       lookup = hash_lookup(zns->ipset_hash, ipset);
+       /* TODO:
+        * - Netlink destroy from kernel
+        * - ?? destroy ipset entries before
+        */
+       if (lookup)
+               XFREE(MTYPE_TMP, lookup);
+       else
+               zlog_warn("%s: IPSet being deleted we know nothing about",
+                         __PRETTY_FUNCTION__);
+}
+
+static void *pbr_ipset_entry_alloc_intern(void *arg)
+{
+       struct zebra_pbr_ipset_entry *zpi;
+       struct zebra_pbr_ipset_entry *new;
+
+       zpi = (struct zebra_pbr_ipset_entry *)arg;
+
+       new = XCALLOC(MTYPE_TMP, sizeof(struct zebra_pbr_ipset_entry));
+
+       memcpy(new, zpi, sizeof(*zpi));
+
+       return new;
+}
+
+void zebra_pbr_add_ipset_entry(struct zebra_ns *zns,
+                              struct zebra_pbr_ipset_entry *ipset)
+{
+       (void)hash_get(zns->ipset_entry_hash, ipset,
+                      pbr_ipset_entry_alloc_intern);
+       /* TODO:
+        * - attach to ipset list
+        * - Netlink add to kernel
+        */
+}
+
+void zebra_pbr_del_ipset_entry(struct zebra_ns *zns,
+                              struct zebra_pbr_ipset_entry *ipset)
+{
+       struct zebra_pbr_ipset_entry *lookup;
+
+       lookup = hash_lookup(zns->ipset_hash, ipset);
+       /* TODO:
+        * - Netlink destroy
+        * - detach from ipset list
+        * - ?? if no more entres, delete ipset
+        */
+       if (lookup)
+               XFREE(MTYPE_TMP, lookup);
+       else
+               zlog_warn("%s: IPSet being deleted we know nothing about",
+                         __PRETTY_FUNCTION__);
+}
+
 /*
  * Handle success or failure of rule (un)install in the kernel.
  */
index f910d8e742b8555eae08dd359daa4c3aa26b8099..31e20a3078dac5da77b0ab8d4c989453ad8bd80c 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "rt.h"
 
+
 /*
  * A PBR filter
  *
@@ -99,8 +100,60 @@ struct zebra_pbr_rule {
        struct zebra_pbr_action action;
 };
 
+
+/*
+ * An IPSet Entry Filter
+ *
+ * This is a filter mapped on ipset entries
+ */
+struct zebra_pbr_ipset {
+       /*
+        * Originating zclient sock fd, so we can know who to send
+        * back to.
+        */
+       int sock;
+
+       uint32_t unique;
+
+       /* type is encoded as uint32_t
+        * but value is an enum ipset_type
+        */
+       uint32_t type;
+       char ipset_name[ZEBRA_IPSET_NAME_SIZE];
+};
+
+/*
+ * An IPSet Entry Filter
+ *
+ * This is a filter mapped on ipset entries
+ */
+struct zebra_pbr_ipset_entry {
+       /*
+        * Originating zclient sock fd, so we can know who to send
+        * back to.
+        */
+       int sock;
+
+       uint32_t unique;
+
+       struct prefix src;
+       struct prefix dst;
+
+       uint32_t filter_bm;
+
+       struct zebra_pbr_ipset *backpointer;
+};
+
 void zebra_pbr_add_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule);
 void zebra_pbr_del_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule);
+void zebra_pbr_create_ipset(struct zebra_ns *zns,
+                           struct zebra_pbr_ipset *ipset);
+void zebra_pbr_destroy_ipset(struct zebra_ns *zns,
+                            struct zebra_pbr_ipset *ipset);
+void zebra_pbr_add_ipset_entry(struct zebra_ns *zns,
+                              struct zebra_pbr_ipset_entry *ipset);
+void zebra_pbr_del_ipset_entry(struct zebra_ns *zns,
+                              struct zebra_pbr_ipset_entry *ipset);
 
 /*
  * Install specified rule for a specific interface.
@@ -138,4 +191,12 @@ extern void zebra_pbr_rules_free(void *arg);
 extern uint32_t zebra_pbr_rules_hash_key(void *arg);
 extern int zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2);
 
+extern void zebra_pbr_ipset_free(void *arg);
+extern uint32_t zebra_pbr_ipset_hash_key(void *arg);
+extern int zebra_pbr_ipset_hash_equal(const void *arg1, const void *arg2);
+
+extern void zebra_pbr_ipset_entry_free(void *arg);
+extern uint32_t zebra_pbr_ipset_entry_hash_key(void *arg);
+extern int zebra_pbr_ipset_entry_hash_equal(const void *arg1, const void *arg2);
+
 #endif /* _ZEBRA_PBR_H */