]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: fix release label chunk when label pool unused
authorPhilippe Guibert <philippe.guibert@6wind.com>
Wed, 27 Sep 2023 05:58:22 +0000 (07:58 +0200)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Wed, 18 Oct 2023 07:41:02 +0000 (09:41 +0200)
A label chunk is used by BGP for L3VPN or LU purposes,
by picking up labels from that chunk; but when those
labels are release, the label chunks are never released.

The below configuration sequence shows that the label
chunks are not released.

> router bgp 65500
>  bgp router-id 1.1.1.1
>  !
>  address-family ipv4 unicast
>   label vpn export auto
>   rd vpn export 55:1
>   rt vpn both 55:1
>   export vpn
>   import vpn
> [..]
>   no label vpn export auto
> [..]
> # show bgp labelpool summary
> [..]
> LabelChunks:  1
> Pending:      128
> [..]

The '128' value stands for the default label chunk size,
which is not released after unconfiguration.

Fix this by checking after each label release, that
the label chunk is still used. If not, release it.
Reset the 'next_chunksize' value to the default value.

Fixes: 955bfd984ffd ("bgpd: dynamic mpls label pool")
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
bgpd/bgp_labelpool.c

index 03987b6bbf54eb9ef3fd849b41d8638fc9b8be85..46443d9d188dac88952be86a0758c7d45f66c198 100644 (file)
@@ -494,8 +494,18 @@ void bgp_lp_release(
                                bf_release_index(chunk->allocated_map, index);
                                chunk->nfree += 1;
                                deallocated = true;
+                               break;
                        }
                        assert(deallocated);
+                       if (deallocated &&
+                           chunk->nfree == chunk->last - chunk->first + 1 &&
+                           lp_fifo_count(&lp->requests) == 0) {
+                               bgp_zebra_release_label_range(chunk->first,
+                                                             chunk->last);
+                               list_delete_node(lp->chunks, node);
+                               lp_chunk_free(chunk);
+                               lp->next_chunksize = LP_CHUNK_SIZE_MIN;
+                       }
                }
        }
 }