Module Name:    src
Committed By:   kefren
Date:           Fri Aug  2 07:29:56 UTC 2013

Modified Files:
        src/usr.sbin/ldpd: ldp_command.c ldp_peer.c ldp_peer.h mpls_interface.c

Log Message:
Use rbtree for storing peers FEC label bindings


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/usr.sbin/ldpd/ldp_command.c
cvs rdiff -u -r1.15 -r1.16 src/usr.sbin/ldpd/ldp_peer.c
cvs rdiff -u -r1.7 -r1.8 src/usr.sbin/ldpd/ldp_peer.h
cvs rdiff -u -r1.12 -r1.13 src/usr.sbin/ldpd/mpls_interface.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/ldp_command.c
diff -u src/usr.sbin/ldpd/ldp_command.c:1.13 src/usr.sbin/ldpd/ldp_command.c:1.14
--- src/usr.sbin/ldpd/ldp_command.c:1.13	Wed Jul 31 06:58:23 2013
+++ src/usr.sbin/ldpd/ldp_command.c	Fri Aug  2 07:29:56 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: ldp_command.c,v 1.13 2013/07/31 06:58:23 kefren Exp $ */
+/* $NetBSD: ldp_command.c,v 1.14 2013/08/02 07:29:56 kefren Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -481,12 +481,12 @@ int
 show_labels(int s, char *recvspace)
 {
 	struct ldp_peer *p;
-	struct label_mapping *lm;
+	struct label_mapping *lm = NULL;
 
 	SLIST_FOREACH(p, &ldp_peer_head, peers) {
 		if (p->state != LDP_PEER_ESTABLISHED)
 			continue;
-		SLIST_FOREACH(lm, &p->label_mapping_head, mappings) {
+		while ((lm = ldp_peer_lm_right(p, lm)) != NULL) {
 			char lma[256];
 			/* XXX: TODO */
 			if (lm->address.sa.sa_family != AF_INET)

