]> git.proxmox.com Git - mirror_frr.git/commitdiff
zebra: handle iptable list of interfaces
authorPhilippe Guibert <philippe.guibert@6wind.com>
Wed, 25 Apr 2018 16:34:27 +0000 (18:34 +0200)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Thu, 31 May 2018 15:44:39 +0000 (17:44 +0200)
Upon reception of an iptable_add or iptable_del, a list of interface
indexes may be passed in the zapi interface. The list is converted in
interface name so that it is ready to be passed to be programmed to the
underlying system.

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

index dbf1f96b18a69f31acbfac408bc957789d68656d..ffc0a4f6f9dbbcb257a7f3a80e5342b3ec928304 100644 (file)
@@ -2930,6 +2930,7 @@ static inline void zread_iptable(ZAPI_HANDLER_ARGS)
 
        memset(&zpi, 0, sizeof(zpi));
 
+       zpi.interface_name_list = list_new();
        zpi.sock = client->sock;
        zpi.vrf_id = zvrf->vrf->vrf_id;
        STREAM_GETL(s, zpi.unique);
@@ -2938,6 +2939,8 @@ static inline void zread_iptable(ZAPI_HANDLER_ARGS)
        STREAM_GETL(s, zpi.action);
        STREAM_GETL(s, zpi.fwmark);
        STREAM_GET(&zpi.ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
+       STREAM_GETL(s, zpi.nb_interface);
+       zebra_pbr_iptable_update_interfacelist(s, &zpi);
 
        if (hdr->command == ZEBRA_IPTABLE_ADD)
                zebra_pbr_add_iptable(zvrf->zns, &zpi);
index 0a6954bc76c04ff48c224dfb8cac540708b66967..d15aac46f3010f95e6ac33c4cd4f06969a2beaad 100644 (file)
 
 #include <jhash.h>
 #include <hash.h>
+#include <memory.h>
 
 #include "zebra/zebra_pbr.h"
 #include "zebra/rt.h"
 #include "zebra/zapi_msg.h"
+#include "zebra/zebra_memory.h"
+#include "zebra_pbr.h"
+
+/* definitions */
+DEFINE_MTYPE_STATIC(ZEBRA, PBR_IPTABLE_IFNAME, "PBR interface list")
 
 /* definitions */
 static const struct message ipset_type_msg[] = {
@@ -246,9 +252,17 @@ int zebra_pbr_ipset_entry_hash_equal(const void *arg1, const void *arg2)
 void zebra_pbr_iptable_free(void *arg)
 {
        struct zebra_pbr_iptable *iptable;
+       struct listnode *node, *nnode;
+       char *name;
 
        iptable = (struct zebra_pbr_iptable *)arg;
 
+       for (ALL_LIST_ELEMENTS(iptable->interface_name_list,
+                                       node, nnode, name)) {
+               XFREE(MTYPE_PBR_IPTABLE_IFNAME, name);
+               list_delete_node(iptable->interface_name_list,
+                                node);
+       }
        XFREE(MTYPE_TMP, iptable);
 }
 
@@ -546,16 +560,26 @@ void zebra_pbr_add_iptable(struct zebra_ns *zns,
 void zebra_pbr_del_iptable(struct zebra_ns *zns,
                           struct zebra_pbr_iptable *iptable)
 {
-       struct zebra_pbr_ipset_entry *lookup;
+       struct zebra_pbr_iptable *lookup;
 
        lookup = hash_lookup(zns->iptable_hash, iptable);
        /* TODO:
         * - call netlink layer
         * - detach from iptable list
         */
-       if (lookup)
+       if (lookup) {
+               struct listnode *node, *nnode;
+               char *name;
+
+               hash_release(zns->iptable_hash, lookup);
+               for (ALL_LIST_ELEMENTS(iptable->interface_name_list,
+                                      node, nnode, name)) {
+                       XFREE(MTYPE_PBR_IPTABLE_IFNAME, name);
+                       list_delete_node(iptable->interface_name_list,
+                                        node);
+               }
                XFREE(MTYPE_TMP, lookup);
-       else
+       else
                zlog_warn("%s: IPTable being deleted we know nothing about",
                          __PRETTY_FUNCTION__);
 }
@@ -880,3 +904,22 @@ void zebra_pbr_show_iptable(struct vty *vty)
        hash_walk(zns->iptable_hash, zebra_pbr_show_iptable_walkcb,
                  &env);
 }
+
+void zebra_pbr_iptable_update_interfacelist(struct stream *s,
+                                           struct zebra_pbr_iptable *zpi)
+{
+       uint32_t i = 0, index;
+       struct interface *ifp;
+       char *name;
+
+       for (i = 0; i < zpi->nb_interface; i++) {
+               STREAM_GETL(s, index);
+               ifp = if_lookup_by_index(index, zpi->vrf_id);
+               if (!ifp)
+                       continue;
+               name = XSTRDUP(MTYPE_PBR_IPTABLE_IFNAME, ifp->name);
+               listnode_add(zpi->interface_name_list, name);
+       }
+stream_failure:
+       return;
+}
index ea152355596092aa6832f1b9e5b9ab2f830771f4..f5a5d5d2944744e100f52bf9a70aa1a072a13d3f 100644 (file)
@@ -131,6 +131,10 @@ struct zebra_pbr_iptable {
 
        uint32_t action;
 
+       uint32_t nb_interface;
+
+       struct list *interface_name_list;
+
        char ipset_name[ZEBRA_IPSET_NAME_SIZE];
 };
 
@@ -219,5 +223,7 @@ extern int zebra_pbr_iptable_hash_equal(const void *arg1, const void *arg2);
 extern void zebra_pbr_init(void);
 extern void zebra_pbr_show_ipset_list(struct vty *vty, char *ipsetname);
 extern void zebra_pbr_show_iptable(struct vty *vty);
+extern void zebra_pbr_iptable_update_interfacelist(struct stream *s,
+                                  struct zebra_pbr_iptable *zpi);
 
 #endif /* _ZEBRA_PBR_H */