diff options
author | 2013-06-04 02:25:28 +0000 | |
---|---|---|
committer | 2013-06-04 02:25:28 +0000 | |
commit | 83dcf7379d84ec59098a3fd7e0cc9e7c08f87ce3 (patch) | |
tree | 62a39a40a0fb33ec6939ef10bf800f2ffd0453fa | |
parent | Since we now have shm_{open,unlink}(), add the S_TYPEIS{MQ,SEM,SHM}() (diff) | |
download | wireguard-openbsd-83dcf7379d84ec59098a3fd7e0cc9e7c08f87ce3.tar.xz wireguard-openbsd-83dcf7379d84ec59098a3fd7e0cc9e7c08f87ce3.zip |
Implement support for adjacencies and targeted hellos
Refactor adjacencies out of the neighbor handling so that it is possible to
have more complex topologies with targeted sessions.
From Renato Westphal
-rw-r--r-- | usr.sbin/ldpd/Makefile | 4 | ||||
-rw-r--r-- | usr.sbin/ldpd/control.c | 5 | ||||
-rw-r--r-- | usr.sbin/ldpd/hello.c | 142 | ||||
-rw-r--r-- | usr.sbin/ldpd/interface.c | 11 | ||||
-rw-r--r-- | usr.sbin/ldpd/ldp.h | 7 | ||||
-rw-r--r-- | usr.sbin/ldpd/ldpd.c | 4 | ||||
-rw-r--r-- | usr.sbin/ldpd/ldpd.conf.5 | 45 | ||||
-rw-r--r-- | usr.sbin/ldpd/ldpd.h | 59 | ||||
-rw-r--r-- | usr.sbin/ldpd/ldpe.c | 50 | ||||
-rw-r--r-- | usr.sbin/ldpd/ldpe.h | 52 | ||||
-rw-r--r-- | usr.sbin/ldpd/log.c | 4 | ||||
-rw-r--r-- | usr.sbin/ldpd/neighbor.c | 64 | ||||
-rw-r--r-- | usr.sbin/ldpd/packet.c | 32 | ||||
-rw-r--r-- | usr.sbin/ldpd/parse.y | 159 | ||||
-rw-r--r-- | usr.sbin/ldpd/printconf.c | 28 |
15 files changed, 464 insertions, 202 deletions
diff --git a/usr.sbin/ldpd/Makefile b/usr.sbin/ldpd/Makefile index 792177b68fd..3ccc3e7b136 100644 --- a/usr.sbin/ldpd/Makefile +++ b/usr.sbin/ldpd/Makefile @@ -1,7 +1,7 @@ -# $OpenBSD: Makefile,v 1.4 2012/04/12 17:33:43 claudio Exp $ +# $OpenBSD: Makefile,v 1.5 2013/06/04 02:25:28 claudio Exp $ PROG= ldpd -SRCS= accept.c address.c control.c hello.c init.c interface.c \ +SRCS= accept.c adjacency.c address.c control.c hello.c init.c interface.c \ keepalive.c kroute.c labelmapping.c lde.c lde_lib.c ldpd.c ldpe.c \ log.c neighbor.c notification.c packet.c parse.y printconf.c diff --git a/usr.sbin/ldpd/control.c b/usr.sbin/ldpd/control.c index 7b6aa47dcea..5da5b4d4c70 100644 --- a/usr.sbin/ldpd/control.c +++ b/usr.sbin/ldpd/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.11 2013/03/11 17:40:11 deraadt Exp $ */ +/* $OpenBSD: control.c,v 1.12 2013/06/04 02:25:28 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -248,6 +248,9 @@ control_dispatch_imsg(int fd, short event, void *bula) 0, -1, NULL, 0); } break; + case IMSG_CTL_SHOW_DISCOVERY: + ldpe_adj_ctl(c); + break; case IMSG_CTL_SHOW_LIB: c->iev.ibuf.pid = imsg.hdr.pid; ldpe_imsg_compose_lde(imsg.hdr.type, 0, imsg.hdr.pid, diff --git a/usr.sbin/ldpd/hello.c b/usr.sbin/ldpd/hello.c index 9d887ace5ad..f1145f0dc9e 100644 --- a/usr.sbin/ldpd/hello.c +++ b/usr.sbin/ldpd/hello.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hello.c,v 1.19 2013/06/04 00:56:49 claudio Exp $ */ +/* $OpenBSD: hello.c,v 1.20 2013/06/04 02:25:28 claudio Exp $ */ /* * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org> @@ -36,23 +36,42 @@ #include "log.h" #include "ldpe.h" +extern struct ldpd_conf *leconf; + int tlv_decode_hello_prms(char *, u_int16_t, u_int16_t *, u_int16_t *); int tlv_decode_opt_hello_prms(char *, u_int16_t, struct in_addr *, u_int32_t *); -int gen_hello_prms_tlv(struct iface *, struct ibuf *); -int gen_opt4_hello_prms_tlv(struct iface *, struct ibuf *); +int gen_hello_prms_tlv(struct ibuf *buf, u_int16_t, u_int16_t); +int gen_opt4_hello_prms_tlv(struct ibuf *, u_int16_t, u_int32_t); int -send_hello(struct iface *iface) +send_hello(enum hello_type type, struct iface *iface, struct tnbr *tnbr) { struct sockaddr_in dst; struct ibuf *buf; - u_int16_t size; + u_int16_t size, holdtime = 0, flags = 0; + int fd = 0; dst.sin_port = htons(LDP_PORT); dst.sin_family = AF_INET; dst.sin_len = sizeof(struct sockaddr_in); - inet_aton(AllRouters, &dst.sin_addr); + + switch (type) { + case HELLO_LINK: + inet_aton(AllRouters, &dst.sin_addr); + holdtime = iface->hello_holdtime; + flags = 0; + fd = iface->discovery_fd; + break; + case HELLO_TARGETED: + dst.sin_addr.s_addr = tnbr->addr.s_addr; + holdtime = tnbr->hello_holdtime; + flags = TARGETED_HELLO; + if (tnbr->flags & F_TNBR_CONFIGURED) + flags |= REQUEST_TARG_HELLO; + fd = tnbr->discovery_fd; + break; + } if ((buf = ibuf_open(LDP_MAX_LEN)) == NULL) fatal("send_hello"); @@ -67,10 +86,10 @@ send_hello(struct iface *iface) gen_msg_tlv(buf, MSG_TYPE_HELLO, size); - gen_hello_prms_tlv(iface, buf); - gen_opt4_hello_prms_tlv(iface, buf); + gen_hello_prms_tlv(buf, holdtime, flags); + gen_opt4_hello_prms_tlv(buf, TLV_TYPE_IPV4TRANSADDR, ldpe_router_id()); - send_packet(iface, buf->buf, buf->wpos, &dst); + send_packet(fd, iface, buf->buf, buf->wpos, &dst); ibuf_free(buf); return (0); @@ -81,12 +100,15 @@ recv_hello(struct iface *iface, struct in_addr src, char *buf, u_int16_t len) { struct ldp_msg hello; struct ldp_hdr ldp; - struct nbr *nbr = NULL; - struct in_addr address; + struct adj *adj; + struct nbr *nbr; struct in_addr lsr_id; + struct in_addr transport_addr; u_int32_t conf_number; u_int16_t holdtime, flags; int r; + struct hello_source source; + struct tnbr *tnbr = NULL; bcopy(buf, &ldp, sizeof(ldp)); buf += LDP_HDR_SIZE; @@ -105,15 +127,47 @@ recv_hello(struct iface *iface, struct in_addr src, char *buf, u_int16_t len) return; } + bzero(&source, sizeof(source)); + if (flags & TARGETED_HELLO) { + tnbr = tnbr_find(src); + if (!tnbr) { + if (!((flags & REQUEST_TARG_HELLO) && + leconf->flags & LDPD_FLAG_TH_ACCEPT)) + return; + + tnbr = tnbr_new(src, 0); + if (!tnbr) + return; + tnbr_init(leconf, tnbr); + LIST_INSERT_HEAD(&leconf->tnbr_list, tnbr, entry); + } + source.type = HELLO_TARGETED; + source.target = tnbr; + } else { + if (ldp.lspace_id != 0) { + log_debug("recv_hello: invalid label space " + "ID %s, interface %s", ldp.lspace_id, + iface->name); + return; + } + source.type = HELLO_LINK; + source.link.iface = iface; + source.link.src_addr.s_addr = src.s_addr; + } + buf += r; len -= r; - r = tlv_decode_opt_hello_prms(buf, len, &address, &conf_number); + r = tlv_decode_opt_hello_prms(buf, len, &transport_addr, + &conf_number); if (r == -1) { log_debug("recv_hello: neighbor %s: failed to decode " "optional params", inet_ntoa(lsr_id)); return; } + if (transport_addr.s_addr == INADDR_ANY) + transport_addr.s_addr = src.s_addr; + if (r != len) { log_debug("recv_hello: neighbor %s: unexpected data in message", inet_ntoa(lsr_id)); @@ -122,29 +176,46 @@ recv_hello(struct iface *iface, struct in_addr src, char *buf, u_int16_t len) nbr = nbr_find_ldpid(ldp.lsr_id); if (!nbr) { - struct in_addr a; - - if (address.s_addr == INADDR_ANY) - a = src; - else - a = address; - - nbr = nbr_new(lsr_id, a); - - /* set neighbor parameters */ - nbr->hello_type = flags; + /* create new adjacency and new neighbor */ + nbr = nbr_new(lsr_id, transport_addr); + adj = adj_new(nbr, &source, holdtime, transport_addr); + } else { + adj = adj_find(nbr, &source); + if (!adj) { + /* create new adjacency for existing neighbor */ + adj = adj_new(nbr, &source, holdtime, transport_addr); + + if (nbr->addr.s_addr != transport_addr.s_addr) + log_warnx("recv_hello: neighbor %s: multiple " + "adjacencies advertising different " + "transport addresses", inet_ntoa(lsr_id)); + } + } - /* XXX: lacks support for targeted hellos */ + /* always update the holdtime to properly handle runtime changes */ + switch (source.type) { + case HELLO_LINK: if (holdtime == 0) holdtime = LINK_DFLT_HOLDTIME; - - if (iface->holdtime < holdtime) - nbr->holdtime = iface->holdtime; + if (iface->hello_holdtime < holdtime) + adj->holdtime = iface->hello_holdtime; + else + adj->holdtime = holdtime; + break; + case HELLO_TARGETED: + if (holdtime == 0) + holdtime = TARGETED_DFLT_HOLDTIME; + if (tnbr->hello_holdtime < holdtime) + adj->holdtime = tnbr->hello_holdtime; else - nbr->holdtime = holdtime; + adj->holdtime = holdtime; + break; } - nbr_fsm(nbr, NBR_EVT_HELLO_RCVD); + if (adj->holdtime != INFINITE_HOLDTIME) + adj_start_itimer(adj); + else + adj_stop_itimer(adj); if (nbr->state == NBR_STA_PRESENT && nbr_session_active_role(nbr) && !nbr_pending_connect(nbr) && !nbr_pending_idtimer(nbr)) @@ -152,29 +223,28 @@ recv_hello(struct iface *iface, struct in_addr src, char *buf, u_int16_t len) } int -gen_hello_prms_tlv(struct iface *iface, struct ibuf *buf) +gen_hello_prms_tlv(struct ibuf *buf, u_int16_t holdtime, u_int16_t flags) { struct hello_prms_tlv parms; bzero(&parms, sizeof(parms)); parms.type = htons(TLV_TYPE_COMMONHELLO); parms.length = htons(sizeof(parms.holdtime) + sizeof(parms.flags)); - /* XXX */ - parms.holdtime = htons(iface->holdtime); - parms.flags = 0; + parms.holdtime = htons(holdtime); + parms.flags = htons(flags); return (ibuf_add(buf, &parms, sizeof(parms))); } int -gen_opt4_hello_prms_tlv(struct iface *iface, struct ibuf *buf) +gen_opt4_hello_prms_tlv(struct ibuf *buf, u_int16_t type, u_int32_t value) { struct hello_prms_opt4_tlv parms; bzero(&parms, sizeof(parms)); - parms.type = htons(TLV_TYPE_IPV4TRANSADDR); + parms.type = htons(type); parms.length = htons(4); - parms.value = ldpe_router_id(); + parms.value = value; return (ibuf_add(buf, &parms, sizeof(parms))); } diff --git a/usr.sbin/ldpd/interface.c b/usr.sbin/ldpd/interface.c index 2e91f158cb7..7c86d2b66f2 100644 --- a/usr.sbin/ldpd/interface.c +++ b/usr.sbin/ldpd/interface.c @@ -1,4 +1,4 @@ -/* $OpenBSD: interface.c,v 1.16 2013/06/04 00:41:18 claudio Exp $ */ +/* $OpenBSD: interface.c,v 1.17 2013/06/04 02:25:28 claudio Exp $ */ /* * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> @@ -167,12 +167,17 @@ if_new(struct kif *kif) void if_del(struct iface *iface) { + struct adj *adj; struct if_addr *if_addr; log_debug("if_del: interface %s", iface->name); if_stop_hello_timer(iface); + while ((adj = LIST_FIRST(&iface->adj_list)) != NULL) { + LIST_REMOVE(adj, iface_entry); + adj_del(adj); + } while ((if_addr = LIST_FIRST(&iface->addr_list)) != NULL) LIST_REMOVE(if_addr, iface_entry); @@ -208,7 +213,7 @@ if_hello_timer(int fd, short event, void *arg) struct iface *iface = arg; struct timeval tv; - send_hello(iface); + send_hello(HELLO_LINK, iface, NULL); /* reschedule hello_timer */ timerclear(&tv); @@ -307,7 +312,7 @@ if_to_ctl(struct iface *iface) ictl.state = iface->state; ictl.mtu = iface->mtu; ictl.baudrate = iface->baudrate; - ictl.holdtime = iface->holdtime; + ictl.holdtime = iface->hello_holdtime; ictl.hello_interval = iface->hello_interval; ictl.flags = iface->flags; ictl.type = iface->type; diff --git a/usr.sbin/ldpd/ldp.h b/usr.sbin/ldpd/ldp.h index 115d23deae8..910b7be825c 100644 --- a/usr.sbin/ldpd/ldp.h +++ b/usr.sbin/ldpd/ldp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ldp.h,v 1.12 2013/06/04 01:32:16 claudio Exp $ */ +/* $OpenBSD: ldp.h,v 1.13 2013/06/04 02:25:28 claudio Exp $ */ /* * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org> @@ -33,8 +33,6 @@ #define LINK_DFLT_HOLDTIME 15 #define TARGETED_DFLT_HOLDTIME 45 - -#define DEFAULT_HOLDTIME 15 #define MIN_HOLDTIME 1 #define MAX_HOLDTIME 0xffff #define INFINITE_HOLDTIME 0xffff @@ -46,11 +44,10 @@ #define DEFAULT_HELLO_INTERVAL 5 #define MIN_HELLO_INTERVAL 1 -#define MAX_HELLO_INTERVAL 0xffff /* XXX */ +#define MAX_HELLO_INTERVAL 0xffff #define INIT_DELAY_TMR 15 #define MAX_DELAY_TMR 120 -#define DEFAULT_NBR_TMOUT 86400 /* 24 hours */ /* LDP message types */ #define MSG_TYPE_NOTIFICATION 0x0001 diff --git a/usr.sbin/ldpd/ldpd.c b/usr.sbin/ldpd/ldpd.c index c2f3b5d3517..9d53b5c13cd 100644 --- a/usr.sbin/ldpd/ldpd.c +++ b/usr.sbin/ldpd/ldpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ldpd.c,v 1.16 2013/06/03 16:53:49 claudio Exp $ */ +/* $OpenBSD: ldpd.c,v 1.17 2013/06/04 02:25:28 claudio Exp $ */ /* * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> @@ -296,8 +296,6 @@ ldpd_shutdown(void) free(iev_ldpe); msgbuf_clear(&iev_lde->ibuf.w); free(iev_lde); - - close(ldpd_conf->ldp_session_socket); free(ldpd_conf); log_info("terminating"); diff --git a/usr.sbin/ldpd/ldpd.conf.5 b/usr.sbin/ldpd/ldpd.conf.5 index 4f3d72eb6cc..71d4f3010d5 100644 --- a/usr.sbin/ldpd/ldpd.conf.5 +++ b/usr.sbin/ldpd/ldpd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ldpd.conf.5,v 1.12 2013/06/01 20:07:07 jmc Exp $ +.\" $OpenBSD: ldpd.conf.5,v 1.13 2013/06/04 02:25:28 claudio Exp $ .\" .\" Copyright (c) 2009 Michele Marchetto <michele@openbsd.org> .\" Copyright (c) 2005, 2006 Esben Norby <norby@openbsd.org> @@ -18,7 +18,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: June 1 2013 $ +.Dd $Mdocdate: June 4 2013 $ .Dt LDPD.CONF 5 .Os .Sh NAME @@ -31,7 +31,7 @@ daemon implements the Label Distribution Protocol as described in RFC 5036. .Sh SECTIONS The .Nm -config file is divided into three main sections. +config file is divided into four main sections. .Bl -tag -width xxxx .It Sy Macros User-defined variables may be defined and used later, simplifying the @@ -41,6 +41,8 @@ Global settings for .Xr ldpd 8 . .It Sy Interfaces Configuration Interface-specific parameters. +.It Sy Targeted neighbors Configuration +Targeted neighbor specific parameters. .El .Sh MACROS Much like @@ -116,6 +118,17 @@ Select the advertisement mode. advertises labels according to the distribution mode; .Ic ondemand advertises labels solely upon explicit request from peers. +.Pp +.It Xo +.Ic targeted-hello-accept +.Pq Ic yes Ns | Ns Ic no +.Xc +If set to +.Ic yes , +allow LDP sessions to be established with remote neighbors that have not been +specifically configured. +The default is +.Ic no . .El .Sh INTERFACES Each interface can have several parameters configured individually, otherwise @@ -127,14 +140,36 @@ interface em0 { .Pp Interface-specific parameters are listed below. .Bl -tag -width Ds -.It Ic holdtime Ar seconds +.It Ic link-hello-holdtime Ar seconds Set the hello holdtime in seconds. The maximum time .Xr ldpd 8 will wait between two consecutive hello messages from a peer before it is marked as being down. The default value is 15. -.It Ic hello-interval Ar seconds +.It Ic link-hello-interval Ar seconds +Set the hello interval in seconds. +The default value is 5; valid range is 1\-65535. +.El +.Sh TARGETED NEIGHBORS +Each targeted neighbor can have several parameters configured individually, +otherwise they are inherited. +.Bd -literal -offset indent +targeted-neighbor A.B.C.D { +} +.Ed +.Pp +Targeted-neighbor specific parameters are listed below. +.Bl -tag -width Ds +.It Ic targeted-hello-holdtime Ar seconds +Set the hello holdtime in seconds. +The maximum time +.Xr ldpd 8 +will wait between two consecutive hello messages from a peer before it is +marked as being down. +The default value is 45. +.Pp +.It Ic targeted-hello-interval Ar seconds Set the hello interval in seconds. The default value is 5; valid range is 1\-65535. .El diff --git a/usr.sbin/ldpd/ldpd.h b/usr.sbin/ldpd/ldpd.h index 156ca1d437f..b1e4da33580 100644 --- a/usr.sbin/ldpd/ldpd.h +++ b/usr.sbin/ldpd/ldpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ldpd.h,v 1.39 2013/06/04 00:56:49 claudio Exp $ */ +/* $OpenBSD: ldpd.h,v 1.40 2013/06/04 02:25:28 claudio Exp $ */ /* * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org> @@ -45,6 +45,7 @@ #define LDP_BACKLOG 128 #define LDPD_FLAG_NO_FIB_UPDATE 0x0001 +#define LDPD_FLAG_TH_ACCEPT 0x0002 #define F_LDPD_INSERTED 0x0001 #define F_CONNECTED 0x0002 @@ -71,6 +72,7 @@ enum imsg_type { IMSG_NONE, IMSG_CTL_RELOAD, IMSG_CTL_SHOW_INTERFACE, + IMSG_CTL_SHOW_DISCOVERY, IMSG_CTL_SHOW_NBR, IMSG_CTL_SHOW_LIB, IMSG_CTL_FIB_COUPLE, @@ -140,20 +142,17 @@ enum iface_type { }; /* neighbor states */ -#define NBR_STA_DOWN 0x0001 -#define NBR_STA_PRESENT 0x0002 -#define NBR_STA_INITIAL 0x0004 -#define NBR_STA_OPENREC 0x0008 -#define NBR_STA_OPENSENT 0x0010 -#define NBR_STA_OPER 0x0020 -#define NBR_STA_SESSION (NBR_STA_PRESENT | NBR_STA_INITIAL | \ - NBR_STA_OPENREC | NBR_STA_OPENSENT | \ - NBR_STA_OPER) +#define NBR_STA_PRESENT 0x0001 +#define NBR_STA_INITIAL 0x0002 +#define NBR_STA_OPENREC 0x0004 +#define NBR_STA_OPENSENT 0x0008 +#define NBR_STA_OPER 0x0010 +#define NBR_STA_SESSION (NBR_STA_INITIAL | NBR_STA_OPENREC | \ + NBR_STA_OPENSENT | NBR_STA_OPER) /* neighbor events */ enum nbr_event { NBR_EVT_NOTHING, - NBR_EVT_HELLO_RCVD, NBR_EVT_CONNECT_UP, NBR_EVT_CLOSE_SESSION, NBR_EVT_INIT_RCVD, @@ -166,8 +165,6 @@ enum nbr_event { /* neighbor actions */ enum nbr_action { NBR_ACT_NOTHING, - NBR_ACT_STRT_ITIMER, - NBR_ACT_RST_ITIMER, NBR_ACT_RST_KTIMEOUT, NBR_ACT_SESSION_EST, NBR_ACT_RST_KTIMER, @@ -211,6 +208,7 @@ struct iface { char name[IF_NAMESIZE]; LIST_HEAD(, if_addr) addr_list; + LIST_HEAD(, adj) adj_list; u_int64_t baudrate; time_t uptime; @@ -219,7 +217,7 @@ struct iface { int session_fd; int state; int mtu; - u_int16_t holdtime; + u_int16_t hello_holdtime; u_int16_t hello_interval; u_int16_t flags; enum iface_type type; @@ -228,6 +226,20 @@ struct iface { u_int8_t priority; }; +/* source of targeted hellos */ +struct tnbr { + LIST_ENTRY(tnbr) entry; + struct event hello_timer; + int discovery_fd; + struct adj *adj; + struct in_addr addr; + + u_int16_t hello_holdtime; + u_int16_t hello_interval; + u_int8_t flags; +}; +#define F_TNBR_CONFIGURED 0x01 + /* ldp_conf */ enum { PROC_MAIN, @@ -240,6 +252,11 @@ enum blockmodes { BM_NONBLOCK }; +enum hello_type { + HELLO_LINK, + HELLO_TARGETED +}; + #define MODE_DIST_INDEPENDENT 0x01 #define MODE_DIST_ORDERED 0x02 #define MODE_RET_LIBERAL 0x04 @@ -249,9 +266,11 @@ enum blockmodes { struct ldpd_conf { struct event disc_ev; + struct event edisc_ev; struct in_addr rtr_id; LIST_HEAD(, iface) iface_list; LIST_HEAD(, if_addr) addr_list; + LIST_HEAD(, tnbr) tnbr_list; u_int32_t opts; #define LDPD_OPT_VERBOSE 0x00000001 @@ -259,10 +278,13 @@ struct ldpd_conf { #define LDPD_OPT_NOACTION 0x00000004 time_t uptime; int ldp_discovery_socket; + int ldp_ediscovery_socket; int ldp_session_socket; int flags; u_int8_t mode; u_int16_t keepalive; + u_int16_t thello_holdtime; + u_int16_t thello_interval; }; /* kroute */ @@ -321,12 +343,19 @@ struct ctl_iface { u_int8_t priority; }; +struct ctl_adj { + struct in_addr id; + enum hello_type type; + char ifname[IF_NAMESIZE]; + struct in_addr src_addr; + u_int16_t holdtime; +}; + struct ctl_nbr { struct in_addr id; struct in_addr addr; struct in_addr dr; struct in_addr bdr; - time_t dead_timer; time_t uptime; u_int32_t db_sum_lst_cnt; u_int32_t ls_req_lst_cnt; diff --git a/usr.sbin/ldpd/ldpe.c b/usr.sbin/ldpd/ldpe.c index a461db7dbb4..b20585e800c 100644 --- a/usr.sbin/ldpd/ldpe.c +++ b/usr.sbin/ldpd/ldpe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ldpe.c,v 1.20 2013/06/04 00:45:00 claudio Exp $ */ +/* $OpenBSD: ldpe.c,v 1.21 2013/06/04 02:25:28 claudio Exp $ */ /* * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> @@ -73,6 +73,7 @@ ldpe(struct ldpd_conf *xconf, int pipe_parent2ldpe[2], int pipe_ldpe2lde[2], int pipe_parent2lde[2]) { struct iface *iface; + struct tnbr *tnbr; struct passwd *pw; struct event ev_sigint, ev_sigterm; struct sockaddr_in disc_addr, sess_addr; @@ -105,6 +106,9 @@ ldpe(struct ldpd_conf *xconf, int pipe_parent2ldpe[2], int pipe_ldpe2lde[2], IPPROTO_UDP)) == -1) fatal("error creating discovery socket"); + if (if_set_reuse(xconf->ldp_discovery_socket, 1) == -1) + fatal("if_set_reuse"); + if (bind(xconf->ldp_discovery_socket, (struct sockaddr *)&disc_addr, sizeof(disc_addr)) == -1) fatal("error binding discovery socket"); @@ -122,6 +126,30 @@ ldpe(struct ldpd_conf *xconf, int pipe_parent2ldpe[2], int pipe_ldpe2lde[2], fatal("if_set_recvif"); if_set_recvbuf(xconf->ldp_discovery_socket); + /* create the extended discovery UDP socket */ + disc_addr.sin_family = AF_INET; + disc_addr.sin_port = htons(LDP_PORT); + disc_addr.sin_addr.s_addr = xconf->rtr_id.s_addr; + + if ((xconf->ldp_ediscovery_socket = socket(AF_INET, SOCK_DGRAM, + IPPROTO_UDP)) == -1) + fatal("error creating extended discovery socket"); + + if (if_set_reuse(xconf->ldp_ediscovery_socket, 1) == -1) + fatal("if_set_reuse"); + + if (bind(xconf->ldp_ediscovery_socket, (struct sockaddr *)&disc_addr, + sizeof(disc_addr)) == -1) + fatal("error binding extended discovery socket"); + + /* set some defaults */ + if (if_set_tos(xconf->ldp_ediscovery_socket, + IPTOS_PREC_INTERNETCONTROL) == -1) + fatal("if_set_tos"); + if (if_set_recvif(xconf->ldp_ediscovery_socket, 1) == -1) + fatal("if_set_recvif"); + if_set_recvbuf(xconf->ldp_ediscovery_socket); + /* create the session TCP socket */ sess_addr.sin_family = AF_INET; sess_addr.sin_port = htons(LDP_PORT); @@ -197,10 +225,14 @@ ldpe(struct ldpd_conf *xconf, int pipe_parent2ldpe[2], int pipe_ldpe2lde[2], event_add(&iev_main->ev, NULL); event_set(&leconf->disc_ev, leconf->ldp_discovery_socket, - EV_READ|EV_PERSIST, disc_recv_packet, leconf); + EV_READ|EV_PERSIST, disc_recv_packet, NULL); event_add(&leconf->disc_ev, NULL); - accept_add(leconf->ldp_session_socket, session_accept, leconf); + event_set(&leconf->edisc_ev, leconf->ldp_ediscovery_socket, + EV_READ|EV_PERSIST, disc_recv_packet, NULL); + event_add(&leconf->edisc_ev, NULL); + + accept_add(leconf->ldp_session_socket, session_accept, NULL); /* listen on ldpd control socket */ TAILQ_INIT(&ctl_conns); control_listen(); @@ -212,6 +244,10 @@ ldpe(struct ldpd_conf *xconf, int pipe_parent2ldpe[2], int pipe_ldpe2lde[2], LIST_FOREACH(iface, &leconf->iface_list, entry) if_init(xconf, iface); + /* start configured targeted neighbors */ + LIST_FOREACH(tnbr, &leconf->tnbr_list, entry) + tnbr_init(xconf, tnbr); + event_dispatch(); ldpe_shutdown(); @@ -223,6 +259,7 @@ void ldpe_shutdown(void) { struct iface *iface; + struct tnbr *tnbr; /* stop all interfaces */ while ((iface = LIST_FIRST(&leconf->iface_list)) != NULL) { @@ -234,7 +271,14 @@ ldpe_shutdown(void) if_del(iface); } + /* stop all targeted neighbors */ + while ((tnbr = LIST_FIRST(&leconf->tnbr_list)) != NULL) { + LIST_REMOVE(tnbr, entry); + tnbr_del(tnbr); + } + close(leconf->ldp_discovery_socket); + close(leconf->ldp_session_socket); /* clean up */ msgbuf_write(&iev_lde->ibuf.w); diff --git a/usr.sbin/ldpd/ldpe.h b/usr.sbin/ldpd/ldpe.h index ee70736ca29..33c68227f32 100644 --- a/usr.sbin/ldpd/ldpe.h +++ b/usr.sbin/ldpd/ldpe.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ldpe.h,v 1.24 2013/06/04 01:32:16 claudio Exp $ */ +/* $OpenBSD: ldpe.h,v 1.25 2013/06/04 02:25:28 claudio Exp $ */ /* * Copyright (c) 2004, 2005, 2008 Esben Norby <norby@openbsd.org> @@ -29,17 +29,31 @@ TAILQ_HEAD(ctl_conns, ctl_conn) ctl_conns; -struct mapping_entry { - TAILQ_ENTRY(mapping_entry) entry; - struct map map; +struct hello_source { + enum hello_type type; + struct { + struct iface *iface; + struct in_addr src_addr; + } link; + struct tnbr *target; +}; + +struct adj { + LIST_ENTRY(adj) nbr_entry; + LIST_ENTRY(adj) iface_entry; + struct nbr *nbr; + struct hello_source source; + struct event inactivity_timer; + u_int16_t holdtime; + struct in_addr addr; }; struct nbr { RB_ENTRY(nbr) id_tree, addr_tree, pid_tree; struct evbuf wbuf; struct event rev; + LIST_HEAD(, adj) adj_list; /* adjacencies */ struct event ev_connect; - struct event inactivity_timer; struct event keepalive_timer; struct event keepalive_timeout; struct event initdelay_timer; @@ -62,15 +76,17 @@ struct nbr { int state; int idtimer_cnt; - u_int16_t holdtime; u_int16_t keepalive; u_int8_t priority; u_int8_t options; u_int8_t flags; - u_int8_t hello_type; +}; +struct mapping_entry { + TAILQ_ENTRY(mapping_entry) entry; + struct map map; }; /* accept.c */ @@ -81,7 +97,7 @@ void accept_pause(void); void accept_unpause(void); /* hello.c */ -int send_hello(struct iface *); +int send_hello(enum hello_type, struct iface *, struct tnbr *); void recv_hello(struct iface *, struct in_addr, char *, u_int16_t); /* init.c */ @@ -146,6 +162,21 @@ int if_set_mcast_ttl(int, u_int8_t); int if_set_tos(int, int); int if_set_reuse(int, int); +/* adjacency.c */ +struct adj *adj_new(struct nbr *, struct hello_source *, u_int16_t, + struct in_addr); +void adj_del(struct adj *); +struct adj *adj_find(struct nbr *, struct hello_source *); +void adj_start_itimer(struct adj *); +void adj_stop_itimer(struct adj *); +struct tnbr *tnbr_new(struct in_addr, int); +void tnbr_del(struct tnbr *); +void tnbr_init(struct ldpd_conf *, struct tnbr *); +struct tnbr *tnbr_find(struct in_addr); + +struct ctl_adj *adj_to_ctl(struct adj *); +void ldpe_adj_ctl(struct ctl_conn *); + /* neighbor.c */ struct nbr *nbr_new(struct in_addr, struct in_addr); void nbr_del(struct nbr *); @@ -157,9 +188,6 @@ struct nbr *nbr_find_peerid(u_int32_t); int nbr_fsm(struct nbr *, enum nbr_event); int nbr_session_active_role(struct nbr *); -void nbr_itimer(int, short, void *); -void nbr_start_itimer(struct nbr *); -void nbr_stop_itimer(struct nbr *); void nbr_ktimer(int, short, void *); void nbr_start_ktimer(struct nbr *); void nbr_stop_ktimer(struct nbr *); @@ -190,7 +218,7 @@ void ldpe_nbr_ctl(struct ctl_conn *); /* packet.c */ int gen_ldp_hdr(struct ibuf *, u_int16_t); int gen_msg_tlv(struct ibuf *, u_int32_t, u_int16_t); -int send_packet(struct iface *, void *, size_t, struct sockaddr_in *); +int send_packet(int, struct iface *, void *, size_t, struct sockaddr_in *); void disc_recv_packet(int, short, void *); void session_accept(int, short, void *); diff --git a/usr.sbin/ldpd/log.c b/usr.sbin/ldpd/log.c index d6fcc67f9e8..4ef03995d5a 100644 --- a/usr.sbin/ldpd/log.c +++ b/usr.sbin/ldpd/log.c @@ -1,4 +1,4 @@ -/* $OpenBSD: log.c,v 1.11 2013/06/01 20:13:04 claudio Exp $ */ +/* $OpenBSD: log.c,v 1.12 2013/06/04 02:25:28 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -179,8 +179,6 @@ const char * nbr_state_name(int state) { switch (state) { - case NBR_STA_DOWN: - return ("DOWN"); case NBR_STA_PRESENT: return ("PRESENT"); case NBR_STA_INITIAL: diff --git a/usr.sbin/ldpd/neighbor.c b/usr.sbin/ldpd/neighbor.c index 13b2df1d0c4..f9ecb08b36b 100644 --- a/usr.sbin/ldpd/neighbor.c +++ b/usr.sbin/ldpd/neighbor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: neighbor.c,v 1.35 2013/06/04 01:32:16 claudio Exp $ */ +/* $OpenBSD: neighbor.c,v 1.36 2013/06/04 02:25:28 claudio Exp $ */ /* * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org> @@ -92,9 +92,6 @@ struct { int new_state; } nbr_fsm_tbl[] = { /* current state event that happened action to take resulting state */ -/* Discovery States */ - {NBR_STA_DOWN, NBR_EVT_HELLO_RCVD, NBR_ACT_STRT_ITIMER, NBR_STA_PRESENT}, - {NBR_STA_SESSION, NBR_EVT_HELLO_RCVD, NBR_ACT_RST_ITIMER, 0}, {NBR_STA_PRESENT, NBR_EVT_CONNECT_UP, NBR_ACT_CONNECT_SETUP, NBR_STA_INITIAL}, /* Passive Role */ {NBR_STA_INITIAL, NBR_EVT_INIT_RCVD, NBR_ACT_PASSIVE_INIT, NBR_STA_OPENREC}, @@ -106,13 +103,13 @@ struct { {NBR_STA_OPER, NBR_EVT_PDU_RCVD, NBR_ACT_RST_KTIMEOUT, 0}, {NBR_STA_OPER, NBR_EVT_PDU_SENT, NBR_ACT_RST_KTIMER, 0}, /* Session Close */ + {NBR_STA_PRESENT, NBR_EVT_CLOSE_SESSION, NBR_ACT_NOTHING, 0}, {NBR_STA_SESSION, NBR_EVT_CLOSE_SESSION, NBR_ACT_CLOSE_SESSION, NBR_STA_PRESENT}, {-1, NBR_EVT_NOTHING, NBR_ACT_NOTHING, 0}, }; const char * const nbr_event_names[] = { "NOTHING", - "HELLO RECEIVED", "CONNECTION UP", "SESSION CLOSE", "INIT RECEIVED", @@ -124,8 +121,6 @@ const char * const nbr_event_names[] = { const char * const nbr_action_names[] = { "NOTHING", - "START INACTIVITY TIMER", - "RESET INACTIVITY TIMER", "RESET KEEPALIVE TIMEOUT", "START NEIGHBOR SESSION", "RESET KEEPALIVE TIMER", @@ -178,13 +173,6 @@ nbr_fsm(struct nbr *nbr, enum nbr_event event) } switch (nbr_fsm_tbl[i].action) { - case NBR_ACT_RST_ITIMER: - case NBR_ACT_STRT_ITIMER: - if (nbr->holdtime != INFINITE_HOLDTIME) - nbr_start_itimer(nbr); - else - nbr_stop_itimer(nbr); - break; case NBR_ACT_RST_KTIMEOUT: nbr_start_ktimeout(nbr); break; @@ -240,7 +228,7 @@ nbr_new(struct in_addr id, struct in_addr addr) if ((nbr->rbuf = calloc(1, sizeof(struct ibuf_read))) == NULL) fatal("nbr_new"); - nbr->state = NBR_STA_DOWN; + nbr->state = NBR_STA_PRESENT; nbr->id.s_addr = id.s_addr; nbr->addr = addr; @@ -263,7 +251,6 @@ nbr_new(struct in_addr id, struct in_addr addr) TAILQ_INIT(&nbr->abortreq_list); /* set event structures */ - evtimer_set(&nbr->inactivity_timer, nbr_itimer, nbr); evtimer_set(&nbr->keepalive_timeout, nbr_ktimeout, nbr); evtimer_set(&nbr->keepalive_timer, nbr_ktimer, nbr); evtimer_set(&nbr->initdelay_timer, nbr_idtimer, nbr); @@ -280,7 +267,6 @@ nbr_del(struct nbr *nbr) if (event_pending(&nbr->ev_connect, EV_WRITE, NULL)) event_del(&nbr->ev_connect); - nbr_stop_itimer(nbr); nbr_stop_ktimer(nbr); nbr_stop_ktimeout(nbr); nbr_stop_idtimer(nbr); @@ -334,39 +320,6 @@ nbr_session_active_role(struct nbr *nbr) /* timers */ -/* Inactivity timer: timeout based on hellos */ -/* ARGSUSED */ -void -nbr_itimer(int fd, short event, void *arg) -{ - struct nbr *nbr = arg; - - log_debug("nbr_itimer: neighbor ID %s peerid %lu", inet_ntoa(nbr->id), - nbr->peerid); - - nbr_del(nbr); -} - -void -nbr_start_itimer(struct nbr *nbr) -{ - struct timeval tv; - - timerclear(&tv); - tv.tv_sec = nbr->holdtime; - - if (evtimer_add(&nbr->inactivity_timer, &tv) == -1) - fatal("nbr_start_itimer"); -} - -void -nbr_stop_itimer(struct nbr *nbr) -{ - if (evtimer_pending(&nbr->inactivity_timer, NULL) && - evtimer_del(&nbr->inactivity_timer) == -1) - fatal("nbr_stop_itimer"); -} - /* Keepalive timer: timer to send keepalive message to neighbors */ void @@ -672,22 +625,13 @@ struct ctl_nbr * nbr_to_ctl(struct nbr *nbr) { static struct ctl_nbr nctl; - struct timeval tv, now, res; + struct timeval now; memcpy(&nctl.id, &nbr->id, sizeof(nctl.id)); memcpy(&nctl.addr, &nbr->addr, sizeof(nctl.addr)); nctl.nbr_state = nbr->state; gettimeofday(&now, NULL); - if (evtimer_pending(&nbr->inactivity_timer, &tv)) { - timersub(&tv, &now, &res); - if (nbr->state & NBR_STA_DOWN) - nctl.dead_timer = DEFAULT_NBR_TMOUT - res.tv_sec; - else - nctl.dead_timer = res.tv_sec; - } else - nctl.dead_timer = 0; - if (nbr->state == NBR_STA_OPER) { nctl.uptime = now.tv_sec - nbr->uptime; } else diff --git a/usr.sbin/ldpd/packet.c b/usr.sbin/ldpd/packet.c index 87b6b4aa106..98637b8d769 100644 --- a/usr.sbin/ldpd/packet.c +++ b/usr.sbin/ldpd/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.25 2013/06/03 16:53:49 claudio Exp $ */ +/* $OpenBSD: packet.c,v 1.26 2013/06/04 02:25:28 claudio Exp $ */ /* * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org> @@ -81,22 +81,22 @@ gen_msg_tlv(struct ibuf *buf, u_int32_t type, u_int16_t size) return (ibuf_add(buf, &msg, sizeof(msg))); } -/* send and receive packets */ +/* send packets */ int -send_packet(struct iface *iface, void *pkt, size_t len, struct sockaddr_in *dst) +send_packet(int fd, struct iface *iface, void *pkt, size_t len, + struct sockaddr_in *dst) { /* set outgoing interface for multicast traffic */ - if (IN_MULTICAST(ntohl(dst->sin_addr.s_addr))) + if (iface && IN_MULTICAST(ntohl(dst->sin_addr.s_addr))) if (if_set_mcast(iface) == -1) { log_warn("send_packet: error setting multicast " "interface, %s", iface->name); return (-1); } - if (sendto(iface->discovery_fd, pkt, len, 0, - (struct sockaddr *)dst, sizeof(*dst)) == -1) { - log_warn("send_packet: error sending packet on interface %s", - iface->name); + if (sendto(fd, pkt, len, 0, (struct sockaddr *)dst, + sizeof(*dst)) == -1) { + log_warn("send_packet: error sending packet"); return (-1); } @@ -116,7 +116,7 @@ disc_recv_packet(int fd, short event, void *bula) struct iovec iov; struct ldp_hdr ldp_hdr; struct ldp_msg ldp_msg; - struct iface *iface; + struct iface *iface = NULL; char *buf; struct cmsghdr *cmsg; ssize_t r; @@ -156,7 +156,8 @@ disc_recv_packet(int fd, short event, void *bula) len = (u_int16_t)r; /* find a matching interface */ - if ((iface = disc_find_iface(ifindex, src.sin_addr)) == NULL) { + if ((fd == leconf->ldp_discovery_socket) && + (iface = disc_find_iface(ifindex, src.sin_addr)) == NULL) { log_debug("disc_recv_packet: cannot find a matching interface"); return; } @@ -174,13 +175,6 @@ disc_recv_packet(int fd, short event, void *bula) return; } - if (ldp_hdr.lspace_id != 0) { - log_debug("disc_recv_packet: invalid label space " - "ID %s, interface %s", ldp_hdr.lspace_id, - iface->name); - return; - } - if (ntohs(ldp_hdr.length) > len - sizeof(ldp_hdr.version) - sizeof(ldp_hdr.length)) { log_debug("disc_recv_packet: invalid LDP packet length %u", @@ -202,8 +196,8 @@ disc_recv_packet(int fd, short event, void *bula) recv_hello(iface, src.sin_addr, buf, len); break; default: - log_debug("recv_packet: unknown LDP packet type, interface %s", - iface->name); + log_debug("recv_packet: unknown LDP packet type, source %s", + inet_ntoa(src.sin_addr)); } } diff --git a/usr.sbin/ldpd/parse.y b/usr.sbin/ldpd/parse.y index fa66d961121..e6130b2d1a4 100644 --- a/usr.sbin/ldpd/parse.y +++ b/usr.sbin/ldpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.16 2013/06/03 16:58:14 claudio Exp $ */ +/* $OpenBSD: parse.y,v 1.17 2013/06/04 02:25:28 claudio Exp $ */ /* * Copyright (c) 2004, 2005, 2008 Esben Norby <norby@openbsd.org> @@ -84,17 +84,22 @@ static struct ldpd_conf *conf; static int errors = 0; struct iface *iface = NULL; +struct tnbr *tnbr = NULL; struct config_defaults { - u_int16_t holdtime; - u_int16_t hello_interval; + u_int16_t lhello_holdtime; + u_int16_t lhello_interval; + u_int16_t thello_holdtime; + u_int16_t thello_interval; }; struct config_defaults globaldefs; struct config_defaults ifacedefs; +struct config_defaults tnbrdefs; struct config_defaults *defs; struct iface *conf_get_if(struct kif *); +struct tnbr *conf_get_tnbr(struct in_addr); typedef struct { union { @@ -106,11 +111,13 @@ typedef struct { %} -%token INTERFACE ROUTERID FIBUPDATE -%token HOLDTIME HELLOINTERVAL KEEPALIVE +%token INTERFACE TNEIGHBOR ROUTERID FIBUPDATE +%token LHELLOHOLDTIME LHELLOINTERVAL +%token THELLOHOLDTIME THELLOINTERVAL +%token THELLOACCEPT +%token KEEPALIVE %token DISTRIBUTION RETENTION ADVERTISEMENT %token EXTTAG -%token HELLOINTERVAL %token YES NO %token ERROR %token <v.string> STRING @@ -125,6 +132,7 @@ grammar : /* empty */ | grammar conf_main '\n' | grammar varset '\n' | grammar interface '\n' + | grammar tneighbor '\n' | grammar error '\n' { file->errors++; } ; @@ -211,6 +219,12 @@ conf_main : ROUTERID STRING { YYERROR; } } + | THELLOACCEPT yesno { + if ($2 == 0) + conf->flags &= ~LDPD_FLAG_TH_ACCEPT; + else + conf->flags |= LDPD_FLAG_TH_ACCEPT; + } | KEEPALIVE NUMBER { if ($2 < MIN_KEEPALIVE || $2 > MAX_KEEPALIVE) { @@ -220,25 +234,48 @@ conf_main : ROUTERID STRING { } conf->keepalive = $2; } - | defaults + | iface_defaults + | tnbr_defaults ; -defaults : HOLDTIME NUMBER { +iface_defaults : LHELLOHOLDTIME NUMBER { if ($2 < MIN_HOLDTIME || $2 > MAX_HOLDTIME) { - yyerror("holdtime out of range (%d-%d)", + yyerror("hello holdtime out of range (%d-%d)", MIN_HOLDTIME, MAX_HOLDTIME); YYERROR; } - defs->holdtime = $2; + defs->lhello_holdtime = $2; } - | HELLOINTERVAL NUMBER { + | LHELLOINTERVAL NUMBER { if ($2 < MIN_HELLO_INTERVAL || $2 > MAX_HELLO_INTERVAL) { yyerror("hello-interval out of range (%d-%d)", MIN_HELLO_INTERVAL, MAX_HELLO_INTERVAL); YYERROR; } - defs->hello_interval = $2; + defs->lhello_interval = $2; + } + ; + +tnbr_defaults : THELLOHOLDTIME NUMBER { + if ($2 < MIN_HOLDTIME || + $2 > MAX_HOLDTIME) { + yyerror("hello holdtime out of range (%d-%d)", + MIN_HOLDTIME, MAX_HOLDTIME); + YYERROR; + } + conf->thello_holdtime = $2; + defs->thello_holdtime = $2; + } + | THELLOINTERVAL NUMBER { + if ($2 < MIN_HELLO_INTERVAL || + $2 > MAX_HELLO_INTERVAL) { + yyerror("hello-interval out of range (%d-%d)", + MIN_HELLO_INTERVAL, MAX_HELLO_INTERVAL); + YYERROR; + } + conf->thello_interval = $2; + defs->thello_interval = $2; } ; @@ -272,8 +309,8 @@ interface : INTERFACE STRING { memcpy(&ifacedefs, defs, sizeof(ifacedefs)); defs = &ifacedefs; } interface_block { - iface->holdtime = defs->holdtime; - iface->hello_interval = defs->hello_interval; + iface->hello_holdtime = defs->lhello_holdtime; + iface->hello_interval = defs->lhello_interval; iface = NULL; defs = &globaldefs; @@ -285,8 +322,44 @@ interface_block : '{' optnl interfaceopts_l '}' | /* nothing */ ; -interfaceopts_l : interfaceopts_l defaults nl - | defaults optnl +interfaceopts_l : interfaceopts_l iface_defaults nl + | iface_defaults optnl + ; + +tneighbor : TNEIGHBOR STRING { + struct in_addr addr; + + if (inet_aton($2, &addr) == 0) { + yyerror( + "error parsing neighbor address"); + free($2); + YYERROR; + } + free($2); + + tnbr = conf_get_tnbr(addr); + if (tnbr == NULL) + YYERROR; + LIST_INSERT_HEAD(&conf->tnbr_list, tnbr, entry); + + memcpy(&tnbrdefs, defs, sizeof(tnbrdefs)); + defs = &tnbrdefs; + } tneighbor_block { + tnbr->hello_holdtime = defs->thello_holdtime; + tnbr->hello_interval = defs->thello_interval; + tnbr = NULL; + + defs = &globaldefs; + } + ; + +tneighbor_block : '{' optnl tneighboropts_l '}' + | '{' optnl '}' + | /* nothing */ + ; + +tneighboropts_l : tneighboropts_l tnbr_defaults nl + | tnbr_defaults optnl ; %% @@ -323,18 +396,22 @@ lookup(char *s) { /* this has to be sorted always */ static const struct keywords keywords[] = { - {"advertisement", ADVERTISEMENT}, - {"distribution", DISTRIBUTION}, - {"external-tag", EXTTAG}, - {"fib-update", FIBUPDATE}, - {"hello-interval", HELLOINTERVAL}, - {"holdtime", HOLDTIME}, - {"interface", INTERFACE}, - {"keepalive", KEEPALIVE}, - {"no", NO}, - {"retention", RETENTION}, - {"router-id", ROUTERID}, - {"yes", YES} + {"advertisement", ADVERTISEMENT}, + {"distribution", DISTRIBUTION}, + {"external-tag", EXTTAG}, + {"fib-update", FIBUPDATE}, + {"interface", INTERFACE}, + {"keepalive", KEEPALIVE}, + {"link-hello-holdtime", LHELLOHOLDTIME}, + {"link-hello-interval", LHELLOINTERVAL}, + {"no", NO}, + {"retention", RETENTION}, + {"router-id", ROUTERID}, + {"targeted-hello-accept", THELLOACCEPT}, + {"targeted-hello-holdtime", THELLOHOLDTIME}, + {"targeted-hello-interval", THELLOINTERVAL}, + {"targeted-neighbor", TNEIGHBOR}, + {"yes", YES} }; const struct keywords *p; @@ -664,8 +741,12 @@ parse_config(char *filename, int opts) bzero(&globaldefs, sizeof(globaldefs)); defs = &globaldefs; - defs->holdtime = DEFAULT_HOLDTIME; - defs->hello_interval = DEFAULT_HELLO_INTERVAL; + defs->lhello_holdtime = LINK_DFLT_HOLDTIME; + defs->lhello_interval = DEFAULT_HELLO_INTERVAL; + defs->thello_holdtime = TARGETED_DFLT_HOLDTIME; + defs->thello_interval = DEFAULT_HELLO_INTERVAL; + conf->thello_holdtime = TARGETED_DFLT_HOLDTIME; + conf->thello_interval = DEFAULT_HELLO_INTERVAL; conf->mode = (MODE_DIST_INDEPENDENT | MODE_RET_LIBERAL | MODE_ADV_UNSOLICITED); @@ -798,6 +879,24 @@ conf_get_if(struct kif *kif) return (i); } +struct tnbr * +conf_get_tnbr(struct in_addr addr) +{ + struct tnbr *t; + + LIST_FOREACH(t, &conf->tnbr_list, entry) { + if (t->addr.s_addr == addr.s_addr) { + yyerror("targeted neighbor %s already configured", + inet_ntoa(addr)); + return (NULL); + } + } + + t = tnbr_new(addr, 1); + + return (t); +} + void clear_config(struct ldpd_conf *xconf) { diff --git a/usr.sbin/ldpd/printconf.c b/usr.sbin/ldpd/printconf.c index 1d8b0714638..cbdddd52544 100644 --- a/usr.sbin/ldpd/printconf.c +++ b/usr.sbin/ldpd/printconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printconf.c,v 1.6 2013/06/03 16:58:14 claudio Exp $ */ +/* $OpenBSD: printconf.c,v 1.7 2013/06/04 02:25:28 claudio Exp $ */ /* * Copyright (c) 2004, 2005, 2008 Esben Norby <norby@openbsd.org> @@ -30,6 +30,7 @@ void print_mainconf(struct ldpd_conf *); void print_iface(struct iface *); +void print_tnbr(struct tnbr *tnbr); void print_mainconf(struct ldpd_conf *conf) @@ -56,6 +57,11 @@ print_mainconf(struct ldpd_conf *conf) else printf("advertisement unsolicited\n"); + if (conf->flags & LDPD_FLAG_TH_ACCEPT) + printf("targeted-hello-accept yes\n"); + else + printf("targeted-hello-accept no\n"); + printf("keepalive %u\n", conf->keepalive); } @@ -63,8 +69,17 @@ void print_iface(struct iface *iface) { printf("\ninterface %s {\n", iface->name); - printf("\tholdtime %d\n", iface->holdtime); - printf("\thello-interval %d\n", iface->hello_interval); + printf("\tlink-hello-holdtime %u\n", iface->hello_holdtime); + printf("\tlink-hello-interval %u\n", iface->hello_interval); + printf("}\n"); +} + +void +print_tnbr(struct tnbr *tnbr) +{ + printf("\ntargeted-neighbor %s {\n", inet_ntoa(tnbr->addr)); + printf("\ttargeted-hello-holdtime %u\n", tnbr->hello_holdtime); + printf("\ttargeted-hello-interval %u\n", tnbr->hello_interval); printf("}\n"); } @@ -72,11 +87,14 @@ void print_config(struct ldpd_conf *conf) { struct iface *iface; + struct tnbr *tnbr; print_mainconf(conf); printf("\n"); - LIST_FOREACH(iface, &conf->iface_list, entry) { + LIST_FOREACH(iface, &conf->iface_list, entry) print_iface(iface); - } + printf("\n"); + LIST_FOREACH(tnbr, &conf->tnbr_list, entry) + print_tnbr(tnbr); } |