Index: src/usr.sbin/ldpd/ldp_peer.c
diff -u src/usr.sbin/ldpd/ldp_peer.c:1.15 src/usr.sbin/ldpd/ldp_peer.c:1.16
--- src/usr.sbin/ldpd/ldp_peer.c:1.15	Sat Jul 20 05:16:08 2013
+++ src/usr.sbin/ldpd/ldp_peer.c	Fri Aug  2 07:29:56 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: ldp_peer.c,v 1.15 2013/07/20 05:16:08 kefren Exp $ */
+/* $NetBSD: ldp_peer.c,v 1.16 2013/08/02 07:29:56 kefren Exp $ */
 
 /*
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -41,6 +41,7 @@
 #include <fcntl.h>
 #include <stdlib.h>
 #include <strings.h>
+#include <stddef.h>
 #include <stdio.h>
 #include <unistd.h>
 
@@ -55,6 +56,17 @@
 
 extern int ldp_holddown_time;
 
+static struct label_mapping *ldp_peer_get_lm(struct ldp_peer *,
+    const struct sockaddr *, uint);
+
+static int mappings_compare(void *, const void *, const void *);
+static rb_tree_ops_t mappings_tree_ops = {
+	.rbto_compare_nodes = mappings_compare,
+	.rbto_compare_key = mappings_compare,
+	.rbto_node_offset = offsetof(struct label_mapping, mappings_node),
+	.rbto_context = NULL
+};
+
 void 
 ldp_peer_init(void)
 {
@@ -69,6 +81,28 @@ sockaddr_cmp(const struct sockaddr *a, c
 		return -1;
 	return memcmp(a, b, a->sa_len);
 }
+
+static int
+mappings_compare(void *context, const void *node1, const void *node2)
+{
+	const struct label_mapping *l1 = node1, *l2 = node2;
+	int ret;
+
+	if (__predict_false(l1->address.sa.sa_family !=
+	    l2->address.sa.sa_family))
+		return l1->address.sa.sa_family > l2->address.sa.sa_family ?
+		    1 : -1;
+
+	assert(l1->address.sa.sa_len == l2->address.sa.sa_len);
+	if ((ret = memcmp(&l1->address.sa, &l2->address.sa, l1->address.sa.sa_len)) != 0)
+		return ret;
+
+	if (__predict_false(l1->prefix != l2->prefix))
+		return l1->prefix > l2->prefix ? 1 : -1;
+
+	return 0;
+}
+
 /*
  * soc should be > 1 if there is already a TCP socket for this else we'll
  * initiate a new one
@@ -150,7 +184,7 @@ ldp_peer_new(const struct in_addr * ldp_
 		set_ttl(p->socket);
 	}
 	SLIST_INIT(&p->ldp_peer_address_head);
-	SLIST_INIT(&p->label_mapping_head);
+	rb_tree_init(&p->label_mapping_tree, &mappings_tree_ops);
 	p->timeout = p->holdtime;
 
 	sopts = fcntl(p->socket, F_GETFL);
@@ -449,7 +483,7 @@ ldp_peer_add_mapping(struct ldp_peer * p
 	lma->prefix = prefix;
 	lma->label = label;
 
-	SLIST_INSERT_HEAD(&p->label_mapping_head, lma, mappings);
+	rb_tree_insert_node(&p->label_mapping_tree, lma);
 
 	return LDP_E_OK;
 }
@@ -460,34 +494,28 @@ ldp_peer_delete_mapping(struct ldp_peer 
 {
 	struct label_mapping *lma;
 
-	if (!a)
+	if (a == NULL || (lma = ldp_peer_get_lm(p, a, prefix)) == NULL)
 		return LDP_E_NOENT;
 
-	lma = ldp_peer_get_lm(p, a, prefix);
-	if (!lma)
-		return LDP_E_NOENT;
-
-	SLIST_REMOVE(&p->label_mapping_head, lma, label_mapping, mappings);
+	rb_tree_remove_node(&p->label_mapping_tree, lma);
 	free(lma);
 
 	return LDP_E_OK;
 }
 
-struct label_mapping *
-ldp_peer_get_lm(const struct ldp_peer * p, const struct sockaddr * a,
+static struct label_mapping *
+ldp_peer_get_lm(struct ldp_peer * p, const struct sockaddr * a,
     uint prefix)
 {
-	struct label_mapping *rv;
+	struct label_mapping rv;
 
-	if (!p)
-		return NULL;
-
-	SLIST_FOREACH(rv, &p->label_mapping_head, mappings)
-		if (rv->prefix == prefix && sockaddr_cmp(a, &rv->address.sa)==0)
-			break;
+	assert(a->sa_len <= sizeof(union sockunion));
 
-	return rv;
+	memset(&rv, 0, sizeof(rv));
+	memcpy(&rv.address.sa, a, a->sa_len);
+	rv.prefix = prefix;
 
+	return rb_tree_find_node(&p->label_mapping_tree, &rv);
 }
 
 void
@@ -495,9 +523,8 @@ ldp_peer_delete_all_mappings(struct ldp_
 {
 	struct label_mapping *lma;
 
-	while(!SLIST_EMPTY(&p->label_mapping_head)) {
-		lma = SLIST_FIRST(&p->label_mapping_head);
-		SLIST_REMOVE_HEAD(&p->label_mapping_head, mappings);
+	while((lma = RB_TREE_MIN(&p->label_mapping_tree)) != NULL) {
+		rb_tree_remove_node(&p->label_mapping_tree, lma);
 		free(lma);
 	}
 }
@@ -542,6 +569,16 @@ ldp_test_mapping(const struct sockaddr *
 	return rv;
 }
 
+struct label_mapping * ldp_peer_lm_right(struct ldp_peer *p,
+    struct label_mapping * map)
+{
+	if (map == NULL)
+		return RB_TREE_MIN(&p->label_mapping_tree);
+	else
+		return rb_tree_iterate(&p->label_mapping_tree, map,
+		    RB_DIR_RIGHT);
+}
+
 /* Name from state */
 const char * ldp_state_to_name(int state)
 {

Index: src/usr.sbin/ldpd/ldp_peer.h
diff -u src/usr.sbin/ldpd/ldp_peer.h:1.7 src/usr.sbin/ldpd/ldp_peer.h:1.8
--- src/usr.sbin/ldpd/ldp_peer.h:1.7	Sat Jul 20 05:16:08 2013
+++ src/usr.sbin/ldpd/ldp_peer.h	Fri Aug  2 07:29:56 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: ldp_peer.h,v 1.7 2013/07/20 05:16:08 kefren Exp $ */
+/* $NetBSD: ldp_peer.h,v 1.8 2013/08/02 07:29:56 kefren Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -33,6 +33,7 @@
 #define _LDP_PEER_H_
 
 #include "sys/types.h"
+#include "sys/rbtree.h"
 #include "sys/queue.h"
 #include "netinet/in.h"
 
@@ -48,7 +49,7 @@ struct label_mapping {
 	union sockunion address;
 	uint	prefix;
 	uint	label;
-	SLIST_ENTRY(label_mapping) mappings;
+	rb_node_t mappings_node;
 };
 
 struct ldp_peer {
@@ -69,7 +70,7 @@ struct ldp_peer {
 	time_t		established_t;	/* time when it did connect */
 	/* Here I maintain all the addresses announced by a peer */
 	SLIST_HEAD(,ldp_peer_address) ldp_peer_address_head;
-	SLIST_HEAD(,label_mapping) label_mapping_head;
+	rb_tree_t label_mapping_tree;
 
 	SLIST_ENTRY(ldp_peer) peers;
 };
