]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_pbr.c
Merge pull request #5789 from donaldsharp/bgp_ebgp_reason
[mirror_frr.git] / zebra / zebra_pbr.c
index e24d2e2b422914f776ff6bd677d21a36a1e7adf3..ff3907451b4808c6d274af1736d1a3ed06efaa21 100644 (file)
@@ -345,11 +345,13 @@ void zebra_pbr_iptable_free(void *arg)
        iptable = (struct zebra_pbr_iptable *)arg;
        hook_call(zebra_pbr_iptable_update, 0, iptable);
 
-       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);
+       if (iptable->interface_name_list) {
+               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);
+               }
+               list_delete(&iptable->interface_name_list);
        }
        XFREE(MTYPE_TMP, iptable);
 }
@@ -481,8 +483,10 @@ static void zebra_pbr_cleanup_ipset(struct hash_bucket *b, void *data)
        int *sock = data;
 
        if (ipset->sock == *sock) {
-               hook_call(zebra_pbr_ipset_update, 0, ipset);
-               hash_release(zrouter.ipset_hash, ipset);
+               if (hash_release(zrouter.ipset_hash, ipset))
+                       zebra_pbr_ipset_free(ipset);
+               else
+                       hook_call(zebra_pbr_ipset_update, 0, ipset);
        }
 }
 
@@ -492,8 +496,10 @@ static void zebra_pbr_cleanup_ipset_entry(struct hash_bucket *b, void *data)
        int *sock = data;
 
        if (ipset->sock == *sock) {
-               hook_call(zebra_pbr_ipset_entry_update, 0, ipset);
-               hash_release(zrouter.ipset_entry_hash, ipset);
+               if (hash_release(zrouter.ipset_entry_hash, ipset))
+                       zebra_pbr_ipset_entry_free(ipset);
+               else
+                       hook_call(zebra_pbr_ipset_entry_update, 0, ipset);
        }
 }
 
@@ -503,8 +509,10 @@ static void zebra_pbr_cleanup_iptable(struct hash_bucket *b, void *data)
        int *sock = data;
 
        if (iptable->sock == *sock) {
-               hook_call(zebra_pbr_iptable_update, 0, iptable);
-               hash_release(zrouter.iptable_hash, iptable);
+               if (hash_release(zrouter.iptable_hash, iptable))
+                       zebra_pbr_iptable_free(iptable);
+               else
+                       hook_call(zebra_pbr_iptable_update, 0, iptable);
        }
 }
 
@@ -650,12 +658,22 @@ static void *pbr_iptable_alloc_intern(void *arg)
 {
        struct zebra_pbr_iptable *zpi;
        struct zebra_pbr_iptable *new;
+       struct listnode *ln;
+       char *ifname;
 
        zpi = (struct zebra_pbr_iptable *)arg;
 
        new = XCALLOC(MTYPE_TMP, sizeof(struct zebra_pbr_iptable));
 
+       /* Deep structure copy */
        memcpy(new, zpi, sizeof(*zpi));
+       new->interface_name_list = list_new();
+
+       if (zpi->interface_name_list) {
+               for (ALL_LIST_ELEMENTS_RO(zpi->interface_name_list, ln, ifname))
+                       listnode_add(new->interface_name_list,
+                                    XSTRDUP(MTYPE_PBR_IPTABLE_IFNAME, ifname));
+       }
 
        return new;
 }
@@ -688,6 +706,7 @@ void zebra_pbr_del_iptable(struct zebra_pbr_iptable *iptable)
                        list_delete_node(iptable->interface_name_list,
                                         node);
                }
+               list_delete(&iptable->interface_name_list);
                XFREE(MTYPE_TMP, lookup);
        } else
                zlog_debug("%s: IPTable being deleted we know nothing about",