-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The eigrpd daemon will support the Enhanced Interior Gateway Routing Protocol. Built using the imsg/three process framework and heavily based on ospfd(8), ospf6d(8) and ldpd(8). The current status of eigrpd(8) is as follows: * Almost full compliance with the specification: DUAL FSM, RTP, CR mode, SIA, etc * Support for both IPv4 and IPv6 * Support for multiple instances (different ASes/AFs) within the same process * Support for rdomains (one process per rdomain) * RIB/FIB synchronization * Basic redistribution support Not implemented features (yet): * Configuration reload support (partially implemented) * Route summarization * Advanced route redistribution/filtering * Carp integration * Authentication (draft is missing information) * Stub (not released by Cisco) Not yet connected to the builds. ok deraadt@ claudio@
- Loading branch information
0 parents
commit a2ef3d6
Showing
29 changed files
with
11,539 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# $OpenBSD$ | ||
|
||
PROG= eigrpd | ||
SRCS= control.c eigrpd.c eigrpe.c hello.c in_cksum.c interface.c \ | ||
kroute.c log.c neighbor.c packet.c parse.y printconf.c query.c \ | ||
rde.c rde_dual.c reply.c rtp.c tlv.c update.c util.c | ||
|
||
MAN= eigrpd.8 eigrpd.conf.5 | ||
|
||
CFLAGS+= -Wall -I${.CURDIR} | ||
CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes | ||
CFLAGS+= -Wmissing-declarations | ||
CFLAGS+= -Wshadow -Wpointer-arith -Wcast-qual | ||
CFLAGS+= -Wsign-compare | ||
YFLAGS= | ||
LDADD+= -levent -lutil | ||
DPADD+= ${LIBEVENT} ${LIBUTIL} | ||
|
||
.include <bsd.prog.mk> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,315 @@ | ||
/* $OpenBSD$ */ | ||
|
||
/* | ||
* Copyright (c) 2003, 2004 Henning Brauer <[email protected]> | ||
* | ||
* Permission to use, copy, modify, and distribute this software for any | ||
* purpose with or without fee is hereby granted, provided that the above | ||
* copyright notice and this permission notice appear in all copies. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
*/ | ||
|
||
#include <sys/types.h> | ||
#include <sys/stat.h> | ||
#include <sys/un.h> | ||
#include <errno.h> | ||
#include <fcntl.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
|
||
#include "eigrpd.h" | ||
#include "eigrp.h" | ||
#include "eigrpe.h" | ||
#include "log.h" | ||
#include "control.h" | ||
|
||
#define CONTROL_BACKLOG 5 | ||
|
||
struct ctl_conn *control_connbyfd(int); | ||
struct ctl_conn *control_connbypid(pid_t); | ||
void control_close(int); | ||
|
||
int | ||
control_init(char *path) | ||
{ | ||
struct sockaddr_un sun; | ||
int fd; | ||
mode_t old_umask; | ||
|
||
if ((fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, | ||
0)) == -1) { | ||
log_warn("%s: socket", __func__); | ||
return (-1); | ||
} | ||
|
||
memset(&sun, 0, sizeof(sun)); | ||
sun.sun_family = AF_UNIX; | ||
strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); | ||
|
||
if (unlink(path) == -1) | ||
if (errno != ENOENT) { | ||
log_warn("%s: unlink %s", __func__, path); | ||
close(fd); | ||
return (-1); | ||
} | ||
|
||
old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH); | ||
if (bind(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) { | ||
log_warn("%s: bind: %s", __func__, path); | ||
close(fd); | ||
umask(old_umask); | ||
return (-1); | ||
} | ||
umask(old_umask); | ||
|
||
if (chmod(path, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) == -1) { | ||
log_warn("%s: chmod", __func__); | ||
close(fd); | ||
(void)unlink(path); | ||
return (-1); | ||
} | ||
|
||
control_state.fd = fd; | ||
|
||
return (0); | ||
} | ||
|
||
int | ||
control_listen(void) | ||
{ | ||
|
||
if (listen(control_state.fd, CONTROL_BACKLOG) == -1) { | ||
log_warn("%s: listen", __func__); | ||
return (-1); | ||
} | ||
|
||
event_set(&control_state.ev, control_state.fd, EV_READ, | ||
control_accept, NULL); | ||
event_add(&control_state.ev, NULL); | ||
evtimer_set(&control_state.evt, control_accept, NULL); | ||
|
||
return (0); | ||
} | ||
|
||
void | ||
control_cleanup(char *path) | ||
{ | ||
if (path == NULL) | ||
return; | ||
event_del(&control_state.ev); | ||
event_del(&control_state.evt); | ||
unlink(path); | ||
} | ||
|
||
/* ARGSUSED */ | ||
void | ||
control_accept(int listenfd, short event, void *bula) | ||
{ | ||
int connfd; | ||
socklen_t len; | ||
struct sockaddr_un sun; | ||
struct ctl_conn *c; | ||
|
||
event_add(&control_state.ev, NULL); | ||
if ((event & EV_TIMEOUT)) | ||
return; | ||
|
||
len = sizeof(sun); | ||
if ((connfd = accept4(listenfd, (struct sockaddr *)&sun, &len, | ||
SOCK_CLOEXEC | SOCK_NONBLOCK)) == -1) { | ||
/* | ||
* Pause accept if we are out of file descriptors, or | ||
* libevent will haunt us here too. | ||
*/ | ||
if (errno == ENFILE || errno == EMFILE) { | ||
struct timeval evtpause = { 1, 0 }; | ||
|
||
event_del(&control_state.ev); | ||
evtimer_add(&control_state.evt, &evtpause); | ||
} else if (errno != EWOULDBLOCK && errno != EINTR && | ||
errno != ECONNABORTED) | ||
log_warn("%s: accept4", __func__); | ||
return; | ||
} | ||
|
||
if ((c = calloc(1, sizeof(struct ctl_conn))) == NULL) { | ||
log_warn("%s: calloc", __func__); | ||
close(connfd); | ||
return; | ||
} | ||
|
||
imsg_init(&c->iev.ibuf, connfd); | ||
c->iev.handler = control_dispatch_imsg; | ||
c->iev.events = EV_READ; | ||
event_set(&c->iev.ev, c->iev.ibuf.fd, c->iev.events, | ||
c->iev.handler, &c->iev); | ||
event_add(&c->iev.ev, NULL); | ||
|
||
TAILQ_INSERT_TAIL(&ctl_conns, c, entry); | ||
} | ||
|
||
struct ctl_conn * | ||
control_connbyfd(int fd) | ||
{ | ||
struct ctl_conn *c; | ||
|
||
for (c = TAILQ_FIRST(&ctl_conns); c != NULL && c->iev.ibuf.fd != fd; | ||
c = TAILQ_NEXT(c, entry)) | ||
; /* nothing */ | ||
|
||
return (c); | ||
} | ||
|
||
struct ctl_conn * | ||
control_connbypid(pid_t pid) | ||
{ | ||
struct ctl_conn *c; | ||
|
||
for (c = TAILQ_FIRST(&ctl_conns); c != NULL && c->iev.ibuf.pid != pid; | ||
c = TAILQ_NEXT(c, entry)) | ||
; /* nothing */ | ||
|
||
return (c); | ||
} | ||
|
||
void | ||
control_close(int fd) | ||
{ | ||
struct ctl_conn *c; | ||
|
||
if ((c = control_connbyfd(fd)) == NULL) { | ||
log_warnx("%s: fd %d: not found", __func__, fd); | ||
return; | ||
} | ||
|
||
msgbuf_clear(&c->iev.ibuf.w); | ||
TAILQ_REMOVE(&ctl_conns, c, entry); | ||
|
||
event_del(&c->iev.ev); | ||
close(c->iev.ibuf.fd); | ||
|
||
/* Some file descriptors are available again. */ | ||
if (evtimer_pending(&control_state.evt, NULL)) { | ||
evtimer_del(&control_state.evt); | ||
event_add(&control_state.ev, NULL); | ||
} | ||
|
||
free(c); | ||
} | ||
|
||
/* ARGSUSED */ | ||
void | ||
control_dispatch_imsg(int fd, short event, void *bula) | ||
{ | ||
struct ctl_conn *c; | ||
struct imsg imsg; | ||
ssize_t n; | ||
unsigned int ifidx; | ||
int verbose; | ||
|
||
if ((c = control_connbyfd(fd)) == NULL) { | ||
log_warnx("%s: fd %d: not found", __func__, fd); | ||
return; | ||
} | ||
|
||
if (event & EV_READ) { | ||
if ((n = imsg_read(&c->iev.ibuf)) == -1 || n == 0) { | ||
control_close(fd); | ||
return; | ||
} | ||
} | ||
if (event & EV_WRITE) { | ||
if (msgbuf_write(&c->iev.ibuf.w) <= 0 && errno != EAGAIN) { | ||
control_close(fd); | ||
return; | ||
} | ||
} | ||
|
||
for (;;) { | ||
if ((n = imsg_get(&c->iev.ibuf, &imsg)) == -1) { | ||
control_close(fd); | ||
return; | ||
} | ||
|
||
if (n == 0) | ||
break; | ||
|
||
switch (imsg.hdr.type) { | ||
case IMSG_CTL_FIB_COUPLE: | ||
case IMSG_CTL_FIB_DECOUPLE: | ||
case IMSG_CTL_RELOAD: | ||
c->iev.ibuf.pid = imsg.hdr.pid; | ||
eigrpe_imsg_compose_parent(imsg.hdr.type, 0, NULL, 0); | ||
break; | ||
case IMSG_CTL_KROUTE: | ||
case IMSG_CTL_IFINFO: | ||
c->iev.ibuf.pid = imsg.hdr.pid; | ||
eigrpe_imsg_compose_parent(imsg.hdr.type, imsg.hdr.pid, | ||
imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE); | ||
break; | ||
case IMSG_CTL_SHOW_INTERFACE: | ||
if (imsg.hdr.len != IMSG_HEADER_SIZE + | ||
sizeof(ifidx)) | ||
break; | ||
|
||
memcpy(&ifidx, imsg.data, sizeof(ifidx)); | ||
eigrpe_iface_ctl(c, ifidx); | ||
imsg_compose_event(&c->iev, IMSG_CTL_END, 0, | ||
0, -1, NULL, 0); | ||
break; | ||
case IMSG_CTL_SHOW_TOPOLOGY: | ||
if (imsg.hdr.len != IMSG_HEADER_SIZE + | ||
sizeof(struct ctl_show_topology_req)) | ||
break; | ||
|
||
c->iev.ibuf.pid = imsg.hdr.pid; | ||
eigrpe_imsg_compose_rde(imsg.hdr.type, 0, imsg.hdr.pid, | ||
imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE); | ||
break; | ||
case IMSG_CTL_SHOW_NBR: | ||
eigrpe_nbr_ctl(c); | ||
break; | ||
case IMSG_CTL_LOG_VERBOSE: | ||
if (imsg.hdr.len != IMSG_HEADER_SIZE + | ||
sizeof(verbose)) | ||
break; | ||
|
||
/* forward to other processes */ | ||
eigrpe_imsg_compose_parent(imsg.hdr.type, imsg.hdr.pid, | ||
imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE); | ||
eigrpe_imsg_compose_rde(imsg.hdr.type, 0, imsg.hdr.pid, | ||
imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE); | ||
|
||
memcpy(&verbose, imsg.data, sizeof(verbose)); | ||
log_verbose(verbose); | ||
break; | ||
default: | ||
log_debug("%s: error handling imsg %d", __func__, | ||
imsg.hdr.type); | ||
break; | ||
} | ||
imsg_free(&imsg); | ||
} | ||
|
||
imsg_event_add(&c->iev); | ||
} | ||
|
||
int | ||
control_imsg_relay(struct imsg *imsg) | ||
{ | ||
struct ctl_conn *c; | ||
|
||
if ((c = control_connbypid(imsg->hdr.pid)) == NULL) | ||
return (0); | ||
|
||
return (imsg_compose_event(&c->iev, imsg->hdr.type, 0, imsg->hdr.pid, | ||
-1, imsg->data, imsg->hdr.len - IMSG_HEADER_SIZE)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* $OpenBSD$ */ | ||
|
||
/* | ||
* Copyright (c) 2003, 2004 Henning Brauer <[email protected]> | ||
* | ||
* Permission to use, copy, modify, and distribute this software for any | ||
* purpose with or without fee is hereby granted, provided that the above | ||
* copyright notice and this permission notice appear in all copies. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
*/ | ||
|
||
#ifndef _CONTROL_H_ | ||
#define _CONTROL_H_ | ||
|
||
#include <sys/queue.h> | ||
#include <sys/time.h> | ||
#include <event.h> | ||
|
||
struct { | ||
struct event ev; | ||
struct event evt; | ||
int fd; | ||
} control_state; | ||
|
||
struct ctl_conn { | ||
TAILQ_ENTRY(ctl_conn) entry; | ||
struct imsgev iev; | ||
}; | ||
|
||
int control_init(char *); | ||
int control_listen(void); | ||
void control_accept(int, short, void *); | ||
void control_dispatch_imsg(int, short, void *); | ||
int control_imsg_relay(struct imsg *); | ||
void control_cleanup(char *); | ||
|
||
#endif /* _CONTROL_H_ */ |
Oops, something went wrong.