@@ -106,13 +107,13 @@ int del_ifaddresses(struct ldp_peer *, c
 
 int ldp_peer_add_mapping(struct ldp_peer *, const struct sockaddr *, int, int);
 int ldp_peer_delete_mapping(struct ldp_peer *, const struct sockaddr *, int);
-struct label_mapping * ldp_peer_get_lm(const struct ldp_peer *,
-	const struct sockaddr *, uint);
 void ldp_peer_delete_all_mappings(struct ldp_peer *);
 void ldp_peer_holddown_all(void);
 
 struct peer_map * ldp_test_mapping(const struct sockaddr *, int,
 	const struct sockaddr *);
+struct label_mapping * ldp_peer_lm_right(struct ldp_peer *,
+	struct label_mapping *);
 
 const char * ldp_state_to_name(int);
 

Index: src/usr.sbin/ldpd/mpls_interface.c
diff -u src/usr.sbin/ldpd/mpls_interface.c:1.12 src/usr.sbin/ldpd/mpls_interface.c:1.13
--- src/usr.sbin/ldpd/mpls_interface.c:1.12	Wed Jul 24 09:05:53 2013
+++ src/usr.sbin/ldpd/mpls_interface.c	Fri Aug  2 07:29:56 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: mpls_interface.c,v 1.12 2013/07/24 09:05:53 kefren Exp $ */
+/* $NetBSD: mpls_interface.c,v 1.13 2013/08/02 07:29:56 kefren Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -59,6 +59,7 @@ mpls_add_label(struct label *lab)
 	union sockunion *so_dest, *so_nexthop, *so_tag, so_ifa;
 	uint8_t prefixlen;
 	uint32_t oldbinding;
+	struct peer_map *pm;
 
 	assert(lab != NULL);
 
@@ -74,8 +75,13 @@ mpls_add_label(struct label *lab)
 		return LDP_E_BAD_AF;
 
 	/* double check if there is a label mapping for this */
-	if (ldp_peer_get_lm(lab->p, &lab->so_dest.sa, prefixlen) == NULL)
+	if ((pm = ldp_test_mapping(&lab->so_dest.sa, prefixlen,
+	    &lab->so_gate.sa)) == NULL || pm->peer != lab->p) {
+		if (pm != NULL)
+			free(pm);
 		return LDP_E_NOENT;
+	}
+	free(pm);
 
 	if (lab->so_gate.sa.sa_family != AF_INET &&
 	    lab->so_gate.sa.sa_family != AF_INET6) {

Reply via email to