Module Name: src
Committed By: kefren
Date: Thu Dec 30 11:29:22 UTC 2010
Modified Files:
src/usr.sbin/ldpd: Makefile TODO label.c ldp.h ldp_command.c ldp_peer.c
ldpd.8 main.c socketops.c
Added Files:
src/usr.sbin/ldpd: conffile.c conffile.h
Log Message:
* add config file so one can control id, timers and label assignment and
use neighbour specific options - XXX: needs documentation
* add peer authentication using TCP_MD5SIG. Interoperability tested with
Cisco IOS
* use SLIST_FOREACH_SAFE when deleting labels instead of re-looping.
To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/usr.sbin/ldpd/Makefile src/usr.sbin/ldpd/label.c \
src/usr.sbin/ldpd/ldp_command.c src/usr.sbin/ldpd/ldp_peer.c \
src/usr.sbin/ldpd/ldpd.8 src/usr.sbin/ldpd/main.c \
src/usr.sbin/ldpd/socketops.c
cvs rdiff -u -r1.1 -r1.2 src/usr.sbin/ldpd/TODO src/usr.sbin/ldpd/ldp.h
cvs rdiff -u -r0 -r1.1 src/usr.sbin/ldpd/conffile.c \
src/usr.sbin/ldpd/conffile.h
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/Makefile
diff -u src/usr.sbin/ldpd/Makefile:1.2 src/usr.sbin/ldpd/Makefile:1.3
--- src/usr.sbin/ldpd/Makefile:1.2 Sat Dec 18 04:25:37 2010
+++ src/usr.sbin/ldpd/Makefile Thu Dec 30 11:29:21 2010
@@ -1,11 +1,12 @@
-# $NetBSD: Makefile,v 1.2 2010/12/18 04:25:37 joerg Exp $
+# $NetBSD: Makefile,v 1.3 2010/12/30 11:29:21 kefren Exp $
.include <bsd.own.mk>
PROG= ldpd
MAN= ldpd.8
-SRCS= fsm.c \
+SRCS= conffile.c \
+ fsm.c \
label.c \
ldp_command.c \
ldp_errors.c \
Index: src/usr.sbin/ldpd/label.c
diff -u src/usr.sbin/ldpd/label.c:1.2 src/usr.sbin/ldpd/label.c:1.3
--- src/usr.sbin/ldpd/label.c:1.2 Thu Dec 9 00:10:59 2010
+++ src/usr.sbin/ldpd/label.c Thu Dec 30 11:29:21 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: label.c,v 1.2 2010/12/09 00:10:59 christos Exp $ */
+/* $NetBSD: label.c,v 1.3 2010/12/30 11:29:21 kefren Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -41,6 +41,8 @@
#include "label.h"
#include "ldp_errors.h"
+int min_label = MIN_LABEL, max_label = MAX_LABEL;
+
void
label_init()
{
@@ -146,7 +148,7 @@
l->label = 0;
/* Deletes pure MPLS route */
- if (oldbinding >= MIN_LABEL) {
+ if (oldbinding >= min_label) {
u = make_mpls_union(oldbinding);
delete_route(u, NULL, FREESO);
}
@@ -189,22 +191,15 @@
void
del_all_peer_labels(struct ldp_peer * p, int readd)
{
- struct label *l;
- int do_remove = 1;
+ struct label *l, *lnext;
- while(do_remove == 1) {
- do_remove = 0;
- SLIST_FOREACH(l, &label_head, labels) {
- if(l->p != p)
- continue;
- label_reattach_route(l, readd);
- label_del(l);
- /* remove must not interact with foreach */
- SLIST_REMOVE(&label_head, l, label, labels);
- do_remove = 1;
- break; /* XXX: suboptimal */
- }
- } // while
+ SLIST_FOREACH_SAFE(l, &label_head, labels, lnext) {
+ if(l->p != p)
+ continue;
+ label_reattach_route(l, readd);
+ label_del(l);
+ SLIST_REMOVE(&label_head, l, label, labels);
+ }
}
/*
@@ -251,11 +246,11 @@
get_free_local_label()
{
struct label *l;
- uint32_t lbl;
+ int lbl;
- for (lbl = MIN_LABEL; lbl <= MAX_LABEL; lbl++) {
+ for (lbl = min_label; lbl <= max_label; lbl++) {
SLIST_FOREACH(l, &label_head, labels)
- if ((uint32_t)l->binding == lbl)
+ if (l->binding == lbl)
break;
if (l == NULL)
return lbl;
Index: src/usr.sbin/ldpd/ldp_command.c
diff -u src/usr.sbin/ldpd/ldp_command.c:1.2 src/usr.sbin/ldpd/ldp_command.c:1.3
--- src/usr.sbin/ldpd/ldp_command.c:1.2 Tue Dec 14 21:32:43 2010
+++ src/usr.sbin/ldpd/ldp_command.c Thu Dec 30 11:29:21 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: ldp_command.c,v 1.2 2010/12/14 21:32:43 christos Exp $ */
+/* $NetBSD: ldp_command.c,v 1.3 2010/12/30 11:29:21 kefren Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -51,7 +51,8 @@
#include "socketops.h"
struct com_sock csockets[MAX_COMMAND_SOCKETS];
-extern int ldp_hello_time, debug_f, warn_f;
+extern int ldp_hello_time, ldp_keepalive_time, ldp_holddown_time,
+ min_label, max_label, debug_f, warn_f;
#define writestr(soc, str) write(soc, str, strlen(str))
@@ -62,7 +63,7 @@
static void echo_on(int s);
static void echo_off(int s);
-struct com_func main_commands[] = {
+static struct com_func main_commands[] = {
{ "show", show_func },
{ "set", set_func },
{ "quit", exit_func },
@@ -70,7 +71,7 @@
{ "", NULL }
};
-struct com_func show_commands[] = {
+static struct com_func show_commands[] = {
{ "neighbours", show_neighbours },
{ "bindings", show_bindings },
{ "debug", show_debug },
@@ -494,10 +495,10 @@
my_ldp_id,
LDP_VERSION,
ldp_hello_time,
- LDP_KEEPALIVE_TIME,
- LDP_HOLDTIME,
- MIN_LABEL,
- MAX_LABEL);
+ ldp_keepalive_time,
+ ldp_holddown_time,
+ min_label,
+ max_label);
writestr(s, sendspace);
return 1;
}
Index: src/usr.sbin/ldpd/ldp_peer.c
diff -u src/usr.sbin/ldpd/ldp_peer.c:1.2 src/usr.sbin/ldpd/ldp_peer.c:1.3
--- src/usr.sbin/ldpd/ldp_peer.c:1.2 Thu Dec 9 00:10:59 2010
+++ src/usr.sbin/ldpd/ldp_peer.c Thu Dec 30 11:29:21 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: ldp_peer.c,v 1.2 2010/12/09 00:10:59 christos Exp $ */
+/* $NetBSD: ldp_peer.c,v 1.3 2010/12/30 11:29:21 kefren Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -32,6 +32,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
+#include <netinet/tcp.h>
#include <netmpls/mpls.h>
#include <arpa/inet.h>
@@ -40,6 +41,8 @@
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
+
+#include "conffile.h"
#include "socketops.h"
#include "ldp_errors.h"
#include "ldp.h"
@@ -48,6 +51,8 @@
#include "notifications.h"
#include "ldp_peer.h"
+extern int ldp_holddown_time;
+
struct in_addr *myaddresses;
void
@@ -66,8 +71,9 @@
struct in_addr * tradd, uint16_t holdtime, int soc)
{
struct ldp_peer *p;
- int s = soc;
+ int s = soc;
struct sockaddr_in sa;
+ struct conf_neighbour *cn;
if (s < 1) {
s = socket(PF_INET, SOCK_STREAM, 0);
@@ -86,11 +92,22 @@
set_ttl(s);
}
+ /* MD5 authentication needed ? */
+ SLIST_FOREACH(cn, &conei_head, neilist)
+ if (cn->authenticate != 0 && (a->s_addr == cn->address.s_addr ||
+ (tradd && tradd->s_addr == cn->address.s_addr))) {
+ if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG, &(int){1},
+ sizeof(int)) != 0)
+ fatalp("setsockopt TCP_MD5SIG: %s\n",
+ strerror(errno));
+ break;
+ }
+
/* Set the peer in CONNECTING/CONNECTED state */
p = calloc(1, sizeof(*p));
if (!p) {
- fatalp("ldp_peer_new: malloc problem\n");
+ fatalp("ldp_peer_new: calloc problem\n");
return NULL;
}
@@ -103,7 +120,7 @@
else
memcpy(&p->transport_address, a,
sizeof(struct in_addr));
- p->holdtime = holdtime > LDP_HOLDTIME ? holdtime : LDP_HOLDTIME;
+ p->holdtime = holdtime > ldp_holddown_time ? holdtime : ldp_holddown_time;
p->socket = s;
if (soc < 1) {
p->state = LDP_PEER_CONNECTING;
@@ -141,7 +158,7 @@
if (p->state == LDP_PEER_ESTABLISHED)
mpls_delete_ldp_peer(p);
p->state = LDP_PEER_HOLDDOWN;
- p->timeout = LDP_HOLDTIME;
+ p->timeout = ldp_holddown_time;
shutdown(p->socket, SHUT_RDWR);
ldp_peer_delete_all_mappings(p);
del_all_ifaddr(p);
Index: src/usr.sbin/ldpd/ldpd.8
diff -u src/usr.sbin/ldpd/ldpd.8:1.2 src/usr.sbin/ldpd/ldpd.8:1.3
--- src/usr.sbin/ldpd/ldpd.8:1.2 Wed Dec 8 09:43:22 2010
+++ src/usr.sbin/ldpd/ldpd.8 Thu Dec 30 11:29:21 2010
@@ -1,4 +1,4 @@
-.\" $NetBSD: ldpd.8,v 1.2 2010/12/08 09:43:22 wiz Exp $
+.\" $NetBSD: ldpd.8,v 1.3 2010/12/30 11:29:21 kefren Exp $
.\"
.\" Copyright (c) 2010 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -32,6 +32,7 @@
.Nd Label Distribution Protocol Daemon
.Sh SYNOPSIS
.Nm
+.Op Fl c Ar config_file
.Op Fl DdfhW
.Op Fl p Ar port
.Sh DESCRIPTION
@@ -74,6 +75,8 @@
.Pp
The options are as follows:
.Bl -tag -width 15n
+.It Fl c Ar config_file
+Specifies a path to the config file. Default: /etc/ldpd.conf
.It Fl D
Enable debug mode.
.It Fl d
Index: src/usr.sbin/ldpd/main.c
diff -u src/usr.sbin/ldpd/main.c:1.2 src/usr.sbin/ldpd/main.c:1.3
--- src/usr.sbin/ldpd/main.c:1.2 Wed Dec 8 09:43:28 2010
+++ src/usr.sbin/ldpd/main.c Thu Dec 30 11:29:21 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.2 2010/12/08 09:43:28 wiz Exp $ */
+/* $NetBSD: main.c,v 1.3 2010/12/30 11:29:21 kefren Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -48,15 +48,17 @@
#include "fsm.h"
#include "ldp_errors.h"
#include "mpls_interface.h"
+#include "conffile.h"
-extern int ls; /* TCP listening socket */
-extern int dont_catch;
-extern int command_port;
-extern int command_socket;
+extern int ls; /* TCP listening socket */
+extern int dont_catch;
+extern int command_port;
+extern int command_socket;
-extern int debug_f, warn_f, syslog_f;
+extern int debug_f, warn_f, syslog_f;
-extern struct sockaddr mplssockaddr;
+extern struct sockaddr mplssockaddr;
+extern struct in_addr conf_ldp_id;
void print_usage(char *myself)
{
@@ -66,10 +68,15 @@
int
main(int argc, char *argv[])
{
- int ch, forkres, dontfork = 0;
+ int ch, forkres, dontfork = 0, cpf;
+ char conffile[PATH_MAX + 1];
- while((ch = getopt(argc, argv, "dDfhp:W")) != -1)
+ strlcpy(conffile, CONFFILE, sizeof(conffile));
+ while((ch = getopt(argc, argv, "c:dDfhp:W")) != -1)
switch(ch) {
+ case 'c':
+ strlcpy(conffile, optarg, sizeof(conffile));
+ break;
case 'D':
debug_f = 1;
break;
@@ -98,10 +105,23 @@
fatalp("You have to run this as ROOT\n");
return -1;
}
+
+ cpf = conf_parsefile(conffile);
+ if (cpf < 0 && strcmp(conffile, CONFFILE)) {
+ fatalp("Cannot parse config file: %s\n", conffile);
+ return -1;
+ } else if (cpf > 0) {
+ fatalp("Cannot parse line %d in config file\n", cpf);
+ return -1;
+ }
+
if (set_my_ldp_id()) {
fatalp("Cannot set LDP ID\n");
return -1;
}
+ if (conf_ldp_id.s_addr != 0)
+ strlcpy(my_ldp_id, inet_ntoa(conf_ldp_id), INET_ADDRSTRLEN);
+
if (mplssockaddr.sa_len == 0) {
fatalp("You need one mpls interface up and an IP "
"address set for it\n");
Index: src/usr.sbin/ldpd/socketops.c
diff -u src/usr.sbin/ldpd/socketops.c:1.2 src/usr.sbin/ldpd/socketops.c:1.3
--- src/usr.sbin/ldpd/socketops.c:1.2 Thu Dec 9 00:10:59 2010
+++ src/usr.sbin/ldpd/socketops.c Thu Dec 30 11:29:21 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: socketops.c,v 1.2 2010/12/09 00:10:59 christos Exp $ */
+/* $NetBSD: socketops.c,v 1.3 2010/12/30 11:29:21 kefren Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -70,6 +70,8 @@
extern struct com_sock csockets[MAX_COMMAND_SOCKETS];
int ldp_hello_time = LDP_HELLO_TIME;
+int ldp_keepalive_time = LDP_KEEPALIVE_TIME;
+int ldp_holddown_time = LDP_HOLDTIME;
void recv_pdu(int);
void send_hello_alarm(int);
@@ -279,7 +281,7 @@
/* Prepare Common Hello attributes */
cht->type = htons(TLV_COMMON_HELLO);
cht->length = htons(sizeof(cht->holdtime) + sizeof(cht->res));
- cht->holdtime = htons(LDP_HOLDTIME);
+ cht->holdtime = htons(ldp_holddown_time);
cht->res = 0;
/*
@@ -456,7 +458,7 @@
send_hello_alarm(int unused)
{
struct ldp_peer *p;
- struct hello_info *hi;
+ struct hello_info *hi, *hinext;
time_t t = time(NULL);
int olderrno = errno;
@@ -489,7 +491,7 @@
} /* switch */
/* send keepalives */
- if (!(t % LDP_KEEPALIVE_TIME)) {
+ if (!(t % ldp_keepalive_time)) {
SLIST_FOREACH(p, &ldp_peer_head, peers)
if (p->state == LDP_PEER_ESTABLISHED) {
debugp("Sending KeepAlive to %s\n",
@@ -503,12 +505,9 @@
hi->keepalive--;
/* Check hello keepalives */
-check_hello:
- SLIST_FOREACH(hi, &hello_info_head, infos)
- if (hi->keepalive < 1) {
+ SLIST_FOREACH_SAFE(hi, &hello_info_head, infos, hinext)
+ if (hi->keepalive < 1)
SLIST_REMOVE(&hello_info_head, hi, hello_info, infos);
- goto check_hello;
- }
/* Set the alarm again and bail out */
alarm(1);
@@ -707,7 +706,7 @@
return;
}
/* XXX: sa.sin_addr ain't peer LDP ID ... */
- ldp_peer_new(&sa.sin_addr, &sa.sin_addr, NULL, LDP_HOLDTIME, s);
+ ldp_peer_new(&sa.sin_addr, &sa.sin_addr, NULL, ldp_holddown_time, s);
}
@@ -722,7 +721,7 @@
ti.cs_type = htons(TLV_COMMON_SESSION);
ti.cs_len = htons(CS_LEN);
ti.cs_version = htons(LDP_VERSION);
- ti.cs_keepalive = htons(2 * LDP_KEEPALIVE_TIME);
+ ti.cs_keepalive = htons(2 * ldp_keepalive_time);
ti.cs_adpvlim = 0;
ti.cs_maxpdulen = htons(MAX_PDU_SIZE);
ti.cs_peeraddress.s_addr = p->ldp_id.s_addr;
Index: src/usr.sbin/ldpd/TODO
diff -u src/usr.sbin/ldpd/TODO:1.1 src/usr.sbin/ldpd/TODO:1.2
--- src/usr.sbin/ldpd/TODO:1.1 Wed Dec 8 07:20:14 2010
+++ src/usr.sbin/ldpd/TODO Thu Dec 30 11:29:21 2010
@@ -1,4 +1,4 @@
-# $NetBSD: TODO,v 1.1 2010/12/08 07:20:14 kefren Exp $
+# $NetBSD: TODO,v 1.2 2010/12/30 11:29:21 kefren Exp $
TODO
====
@@ -7,6 +7,5 @@
* document better Label Distribution (downstream on demand or
unsolicited downstream), distribution control (independent or
ordered) and retention mode (liberal or conservative) - kefren
-* config/options file
* future: IPv6 support. Have no infrastructure to test right
now - kefren
Index: src/usr.sbin/ldpd/ldp.h
diff -u src/usr.sbin/ldpd/ldp.h:1.1 src/usr.sbin/ldpd/ldp.h:1.2
--- src/usr.sbin/ldpd/ldp.h:1.1 Wed Dec 8 07:20:14 2010
+++ src/usr.sbin/ldpd/ldp.h Thu Dec 30 11:29:21 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: ldp.h,v 1.1 2010/12/08 07:20:14 kefren Exp $ */
+/* $NetBSD: ldp.h,v 1.2 2010/12/30 11:29:21 kefren Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -41,6 +41,8 @@
#define LDPD_VER "0.3.0"
+#define CONFFILE "/etc/ldpd.conf"
+
extern char my_ldp_id[20];
#define LDP_ID my_ldp_id
Added files:
Index: src/usr.sbin/ldpd/conffile.c
diff -u /dev/null src/usr.sbin/ldpd/conffile.c:1.1
--- /dev/null Thu Dec 30 11:29:22 2010
+++ src/usr.sbin/ldpd/conffile.c Thu Dec 30 11:29:21 2010
@@ -0,0 +1,299 @@
+/* $NetBSD: conffile.c,v 1.1 2010/12/30 11:29:21 kefren Exp $ */
+
+/*
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Mihai Chelaru <[email protected]>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#include <ctype.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "conffile.h"
+#include "ldp_errors.h"
+
+#define NextCommand(x) strsep(&x, " ")
+#define LINEMAXSIZE 1024
+
+extern int ldp_hello_time, ldp_keepalive_time, ldp_holddown_time, command_port,
+ min_label, max_label;
+int confh;
+struct in_addr conf_ldp_id;
+
+static int conf_dispatch(char*);
+static int conf_readline(char*, int);
+static int checkeol(char*);
+static int Fhellotime(char*);
+static int Fport(char*);
+static int Fholddown(char*);
+static int Fkeepalive(char*);
+static int Fmaxlabel(char*);
+static int Fminlabel(char*);
+static int Fldpid(char*);
+static int Fneighbour(char*);
+static int Gneighbour(struct conf_neighbour *, char *);
+
+struct conf_func {
+ char com[64];
+ int (* func)(char *);
+};
+
+struct conf_func main_commands[] = {
+ { "hello-time", Fhellotime },
+ { "keepalive-time", Fkeepalive },
+ { "holddown-time", Fholddown },
+ { "command-port", Fport },
+ { "min-label", Fminlabel },
+ { "max-label", Fmaxlabel },
+ { "LDP-ID", Fldpid },
+ { "neighbor", Fneighbour },
+ { "neighbour", Fneighbour },
+ { "", NULL },
+};
+
+/*
+ * Parses config file
+ */
+int
+conf_parsefile(char *fname)
+{
+ int i;
+ char buf[LINEMAXSIZE + 1];
+
+ SLIST_INIT(&conei_head);
+ conf_ldp_id.s_addr = 0;
+
+ confh = open(fname, O_RDONLY, 0);
+
+ if (confh == -1)
+ return E_CONF_IO;
+
+ for (i = 1; conf_readline(buf, sizeof(buf)) >= 0; i++)
+ if (conf_dispatch(buf) != 0) {
+ close(confh);
+ return i;
+ }
+
+ close(confh);
+ return 0;
+}
+
+/*
+ * Reads a line from config file
+ */
+int
+conf_readline(char *buf, int bufsize)
+{
+ int i;
+
+ for (i = 0; i < bufsize; i++) {
+ if (read(confh, &buf[i], 1) != 1) {
+ if (i == 0)
+ return E_CONF_IO;
+ break;
+ }
+ if (buf[i] == '\n')
+ break;
+ if (i == 0 && isspace((int)buf[i]) != 0) {
+ i--;
+ continue;
+ }
+ }
+ if (i == bufsize)
+ return E_CONF_MEM;
+ buf[i] = '\0';
+ return i;
+}
+
+/*
+ * Looks for a matching command on a line
+ */
+int
+conf_dispatch(char *line)
+{
+ int i, last_match = -1, matched = 0;
+ char *command, *nline = line;
+
+ if (strlen(line) == 0 || line[0] == '#')
+ return E_CONF_OK;
+ command = NextCommand(nline);
+ for (i = 0; main_commands[i].func != NULL; i++)
+ if (strncasecmp(main_commands[i].com, command,
+ strlen(command)) == 0) {
+ matched++;
+ last_match = i;
+ }
+ if (matched == 0)
+ return E_CONF_NOMATCH;
+ else if (matched > 1)
+ return E_CONF_AMBIGUOUS;
+
+ if (checkeol(nline) != 0)
+ return E_CONF_PARAM;
+ return main_commands[last_match].func(nline);
+}
+
+/*
+ * Checks if a line is terminated or else if it contains
+ * a start block bracket. If it's semicolon terminated
+ * then trim it.
+ */
+int
+checkeol(char *line)
+{
+ if (line[strlen(line) - 1] == ';') {
+ line[strlen(line) - 1] = '\0';
+ return 0;
+ }
+ for (uint i = 0; i < strlen(line); i++)
+ if (line[i] == '{')
+ return 0;
+ return -1;
+}
+
+/*
+ * Sets hello time
+ */
+int
+Fhellotime(char *line)
+{
+ int ht = atoi(line);
+ if (ht <= 0)
+ return E_CONF_PARAM;
+ ldp_hello_time = ht;
+ return 0;
+}
+
+/*
+ * Sets command port
+ */
+int
+Fport(char *line)
+{
+ int cp = atoi(line);
+ if (cp <= 0 || cp > 65535)
+ return E_CONF_PARAM;
+ command_port = cp;
+ return 0;
+}
+
+/*
+ * Sets neighbour keepalive
+ */
+int
+Fkeepalive(char *line)
+{
+ int kt = atoi(line);
+ if (kt <= 0)
+ return E_CONF_PARAM;
+ ldp_keepalive_time = kt;
+ return 0;
+}
+
+/*
+ * Sets neighbour holddown timer
+ */
+int
+Fholddown(char *line)
+{
+ int hdt = atoi(line);
+ if (hdt <= 0)
+ return E_CONF_PARAM;
+ ldp_holddown_time = hdt;
+ return 0;
+}
+
+int
+Fminlabel(char *line)
+{
+ int ml = atoi(line);
+ if (ml <= 0)
+ return E_CONF_PARAM;
+ min_label = ml;
+ return 0;
+}
+
+int
+Fmaxlabel(char *line)
+{
+ int ml = atoi(line);
+ if (ml <= 0)
+ return E_CONF_PARAM;
+ max_label = ml;
+ return 0;
+}
+
+int
+Fldpid(char *line)
+{
+ if (inet_pton(AF_INET, line, &conf_ldp_id) != 1)
+ return E_CONF_PARAM;
+ return 0;
+}
+
+int
+Fneighbour(char *line)
+{
+ char *peer;
+ struct conf_neighbour *nei;
+ struct in_addr ad;
+ char buf[1024];
+
+ peer = NextCommand(line);
+ if (inet_pton(AF_INET, peer, &ad) != 1)
+ return E_CONF_PARAM;
+
+ nei = calloc(1, sizeof(*nei));
+ nei->address.s_addr = ad.s_addr;
+ SLIST_INSERT_HEAD(&conei_head, nei, neilist);
+
+ while(conf_readline(buf, sizeof(buf)) >= 0) {
+ if (buf[0] == '}')
+ return 0;
+ if (Gneighbour(nei, buf) == -1)
+ return -1;
+ }
+ return -1;
+}
+
+/*
+ * neighbour { } sub-commands
+ */
+int
+Gneighbour(struct conf_neighbour *nei, char *line)
+{
+ if (strncasecmp("authenticate", line, 12) == 0) {
+ nei->authenticate = 1;
+ return 0;
+ }
+ return -1;
+}
Index: src/usr.sbin/ldpd/conffile.h
diff -u /dev/null src/usr.sbin/ldpd/conffile.h:1.1
--- /dev/null Thu Dec 30 11:29:22 2010
+++ src/usr.sbin/ldpd/conffile.h Thu Dec 30 11:29:21 2010
@@ -0,0 +1,56 @@
+/* $NetBSD: conffile.h,v 1.1 2010/12/30 11:29:21 kefren Exp $ */
+
+/*
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Mihai Chelaru <[email protected]>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __CONFFILE_H
+#define __CONFFILE_H
+
+#include <netinet/in.h>
+#include <sys/queue.h>
+
+#define E_CONF_OK 0
+#define E_CONF_NOMATCH -1
+#define E_CONF_AMBIGUOUS -2
+#define E_CONF_IO -3
+#define E_CONF_MEM -4
+#define E_CONF_GENERIC -5
+#define E_CONF_PARAM -6
+
+struct conf_neighbour {
+ struct in_addr address;
+ int authenticate; /* RFC 2385 */
+ SLIST_ENTRY(conf_neighbour) neilist;
+};
+SLIST_HEAD(,conf_neighbour) conei_head;
+
+
+int conf_parsefile(char *fname);
+
+#endif