]> git.proxmox.com Git - mirror_frr.git/blobdiff - ldpd/lde.c
Merge pull request #5412 from opensourcerouting/bfdd-vrf-fix
[mirror_frr.git] / ldpd / lde.c
index 5aa53fd39e01dbec2653b13dc513417b671719d1..006d27f6abb873fbd6a1afee0c001b1b8bc0af77 100644 (file)
@@ -56,7 +56,7 @@ static void            lde_map_free(void *);
 static int              lde_address_add(struct lde_nbr *, struct lde_addr *);
 static int              lde_address_del(struct lde_nbr *, struct lde_addr *);
 static void             lde_address_list_free(struct lde_nbr *);
-static void             zclient_sync_init(u_short instance);
+static void zclient_sync_init(unsigned short instance);
 static void             lde_label_list_init(void);
 static int              lde_get_label_chunk(void);
 static void             on_get_label_chunk_response(uint32_t start, uint32_t end);
@@ -520,7 +520,8 @@ lde_dispatch_parent(struct thread *thread)
                        switch (imsg.hdr.type) {
                        case IMSG_NETWORK_ADD:
                                lde_kernel_insert(&fec, kr->af, &kr->nexthop,
-                                   kr->ifindex, kr->priority,
+                                   kr->ifindex, kr->route_type,
+                                   kr->route_instance,
                                    kr->flags & F_CONNECTED, NULL);
                                break;
                        case IMSG_NETWORK_UPDATE:
@@ -747,7 +748,8 @@ lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh)
                kr.ifindex = fnh->ifindex;
                kr.local_label = fn->local_label;
                kr.remote_label = fnh->remote_label;
-               kr.priority = fnh->priority;
+               kr.route_type = fnh->route_type;
+               kr.route_instance = fnh->route_instance;
 
                lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr,
                    sizeof(kr));
@@ -761,7 +763,8 @@ lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh)
                kr.ifindex = fnh->ifindex;
                kr.local_label = fn->local_label;
                kr.remote_label = fnh->remote_label;
-               kr.priority = fnh->priority;
+               kr.route_type = fnh->route_type;
+               kr.route_instance = fnh->route_instance;
 
                lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr,
                    sizeof(kr));
@@ -798,7 +801,8 @@ lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh)
                kr.ifindex = fnh->ifindex;
                kr.local_label = fn->local_label;
                kr.remote_label = fnh->remote_label;
-               kr.priority = fnh->priority;
+               kr.route_type = fnh->route_type;
+               kr.route_instance = fnh->route_instance;
 
                lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr,
                    sizeof(kr));
@@ -812,7 +816,8 @@ lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh)
                kr.ifindex = fnh->ifindex;
                kr.local_label = fn->local_label;
                kr.remote_label = fnh->remote_label;
-               kr.priority = fnh->priority;
+               kr.route_type = fnh->route_type;
+               kr.route_instance = fnh->route_instance;
 
                lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr,
                    sizeof(kr));
@@ -1620,17 +1625,14 @@ lde_address_list_free(struct lde_nbr *ln)
 {
        struct lde_addr         *lde_addr;
 
-       while ((lde_addr = TAILQ_FIRST(&ln->addr_list)) != NULL) {
-               TAILQ_REMOVE(&ln->addr_list, lde_addr, entry);
+       while ((lde_addr = TAILQ_POP_FIRST(&ln->addr_list, entry)) != NULL)
                free(lde_addr);
-       }
 }
 
-static void
-zclient_sync_init(u_short instance)
+static void zclient_sync_init(unsigned short instance)
 {
        /* Initialize special zclient for synchronous message exchanges. */
-       zclient_sync = zclient_new_notify(master, &zclient_options_default);
+       zclient_sync = zclient_new(master, &zclient_options_default);
        zclient_sync->sock = -1;
        zclient_sync->redist_default = ZEBRA_ROUTE_LDP;
        zclient_sync->instance = instance;
@@ -1644,7 +1646,7 @@ zclient_sync_init(u_short instance)
        sock_set_nonblock(zclient_sync->sock);
 
        /* Connect to label manager */
-       while (lm_label_manager_connect(zclient_sync) != 0) {
+       while (lm_label_manager_connect(zclient_sync, 0) != 0) {
                log_warnx("Error connecting to label manager!");
                sleep(1);
        }
@@ -1656,6 +1658,19 @@ lde_del_label_chunk(void *val)
        free(val);
 }
 
+static int
+lde_release_label_chunk(uint32_t start, uint32_t end)
+{
+       int             ret;
+
+       ret = lm_release_label_chunk(zclient_sync, start, end);
+       if (ret < 0) {
+               log_warnx("Error releasing label chunk!");
+               return (-1);
+       }
+       return (0);
+}
+
 static int
 lde_get_label_chunk(void)
 {
@@ -1663,7 +1678,8 @@ lde_get_label_chunk(void)
        uint32_t         start, end;
 
        debug_labels("getting label chunk (size %u)", CHUNK_SIZE);
-       ret = lm_get_label_chunk(zclient_sync, 0, CHUNK_SIZE, &start, &end);
+       ret = lm_get_label_chunk(zclient_sync, 0, MPLS_LABEL_BASE_ANY,
+                                CHUNK_SIZE, &start, &end);
        if (ret < 0) {
                log_warnx("Error getting label chunk!");
                return -1;
@@ -1711,6 +1727,32 @@ on_get_label_chunk_response(uint32_t start, uint32_t end)
                current_label_chunk = listtail(label_chunk_list);
 }
 
+void
+lde_free_label(uint32_t label)
+{
+       struct listnode *node;
+       struct label_chunk      *label_chunk;
+       uint64_t                pos;
+
+       for (ALL_LIST_ELEMENTS_RO(label_chunk_list, node, label_chunk)) {
+               if (label <= label_chunk->end && label >= label_chunk->start) {
+                       pos = 1ULL << (label - label_chunk->start);
+                       label_chunk->used_mask &= ~pos;
+                       /* if nobody is using this chunk and it's not current_label_chunk, then free it */
+                       if (!label_chunk->used_mask && (current_label_chunk != node)) {
+                               if (lde_release_label_chunk(label_chunk->start, label_chunk->end) != 0)
+                                       log_warnx("%s: Error releasing label chunk!", __func__);
+                               else {
+                                       listnode_delete(label_chunk_list, label_chunk);
+                                       lde_del_label_chunk(label_chunk);
+                               }
+                       }
+                       break;
+               }
+       }
+       return;
+}
+
 static uint32_t
 lde_get_next_label(void)
 {