Module Name: src Committed By: kefren Date: Wed Jul 31 06:58:23 UTC 2013
Modified Files: src/usr.sbin/ldpd: label.c label.h ldp_command.c main.c mpls_routes.c tlv_stack.c Log Message: Store local bindings in a rbtree To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 src/usr.sbin/ldpd/label.c cvs rdiff -u -r1.7 -r1.8 src/usr.sbin/ldpd/label.h cvs rdiff -u -r1.12 -r1.13 src/usr.sbin/ldpd/ldp_command.c \ src/usr.sbin/ldpd/tlv_stack.c cvs rdiff -u -r1.8 -r1.9 src/usr.sbin/ldpd/main.c cvs rdiff -u -r1.21 -r1.22 src/usr.sbin/ldpd/mpls_routes.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.sbin/ldpd/label.c diff -u src/usr.sbin/ldpd/label.c:1.10 src/usr.sbin/ldpd/label.c:1.11 --- src/usr.sbin/ldpd/label.c:1.10 Wed Jul 24 09:05:53 2013 +++ src/usr.sbin/ldpd/label.c Wed Jul 31 06:58:23 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: label.c,v 1.10 2013/07/24 09:05:53 kefren Exp $ */ +/* $NetBSD: label.c,v 1.11 2013/07/31 06:58:23 kefren Exp $ */ /*- * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -32,6 +32,7 @@ #include <netmpls/mpls.h> #include <assert.h> +#include <stddef.h> #include <stdlib.h> #include <string.h> @@ -41,12 +42,45 @@ #include "label.h" #include "ldp_errors.h" -int min_label = MIN_LABEL, max_label = MAX_LABEL; +static int labels_compare(void*, const void*, const void*); + +int min_label = MIN_LABEL, max_label = MAX_LABEL; + +static rb_tree_t labels_tree; +static const rb_tree_ops_t tree_ops = { + .rbto_compare_nodes = labels_compare, + .rbto_compare_key = labels_compare, + .rbto_node_offset = offsetof(struct label, lbtree), + .rbto_context = NULL +}; void label_init() { - SLIST_INIT(&label_head); + + rb_tree_init(&labels_tree, &tree_ops); +} + +static int +labels_compare(void *context, const void *node1, const void *node2) +{ + const struct label *l1 = node1, *l2 = node2; + int ret; + + if (__predict_false(l1->so_dest.sa.sa_family != + l2->so_dest.sa.sa_family)) + return l1->so_dest.sa.sa_family > l2->so_dest.sa.sa_family ? + 1 : -1; + + assert(l1->so_dest.sa.sa_len == l2->so_dest.sa.sa_len); + assert(l1->so_pref.sa.sa_len == l2->so_pref.sa.sa_len); + + if ((ret = memcmp(&l1->so_dest.sa, &l2->so_dest.sa, + l1->so_dest.sa.sa_len)) != 0) + return ret; + else + return memcmp(&l1->so_pref.sa, &l2->so_pref.sa, + l1->so_pref.sa.sa_len); } /* @@ -85,7 +119,8 @@ label_add(const union sockunion * so_des l->label = label; l->host = host; - SLIST_INSERT_HEAD(&label_head, l, labels); + if (rb_tree_insert_node(&labels_tree, l) != l) + fatalp("label already in tree"); strlcpy(spreftmp, satos(&so_pref->sa), INET_ADDRSTRLEN); warnp("[label_add] added binding %d for %s/%s\n", l->binding, @@ -102,7 +137,7 @@ label_del(struct label * l) { warnp("[label_del] deleted binding %d for %s\n", l->binding, satos(&l->so_dest.sa)); - SLIST_REMOVE(&label_head, l, label, labels); + rb_tree_remove_node(&labels_tree, l); free(l); } @@ -148,15 +183,13 @@ label_reattach_route(struct label *l, in struct label* label_get(const union sockunion *sodest, const union sockunion *sopref) { - struct label *l; + struct label l; - SLIST_FOREACH (l, &label_head, labels) - if (sodest->sin.sin_addr.s_addr == - l->so_dest.sin.sin_addr.s_addr && - sopref->sin.sin_addr.s_addr == - l->so_pref.sin.sin_addr.s_addr) - return l; - return NULL; + memset(&l, 0, sizeof(l)); + memcpy(&l.so_dest, sodest, sodest->sa.sa_len); + memcpy(&l.so_pref, sopref, sopref->sa.sa_len); + + return rb_tree_find_node(&labels_tree, &l); } /* @@ -168,7 +201,7 @@ label_reattach_all_peer_labels(const str { struct label *l; - SLIST_FOREACH(l, &label_head, labels) + RB_TREE_FOREACH(l, &labels_tree) if (l->p == p) label_reattach_route(l, readd); } @@ -182,12 +215,17 @@ del_all_peer_labels(const struct ldp_pee { struct label *l, *lnext; - SLIST_FOREACH_SAFE(l, &label_head, labels, lnext) { + RB_TREE_FOREACH(l, &labels_tree) { +back_delete: if(l->p != p) continue; label_reattach_route(l, readd); + lnext = rb_tree_iterate(&labels_tree, l, RB_DIR_RIGHT); label_del(l); - SLIST_REMOVE(&label_head, l, label, labels); + if (lnext == NULL) + break; + l = lnext; + goto back_delete; } } @@ -199,11 +237,10 @@ label_del_by_binding(uint32_t binding, i { struct label *l; - SLIST_FOREACH(l, &label_head, labels) + RB_TREE_FOREACH(l, &labels_tree) if ((uint32_t)l->binding == binding) { label_reattach_route(l, readd); label_del(l); - SLIST_REMOVE(&label_head, l, label, labels); break; } } @@ -238,7 +275,7 @@ get_free_local_label() int lbl; for (lbl = min_label; lbl <= max_label; lbl++) { - SLIST_FOREACH(l, &label_head, labels) + RB_TREE_FOREACH(l, &labels_tree) if (l->binding == lbl) break; if (l == NULL) @@ -267,13 +304,22 @@ label_check_assoc(struct ldp_peer *p) struct label *l; struct ldp_peer_address *wp; - SLIST_FOREACH (l, &label_head, labels) + RB_TREE_FOREACH(l, &labels_tree) if (l->p == NULL && l->so_gate.sa.sa_family != 0) SLIST_FOREACH(wp, &p->ldp_peer_address_head, addresses) if (sockaddr_cmp(&l->so_gate.sa, - &wp->address.sa) == 0){ + &wp->address.sa) == 0) { l->p = p; l->label = MPLS_LABEL_IMPLNULL; break; } } + +struct label * +label_get_right(struct label *l) +{ + if (l == NULL) + return RB_TREE_MIN(&labels_tree); + else + return rb_tree_iterate(&labels_tree, l, RB_DIR_RIGHT); +} Index: src/usr.sbin/ldpd/label.h diff -u src/usr.sbin/ldpd/label.h:1.7 src/usr.sbin/ldpd/label.h:1.8 --- src/usr.sbin/ldpd/label.h:1.7 Wed Jul 24 09:05:53 2013 +++ src/usr.sbin/ldpd/label.h Wed Jul 31 06:58:23 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: label.h,v 1.7 2013/07/24 09:05:53 kefren Exp $ */ +/* $NetBSD: label.h,v 1.8 2013/07/31 06:58:23 kefren Exp $ */ /*- * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -32,7 +32,7 @@ #ifndef _LABEL_H_ #define _LABEL_H_ -#include <sys/queue.h> +#include <sys/rbtree.h> #include "mpls_routes.h" #include "ldp_peer.h" @@ -53,9 +53,8 @@ struct label { int binding, label; bool host; /* change routes using RTF_HOST */ const struct ldp_peer *p; - SLIST_ENTRY(label) labels; + rb_node_t lbtree; }; -SLIST_HEAD(,label) label_head; void label_init(void); struct label * label_add(const union sockunion *, const union sockunion *, @@ -72,5 +71,6 @@ uint32_t get_free_local_label(void); void announce_label_change(struct label *); void label_reattach_route(struct label*, int); void label_check_assoc(struct ldp_peer *p); +struct label * label_get_right(struct label *); #endif /* !_LABEL_H_ */ Index: src/usr.sbin/ldpd/ldp_command.c diff -u src/usr.sbin/ldpd/ldp_command.c:1.12 src/usr.sbin/ldpd/ldp_command.c:1.13 --- src/usr.sbin/ldpd/ldp_command.c:1.12 Thu Jul 18 06:07:45 2013 +++ src/usr.sbin/ldpd/ldp_command.c Wed Jul 31 06:58:23 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: ldp_command.c,v 1.12 2013/07/18 06:07:45 kefren Exp $ */ +/* $NetBSD: ldp_command.c,v 1.13 2013/07/31 06:58:23 kefren Exp $ */ /*- * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -504,11 +504,11 @@ show_labels(int s, char *recvspace) int show_bindings(int s, char *recvspace) { - struct label *l; + struct label *l = NULL; snprintf(sendspace, MAXSEND, "Local label\tNetwork\t\t\t\tNexthop\n"); writestr(s, sendspace); - SLIST_FOREACH (l, &label_head, labels) { + while((l = label_get_right(l)) != NULL) { snprintf(sendspace, MAXSEND, "%d\t\t%s/", l->binding, satos(&l->so_dest.sa)); writestr(s, sendspace); Index: src/usr.sbin/ldpd/tlv_stack.c diff -u src/usr.sbin/ldpd/tlv_stack.c:1.12 src/usr.sbin/ldpd/tlv_stack.c:1.13 --- src/usr.sbin/ldpd/tlv_stack.c:1.12 Sat Jul 20 05:16:08 2013 +++ src/usr.sbin/ldpd/tlv_stack.c Wed Jul 31 06:58:23 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: tlv_stack.c,v 1.12 2013/07/20 05:16:08 kefren Exp $ */ +/* $NetBSD: tlv_stack.c,v 1.13 2013/07/31 06:58:23 kefren Exp $ */ /*- * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -201,7 +201,7 @@ withdraw_label(struct ldp_peer * p, stru * POP Label */ lab = label_get_by_prefix(&socktmp.sa, pref->prelen); - if ((lab) && (lab->p == p)) { + if (lab && lab->p == p) { label_reattach_route(lab, REATT_INET_CHANGE); announce_label_change(lab); /* binding has changed */ } @@ -332,9 +332,9 @@ send_label_tlv_to_all(const struct socka void send_all_bindings(const struct ldp_peer * peer) { - struct label *l; + struct label *l = NULL; - SLIST_FOREACH(l, &label_head, labels) + while((l = label_get_right(l)) != NULL) send_label_tlv(peer, &l->so_dest.sa, from_union_to_cidr(&l->so_pref), l->binding, NULL); Index: src/usr.sbin/ldpd/main.c diff -u src/usr.sbin/ldpd/main.c:1.8 src/usr.sbin/ldpd/main.c:1.9 --- src/usr.sbin/ldpd/main.c:1.8 Thu Jul 25 08:40:30 2013 +++ src/usr.sbin/ldpd/main.c Wed Jul 31 06:58:23 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.8 2013/07/25 08:40:30 kefren Exp $ */ +/* $NetBSD: main.c,v 1.9 2013/07/31 06:58:23 kefren Exp $ */ /*- * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -32,7 +32,6 @@ #include <netinet/in.h> #include <sys/stat.h> #include <sys/socket.h> -#include <sys/select.h> #include <arpa/inet.h> #include <stdio.h> Index: src/usr.sbin/ldpd/mpls_routes.c diff -u src/usr.sbin/ldpd/mpls_routes.c:1.21 src/usr.sbin/ldpd/mpls_routes.c:1.22 --- src/usr.sbin/ldpd/mpls_routes.c:1.21 Sat Jul 27 14:35:41 2013 +++ src/usr.sbin/ldpd/mpls_routes.c Wed Jul 31 06:58:23 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: mpls_routes.c,v 1.21 2013/07/27 14:35:41 kefren Exp $ */ +/* $NetBSD: mpls_routes.c,v 1.22 2013/07/31 06:58:23 kefren Exp $ */ /*- * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -900,6 +900,8 @@ bind_current_routes() so_pref->sa.sa_family = AF_INET; so_pref->sa.sa_len = sizeof(struct sockaddr_in); + so_pref->sin.sin_port = 0; + memset(&so_pref->sin.sin_zero, 0, 8); /* Also deletes when dest is IPv4 and gateway MPLS */ if ((rtmes->rtm_addrs & RTA_GATEWAY) &&