summaryrefslogtreecommitdiffstats
path: root/ldpd
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2017-08-09 20:42:27 +0200
committerDavid Lamparter <equinox@opensourcerouting.org>2017-08-09 20:42:27 +0200
commit4e1fd26a5ef5adb25d53c2acbd9dbe8d18652ef5 (patch)
treec3cffc3302835c7a9ee2ef5388579b5a8d473ee3 /ldpd
parentlib: thoroughly disable tcp-zebra (diff)
parentMerge pull request #911 from opensourcerouting/non-recursive-2 (diff)
downloadfrr-4e1fd26a5ef5adb25d53c2acbd9dbe8d18652ef5.tar.xz
frr-4e1fd26a5ef5adb25d53c2acbd9dbe8d18652ef5.zip
Merge remote-tracking branch 'frr/master' into tcp-zebra
Diffstat (limited to 'ldpd')
-rw-r--r--ldpd/.gitignore2
-rw-r--r--ldpd/Makefile10
-rw-r--r--ldpd/Makefile.am30
-rw-r--r--ldpd/l2vpn.c65
-rw-r--r--ldpd/lde.c61
-rw-r--r--ldpd/lde.h1
-rw-r--r--ldpd/lde_lib.c10
-rw-r--r--ldpd/ldp.h3
-rw-r--r--ldpd/ldp_zebra.c76
-rw-r--r--ldpd/ldpd.c41
-rw-r--r--ldpd/ldpd.h33
-rw-r--r--ldpd/ldpe.c1
-rw-r--r--ldpd/neighbor.c7
-rw-r--r--ldpd/subdir.am55
14 files changed, 286 insertions, 109 deletions
diff --git a/ldpd/.gitignore b/ldpd/.gitignore
index f52b227cb..eee96c636 100644
--- a/ldpd/.gitignore
+++ b/ldpd/.gitignore
@@ -1,4 +1,4 @@
-Makefile
+!Makefile
Makefile.in
*.o
ldpd
diff --git a/ldpd/Makefile b/ldpd/Makefile
new file mode 100644
index 000000000..464e02cf5
--- /dev/null
+++ b/ldpd/Makefile
@@ -0,0 +1,10 @@
+all: ALWAYS
+ @$(MAKE) -s -C .. ldpd/ldpd
+%: ALWAYS
+ @$(MAKE) -s -C .. ldpd/$@
+
+Makefile:
+ #nothing
+ALWAYS:
+.PHONY: ALWAYS makefiles
+.SUFFIXES:
diff --git a/ldpd/Makefile.am b/ldpd/Makefile.am
deleted file mode 100644
index de9b07ed4..000000000
--- a/ldpd/Makefile.am
+++ /dev/null
@@ -1,30 +0,0 @@
-## Process this file with automake to produce Makefile.in.
-
-include ../common.am
-
-AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
-DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
-INSTALL_SDATA=@INSTALL@ -m 600
-
-AM_CFLAGS = $(WERROR)
-
-noinst_LIBRARIES = libldp.a
-sbin_PROGRAMS = ldpd
-
-libldp_a_SOURCES = \
- accept.c address.c adjacency.c control.c hello.c init.c interface.c \
- keepalive.c l2vpn.c labelmapping.c lde.c lde_lib.c ldpd.c \
- ldpe.c log.c logmsg.c neighbor.c notification.c packet.c pfkey.c \
- socket.c util.c ldp_vty_cmds.c ldp_vty_conf.c ldp_vty_exec.c \
- ldp_debug.c ldp_zebra.c
-
-ldp_vty_cmds.o: ldp_vty_cmds_clippy.c
-
-noinst_HEADERS = \
- control.h lde.h ldpd.h ldpe.h ldp.h log.h ldp_debug.h ldp_vty.h
-
-ldpd_SOURCES = ldpd.c
-ldpd_LDADD = libldp.a ../lib/libfrr.la @LIBCAP@
-
-examplesdir = $(exampledir)
-dist_examples_DATA = ldpd.conf.sample
diff --git a/ldpd/l2vpn.c b/ldpd/l2vpn.c
index f15461d3d..9bad503b9 100644
--- a/ldpd/l2vpn.c
+++ b/ldpd/l2vpn.c
@@ -235,6 +235,7 @@ void
l2vpn_pw_init(struct l2vpn_pw *pw)
{
struct fec fec;
+ struct zapi_pw zpw;
l2vpn_pw_reset(pw);
@@ -242,16 +243,23 @@ l2vpn_pw_init(struct l2vpn_pw *pw)
lde_kernel_insert(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0, 0,
0, (void *)pw);
lde_kernel_update(&fec);
+
+ pw2zpw(pw, &zpw);
+ lde_imsg_compose_parent(IMSG_KPW_ADD, 0, &zpw, sizeof(zpw));
}
void
l2vpn_pw_exit(struct l2vpn_pw *pw)
{
struct fec fec;
+ struct zapi_pw zpw;
l2vpn_pw_fec(pw, &fec);
lde_kernel_remove(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0, 0);
lde_kernel_update(&fec);
+
+ pw2zpw(pw, &zpw);
+ lde_imsg_compose_parent(IMSG_KPW_DELETE, 0, &zpw, sizeof(zpw));
}
static void
@@ -269,7 +277,8 @@ l2vpn_pw_reset(struct l2vpn_pw *pw)
{
pw->remote_group = 0;
pw->remote_mtu = 0;
- pw->remote_status = 0;
+ pw->local_status = PW_FORWARDING;
+ pw->remote_status = PW_NOT_FORWARDING;
if (pw->flags & F_PW_CWORD_CONF)
pw->flags |= F_PW_CWORD;
@@ -475,6 +484,56 @@ l2vpn_recv_pw_status_wcard(struct lde_nbr *ln, struct notify_msg *nm)
}
}
+int
+l2vpn_pw_status_update(struct zapi_pw_status *zpw)
+{
+ struct l2vpn *l2vpn;
+ struct l2vpn_pw *pw = NULL;
+ struct lde_nbr *ln;
+ struct fec fec;
+ uint32_t local_status;
+
+ RB_FOREACH(l2vpn, l2vpn_head, &ldeconf->l2vpn_tree) {
+ pw = l2vpn_pw_find(l2vpn, zpw->ifname);
+ if (pw)
+ break;
+ }
+ if (!pw) {
+ log_warnx("%s: pseudowire %s not found", __func__, zpw->ifname);
+ return (1);
+ }
+
+ if (zpw->status == PW_STATUS_UP)
+ local_status = PW_FORWARDING;
+ else
+ local_status = PW_NOT_FORWARDING;
+
+ /* local status didn't change */
+ if (pw->local_status == local_status)
+ return (0);
+ pw->local_status = local_status;
+
+ /* notify remote peer about the status update */
+ ln = lde_nbr_find_by_lsrid(pw->lsr_id);
+ if (ln == NULL)
+ return (0);
+ l2vpn_pw_fec(pw, &fec);
+ if (pw->flags & F_PW_STATUSTLV)
+ l2vpn_send_pw_status(ln, local_status, &fec);
+ else {
+ struct fec_node *fn;
+ fn = (struct fec_node *)fec_find(&ft, &fec);
+ if (fn) {
+ if (pw->local_status == PW_FORWARDING)
+ lde_send_labelmapping(ln, fn, 1);
+ else
+ lde_send_labelwithdraw(ln, fn, NULL, NULL);
+ }
+ }
+
+ return (0);
+}
+
void
l2vpn_pw_ctl(pid_t pid)
{
@@ -491,7 +550,9 @@ l2vpn_pw_ctl(pid_t pid)
sizeof(pwctl.ifname));
pwctl.pwid = pw->pwid;
pwctl.lsr_id = pw->lsr_id;
- pwctl.status = pw->flags & F_PW_STATUS_UP;
+ if (pw->local_status == PW_FORWARDING &&
+ pw->remote_status == PW_FORWARDING)
+ pwctl.status = 1;
lde_imsg_compose_ldpe(IMSG_CTL_SHOW_L2VPN_PW, 0,
pid, &pwctl, sizeof(pwctl));
diff --git a/ldpd/lde.c b/ldpd/lde.c
index 11fcbfa46..4460b424d 100644
--- a/ldpd/lde.c
+++ b/ldpd/lde.c
@@ -165,6 +165,7 @@ lde_init(struct ldpd_init *init)
/* drop privileges */
lde_privs.user = init->user;
lde_privs.group = init->group;
+ zprivs_preinit(&lde_privs);
zprivs_init(&lde_privs);
/* start the LIB garbage collector */
@@ -474,6 +475,15 @@ lde_dispatch_parent(struct thread *thread)
}
}
break;
+ case IMSG_PW_UPDATE:
+ if (imsg.hdr.len != IMSG_HEADER_SIZE +
+ sizeof(struct zapi_pw_status))
+ fatalx("PW_UPDATE imsg with wrong len");
+
+ if (l2vpn_pw_status_update(imsg.data) != 0)
+ log_warnx("%s: error updating PW status",
+ __func__);
+ break;
case IMSG_NETWORK_ADD:
case IMSG_NETWORK_UPDATE:
if (imsg.hdr.len != IMSG_HEADER_SIZE +
@@ -714,8 +724,8 @@ lde_update_label(struct fec_node *fn)
void
lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh)
{
- struct kroute kr;
- struct kpw kpw;
+ struct kroute kr;
+ struct zapi_pw zpw;
struct l2vpn_pw *pw;
switch (fn->fec.type) {
@@ -753,19 +763,10 @@ lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh)
return;
pw = (struct l2vpn_pw *) fn->data;
- pw->flags |= F_PW_STATUS_UP;
-
- memset(&kpw, 0, sizeof(kpw));
- kpw.ifindex = pw->ifindex;
- kpw.pw_type = fn->fec.u.pwid.type;
- kpw.af = pw->af;
- kpw.nexthop = pw->addr;
- kpw.local_label = fn->local_label;
- kpw.remote_label = fnh->remote_label;
- kpw.flags = pw->flags;
-
- lde_imsg_compose_parent(IMSG_KPWLABEL_CHANGE, 0, &kpw,
- sizeof(kpw));
+ pw2zpw(pw, &zpw);
+ zpw.local_label = fn->local_label;
+ zpw.remote_label = fnh->remote_label;
+ lde_imsg_compose_parent(IMSG_KPW_SET, 0, &zpw, sizeof(zpw));
break;
}
}
@@ -774,7 +775,7 @@ void
lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh)
{
struct kroute kr;
- struct kpw kpw;
+ struct zapi_pw zpw;
struct l2vpn_pw *pw;
switch (fn->fec.type) {
@@ -808,21 +809,10 @@ lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh)
break;
case FEC_TYPE_PWID:
pw = (struct l2vpn_pw *) fn->data;
- if (!(pw->flags & F_PW_STATUS_UP))
- return;
- pw->flags &= ~F_PW_STATUS_UP;
-
- memset(&kpw, 0, sizeof(kpw));
- kpw.ifindex = pw->ifindex;
- kpw.pw_type = fn->fec.u.pwid.type;
- kpw.af = pw->af;
- kpw.nexthop = pw->addr;
- kpw.local_label = fn->local_label;
- kpw.remote_label = fnh->remote_label;
- kpw.flags = pw->flags;
-
- lde_imsg_compose_parent(IMSG_KPWLABEL_DELETE, 0, &kpw,
- sizeof(kpw));
+ pw2zpw(pw, &zpw);
+ zpw.local_label = fn->local_label;
+ zpw.remote_label = fnh->remote_label;
+ lde_imsg_compose_parent(IMSG_KPW_UNSET, 0, &zpw, sizeof(zpw));
break;
}
}
@@ -903,8 +893,12 @@ lde_send_labelmapping(struct lde_nbr *ln, struct fec_node *fn, int single)
*/
lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec);
if (lw) {
- if (!fec_find(&ln->sent_map_pending, &fn->fec))
+ if (!fec_find(&ln->sent_map_pending, &fn->fec)) {
+ debug_evt("%s: FEC %s: scheduling to send label "
+ "mapping later (waiting for pending label release)",
+ __func__, log_fec(&fn->fec));
lde_map_pending_add(ln, fn);
+ }
return;
}
@@ -950,8 +944,7 @@ lde_send_labelmapping(struct lde_nbr *ln, struct fec_node *fn, int single)
map.flags |= F_MAP_PW_CWORD;
if (pw->flags & F_PW_STATUSTLV) {
map.flags |= F_MAP_PW_STATUS;
- /* VPLS are always up */
- map.pw_status = PW_FORWARDING;
+ map.pw_status = pw->local_status;
}
break;
}
diff --git a/ldpd/lde.h b/ldpd/lde.h
index 1cce48383..43f1d3648 100644
--- a/ldpd/lde.h
+++ b/ldpd/lde.h
@@ -238,6 +238,7 @@ void l2vpn_send_pw_status_wcard(struct lde_nbr *, uint32_t,
void l2vpn_recv_pw_status(struct lde_nbr *, struct notify_msg *);
void l2vpn_recv_pw_status_wcard(struct lde_nbr *,
struct notify_msg *);
+int l2vpn_pw_status_update(struct zapi_pw_status *);
void l2vpn_pw_ctl(pid_t);
void l2vpn_binding_ctl(pid_t);
diff --git a/ldpd/lde_lib.c b/ldpd/lde_lib.c
index edf686537..c56b7e33d 100644
--- a/ldpd/lde_lib.c
+++ b/ldpd/lde_lib.c
@@ -396,8 +396,7 @@ lde_kernel_update(struct fec *fec)
lde_gc_start_timer();
} else {
fn->local_label = lde_update_label(fn);
- if (fn->local_label != NO_LABEL &&
- RB_EMPTY(lde_map_head, &fn->upstream))
+ if (fn->local_label != NO_LABEL)
/* FEC.1: perform lsr label distribution procedure */
RB_FOREACH(ln, nbr_tree, &lde_nbrs)
lde_send_labelmapping(ln, fn, 1);
@@ -531,6 +530,8 @@ lde_check_mapping(struct map *map, struct lde_nbr *ln)
pw->remote_mtu = map->fec.pwid.ifmtu;
if (map->flags & F_MAP_PW_STATUS)
pw->remote_status = map->pw_status;
+ else
+ pw->remote_status = PW_FORWARDING;
fnh->remote_label = map->label;
if (l2vpn_pw_ok(pw, fnh))
lde_send_change_klabel(fn, fnh);
@@ -774,6 +775,7 @@ lde_check_withdraw(struct map *map, struct lde_nbr *ln)
pw = (struct l2vpn_pw *) fn->data;
if (pw == NULL)
continue;
+ pw->remote_status = PW_NOT_FORWARDING;
break;
default:
break;
@@ -802,6 +804,7 @@ lde_check_withdraw_wcard(struct map *map, struct lde_nbr *ln)
struct fec_node *fn;
struct fec_nh *fnh;
struct lde_map *me;
+ struct l2vpn_pw *pw;
/* LWd.2: send label release */
lde_send_labelrelease(ln, NULL, map, map->label);
@@ -825,6 +828,9 @@ lde_check_withdraw_wcard(struct map *map, struct lde_nbr *ln)
case FEC_TYPE_PWID:
if (f->u.pwid.lsr_id.s_addr != ln->id.s_addr)
continue;
+ pw = (struct l2vpn_pw *) fn->data;
+ if (pw)
+ pw->remote_status = PW_NOT_FORWARDING;
break;
default:
break;
diff --git a/ldpd/ldp.h b/ldpd/ldp.h
index c2b64d20c..cac3da7c5 100644
--- a/ldpd/ldp.h
+++ b/ldpd/ldp.h
@@ -285,9 +285,6 @@ struct address_list_tlv {
#define MAP_TYPE_GENPWID 0x81
#define CONTROL_WORD_FLAG 0x8000
-#define PW_TYPE_ETHERNET_TAGGED 0x0004
-#define PW_TYPE_ETHERNET 0x0005
-#define PW_TYPE_WILDCARD 0x7FFF
#define DEFAULT_PW_TYPE PW_TYPE_ETHERNET
#define PW_TWCARD_RESERVED_BIT 0x8000
diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c
index efc6bd527..ecc7db8f2 100644
--- a/ldpd/ldp_zebra.c
+++ b/ldpd/ldp_zebra.c
@@ -52,6 +52,8 @@ static int ldp_interface_address_delete(int, struct zclient *,
zebra_size_t, vrf_id_t);
static int ldp_zebra_read_route(int, struct zclient *, zebra_size_t,
vrf_id_t);
+static int ldp_zebra_read_pw_status_update(int, struct zclient *,
+ zebra_size_t, vrf_id_t);
static void ldp_zebra_connected(struct zclient *);
static struct zclient *zclient;
@@ -92,6 +94,25 @@ ifc2kaddr(struct interface *ifp, struct connected *ifc, struct kaddr *ka)
}
}
+void
+pw2zpw(struct l2vpn_pw *pw, struct zapi_pw *zpw)
+{
+ memset(zpw, 0, sizeof(*zpw));
+ strlcpy(zpw->ifname, pw->ifname, sizeof(zpw->ifname));
+ zpw->ifindex = pw->ifindex;
+ zpw->type = pw->l2vpn->pw_type;
+ zpw->af = pw->af;
+ zpw->nexthop.ipv6 = pw->addr.v6;
+ zpw->local_label = NO_LABEL;
+ zpw->remote_label = NO_LABEL;
+ if (pw->flags & F_PW_CWORD)
+ zpw->flags = F_PSEUDOWIRE_CWORD;
+ zpw->data.ldp.lsr_id = pw->lsr_id;
+ zpw->data.ldp.pwid = pw->pwid;
+ strlcpy(zpw->data.ldp.vpn_name, pw->l2vpn->name,
+ sizeof(zpw->data.ldp.vpn_name));
+}
+
static int
zebra_send_mpls_labels(int cmd, struct kroute *kr)
{
@@ -152,17 +173,40 @@ kr_delete(struct kroute *kr)
}
int
-kmpw_set(struct kpw *kpw)
+kmpw_add(struct zapi_pw *zpw)
{
- /* TODO */
- return (0);
+ debug_zebra_out("pseudowire %s nexthop %s (add)",
+ zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop));
+
+ return (zebra_send_pw(zclient, ZEBRA_PW_ADD, zpw));
}
int
-kmpw_unset(struct kpw *kpw)
+kmpw_del(struct zapi_pw *zpw)
{
- /* TODO */
- return (0);
+ debug_zebra_out("pseudowire %s nexthop %s (del)",
+ zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop));
+
+ return (zebra_send_pw(zclient, ZEBRA_PW_DELETE, zpw));
+}
+
+int
+kmpw_set(struct zapi_pw *zpw)
+{
+ debug_zebra_out("pseudowire %s nexthop %s labels %u/%u (set)",
+ zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop),
+ zpw->local_label, zpw->remote_label);
+
+ return (zebra_send_pw(zclient, ZEBRA_PW_SET, zpw));
+}
+
+int
+kmpw_unset(struct zapi_pw *zpw)
+{
+ debug_zebra_out("pseudowire %s nexthop %s (unset)",
+ zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop));
+
+ return (zebra_send_pw(zclient, ZEBRA_PW_UNSET, zpw));
}
void
@@ -464,6 +508,25 @@ ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length,
return (0);
}
+/*
+ * Receive PW status update from Zebra and send it to LDE process.
+ */
+static int
+ldp_zebra_read_pw_status_update(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct zapi_pw_status zpw;
+
+ zebra_read_pw_status_update(command, zclient, length, vrf_id, &zpw);
+
+ debug_zebra_in("pseudowire %s status %s", zpw.ifname,
+ (zpw.status == PW_STATUS_UP) ? "up" : "down");
+
+ main_imsg_compose_lde(IMSG_PW_UPDATE, 0, &zpw, sizeof(zpw));
+
+ return (0);
+}
+
static void
ldp_zebra_connected(struct zclient *zclient)
{
@@ -494,6 +557,7 @@ ldp_zebra_init(struct thread_master *master)
zclient->redistribute_route_ipv4_del = ldp_zebra_read_route;
zclient->redistribute_route_ipv6_add = ldp_zebra_read_route;
zclient->redistribute_route_ipv6_del = ldp_zebra_read_route;
+ zclient->pw_status_update = ldp_zebra_read_pw_status_update;
}
void
diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c
index abf584484..80af2b14e 100644
--- a/ldpd/ldpd.c
+++ b/ldpd/ldpd.c
@@ -578,21 +578,36 @@ main_dispatch_lde(struct thread *thread)
if (kr_delete(imsg.data))
log_warnx("%s: error deleting route", __func__);
break;
- case IMSG_KPWLABEL_CHANGE:
+ case IMSG_KPW_ADD:
+ case IMSG_KPW_DELETE:
+ case IMSG_KPW_SET:
+ case IMSG_KPW_UNSET:
if (imsg.hdr.len - IMSG_HEADER_SIZE !=
- sizeof(struct kpw))
+ sizeof(struct zapi_pw))
fatalx("invalid size of IMSG_KPWLABEL_CHANGE");
- if (kmpw_set(imsg.data))
- log_warnx("%s: error changing pseudowire",
- __func__);
- break;
- case IMSG_KPWLABEL_DELETE:
- if (imsg.hdr.len - IMSG_HEADER_SIZE !=
- sizeof(struct kpw))
- fatalx("invalid size of IMSG_KPWLABEL_DELETE");
- if (kmpw_unset(imsg.data))
- log_warnx("%s: error unsetting pseudowire",
- __func__);
+
+ switch (imsg.hdr.type) {
+ case IMSG_KPW_ADD:
+ if (kmpw_add(imsg.data))
+ log_warnx("%s: error adding "
+ "pseudowire", __func__);
+ break;
+ case IMSG_KPW_DELETE:
+ if (kmpw_del(imsg.data))
+ log_warnx("%s: error deleting "
+ "pseudowire", __func__);
+ break;
+ case IMSG_KPW_SET:
+ if (kmpw_set(imsg.data))
+ log_warnx("%s: error setting "
+ "pseudowire", __func__);
+ break;
+ case IMSG_KPW_UNSET:
+ if (kmpw_unset(imsg.data))
+ log_warnx("%s: error unsetting "
+ "pseudowire", __func__);
+ break;
+ }
break;
case IMSG_ACL_CHECK:
if (imsg.hdr.len != IMSG_HEADER_SIZE +
diff --git a/ldpd/ldpd.h b/ldpd/ldpd.h
index 00d2627f1..31d0bc69b 100644
--- a/ldpd/ldpd.h
+++ b/ldpd/ldpd.h
@@ -30,6 +30,8 @@
#include "prefix.h"
#include "filter.h"
#include "vty.h"
+#include "pw.h"
+#include "zclient.h"
#include "ldp.h"
@@ -44,7 +46,6 @@
#define LDPD_OPT_NOACTION 0x00000004
#define TCP_MD5_KEY_LEN 80
-#define L2VPN_NAME_LEN 32
#define RT_BUF_SIZE 16384
#define MAX_RTSOCK_BUF 128 * 1024
@@ -102,8 +103,10 @@ enum imsg_type {
IMSG_CTL_LOG_VERBOSE,
IMSG_KLABEL_CHANGE,
IMSG_KLABEL_DELETE,
- IMSG_KPWLABEL_CHANGE,
- IMSG_KPWLABEL_DELETE,
+ IMSG_KPW_ADD,
+ IMSG_KPW_DELETE,
+ IMSG_KPW_SET,
+ IMSG_KPW_UNSET,
IMSG_IFSTATUS,
IMSG_NEWADDR,
IMSG_DELADDR,
@@ -147,7 +150,8 @@ enum imsg_type {
IMSG_DEBUG_UPDATE,
IMSG_LOG,
IMSG_ACL_CHECK,
- IMSG_INIT
+ IMSG_INIT,
+ IMSG_PW_UPDATE
};
struct ldpd_init {
@@ -407,6 +411,7 @@ struct l2vpn_pw {
unsigned int ifindex;
uint32_t remote_group;
uint16_t remote_mtu;
+ uint32_t local_status;
uint32_t remote_status;
uint8_t flags;
QOBJ_FIELDS
@@ -418,8 +423,7 @@ DECLARE_QOBJ_TYPE(l2vpn_pw)
#define F_PW_STATUSTLV 0x02 /* status tlv negotiated */
#define F_PW_CWORD_CONF 0x04 /* control word configured */
#define F_PW_CWORD 0x08 /* control word negotiated */
-#define F_PW_STATUS_UP 0x10 /* pseudowire is operational */
-#define F_PW_STATIC_NBR_ADDR 0x20 /* static neighbor address configured */
+#define F_PW_STATIC_NBR_ADDR 0x10 /* static neighbor address configured */
struct l2vpn {
RB_ENTRY(l2vpn) entry;
@@ -542,16 +546,6 @@ struct kroute {
uint16_t flags;
};
-struct kpw {
- unsigned short ifindex;
- int pw_type;
- int af;
- union ldpd_addr nexthop;
- uint32_t local_label;
- uint32_t remote_label;
- uint8_t flags;
-};
-
struct kaddr {
char ifname[IF_NAMESIZE];
unsigned short ifindex;
@@ -668,11 +662,14 @@ struct ldpd_conf *parse_config(char *);
int cmdline_symset(char *);
/* kroute.c */
+void pw2zpw(struct l2vpn_pw *, struct zapi_pw *);
void kif_redistribute(const char *);
int kr_change(struct kroute *);
int kr_delete(struct kroute *);
-int kmpw_set(struct kpw *);
-int kmpw_unset(struct kpw *);
+int kmpw_add(struct zapi_pw *);
+int kmpw_del(struct zapi_pw *);
+int kmpw_set(struct zapi_pw *);
+int kmpw_unset(struct zapi_pw *);
/* util.c */
uint8_t mask2prefixlen(in_addr_t);
diff --git a/ldpd/ldpe.c b/ldpd/ldpe.c
index b2f9fdce5..1c0a8bdc8 100644
--- a/ldpd/ldpe.c
+++ b/ldpd/ldpe.c
@@ -142,6 +142,7 @@ ldpe_init(struct ldpd_init *init)
/* drop privileges */
ldpe_privs.user = init->user;
ldpe_privs.group = init->group;
+ zprivs_preinit(&ldpe_privs);
zprivs_init(&ldpe_privs);
/* listen on ldpd control socket */
diff --git a/ldpd/neighbor.c b/ldpd/neighbor.c
index f8d4b5f5f..39860a185 100644
--- a/ldpd/neighbor.c
+++ b/ldpd/neighbor.c
@@ -289,6 +289,8 @@ nbr_new(struct in_addr id, int af, int ds_tlv, union ldpd_addr *addr,
void
nbr_del(struct nbr *nbr)
{
+ struct adj *adj;
+
log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
@@ -314,6 +316,11 @@ nbr_del(struct nbr *nbr)
mapping_list_clr(&nbr->release_list);
mapping_list_clr(&nbr->abortreq_list);
+ while ((adj = RB_ROOT(nbr_adj_head, &nbr->adj_tree)) != NULL) {
+ adj->nbr = NULL;
+ RB_REMOVE(nbr_adj_head, &nbr->adj_tree, adj);
+ }
+
if (nbr->peerid)
RB_REMOVE(nbr_pid_head, &nbrs_by_pid, nbr);
RB_REMOVE(nbr_id_head, &nbrs_by_id, nbr);
diff --git a/ldpd/subdir.am b/ldpd/subdir.am
new file mode 100644
index 000000000..db71cee61
--- /dev/null
+++ b/ldpd/subdir.am
@@ -0,0 +1,55 @@
+#
+# ldpd
+#
+
+if LDPD
+noinst_LIBRARIES += ldpd/libldp.a
+sbin_PROGRAMS += ldpd/ldpd
+dist_examples_DATA += ldpd/ldpd.conf.sample
+endif
+
+ldpd_libldp_a_SOURCES = \
+ ldpd/accept.c \
+ ldpd/address.c \
+ ldpd/adjacency.c \
+ ldpd/control.c \
+ ldpd/hello.c \
+ ldpd/init.c \
+ ldpd/interface.c \
+ ldpd/keepalive.c \
+ ldpd/l2vpn.c \
+ ldpd/labelmapping.c \
+ ldpd/lde.c \
+ ldpd/lde_lib.c \
+ ldpd/ldp_debug.c \
+ ldpd/ldp_vty_cmds.c \
+ ldpd/ldp_vty_conf.c \
+ ldpd/ldp_vty_exec.c \
+ ldpd/ldp_zebra.c \
+ ldpd/ldpd.c \
+ ldpd/ldpe.c \
+ ldpd/log.c \
+ ldpd/logmsg.c \
+ ldpd/neighbor.c \
+ ldpd/notification.c \
+ ldpd/packet.c \
+ ldpd/pfkey.c \
+ ldpd/socket.c \
+ ldpd/util.c \
+ # end
+
+ldpd/ldp_vty_cmds.$(OBJEXT): ldpd/ldp_vty_cmds_clippy.c
+
+noinst_HEADERS += \
+ ldpd/control.h \
+ ldpd/lde.h \
+ ldpd/ldp.h \
+ ldpd/ldp_debug.h \
+ ldpd/ldp_vty.h \
+ ldpd/ldpd.h \
+ ldpd/ldpe.h \
+ ldpd/log.h \
+ # end
+
+ldpd_ldpd_SOURCES = ldpd/ldpd.c
+ldpd_ldpd_LDADD = ldpd/libldp.a lib/libfrr.la @LIBCAP@