summaryrefslogtreecommitdiff
path: root/ldpd/lde_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldpd/lde_lib.c')
-rw-r--r--ldpd/lde_lib.c91
1 files changed, 48 insertions, 43 deletions
diff --git a/ldpd/lde_lib.c b/ldpd/lde_lib.c
index 43e5f92f2f..7a4cb760f1 100644
--- a/ldpd/lde_lib.c
+++ b/ldpd/lde_lib.c
@@ -31,7 +31,7 @@ static int lde_nbr_is_nexthop(struct fec_node *,
static void fec_free(void *);
static struct fec_node *fec_add(struct fec *fec);
static struct fec_nh *fec_nh_add(struct fec_node *, int, union ldpd_addr *,
- uint8_t priority);
+ ifindex_t, uint8_t);
static void fec_nh_del(struct fec_nh *);
RB_GENERATE(fec_tree, fec, entry, fec_compare)
@@ -159,7 +159,7 @@ rt_dump(pid_t pid)
RB_FOREACH(f, fec_tree, &ft) {
fn = (struct fec_node *)f;
if (fn->local_label == NO_LABEL &&
- LIST_EMPTY(&fn->downstream))
+ RB_EMPTY(&fn->downstream))
continue;
rtctl.first = 1;
@@ -179,7 +179,7 @@ rt_dump(pid_t pid)
}
rtctl.local_label = fn->local_label;
- LIST_FOREACH(me, &fn->downstream, entry) {
+ RB_FOREACH(me, lde_map_head, &fn->downstream) {
rtctl.in_use = lde_nbr_is_nexthop(fn, me->nexthop);
rtctl.nexthop = me->nexthop->id;
rtctl.remote_label = me->map.label;
@@ -188,7 +188,7 @@ rt_dump(pid_t pid)
&rtctl, sizeof(rtctl));
rtctl.first = 0;
}
- if (LIST_EMPTY(&fn->downstream)) {
+ if (RB_EMPTY(&fn->downstream)) {
rtctl.in_use = 0;
rtctl.nexthop.s_addr = INADDR_ANY;
rtctl.remote_label = NO_LABEL;
@@ -224,10 +224,10 @@ fec_free(void *arg)
while ((fnh = LIST_FIRST(&fn->nexthops)))
fec_nh_del(fnh);
- if (!LIST_EMPTY(&fn->downstream))
+ if (!RB_EMPTY(&fn->downstream))
log_warnx("%s: fec %s downstream list not empty", __func__,
log_fec(&fn->fec));
- if (!LIST_EMPTY(&fn->upstream))
+ if (!RB_EMPTY(&fn->upstream))
log_warnx("%s: fec %s upstream list not empty", __func__,
log_fec(&fn->fec));
@@ -251,8 +251,8 @@ fec_add(struct fec *fec)
fn->fec = *fec;
fn->local_label = NO_LABEL;
- LIST_INIT(&fn->upstream);
- LIST_INIT(&fn->downstream);
+ RB_INIT(&fn->upstream);
+ RB_INIT(&fn->downstream);
LIST_INIT(&fn->nexthops);
if (fec_insert(&ft, &fn->fec))
@@ -264,13 +264,14 @@ fec_add(struct fec *fec)
struct fec_nh *
fec_nh_find(struct fec_node *fn, int af, union ldpd_addr *nexthop,
- uint8_t priority)
+ ifindex_t ifindex, uint8_t priority)
{
struct fec_nh *fnh;
LIST_FOREACH(fnh, &fn->nexthops, entry)
if (fnh->af == af &&
ldp_addrcmp(af, &fnh->nexthop, nexthop) == 0 &&
+ fnh->ifindex == ifindex &&
fnh->priority == priority)
return (fnh);
@@ -279,7 +280,7 @@ fec_nh_find(struct fec_node *fn, int af, union ldpd_addr *nexthop,
static struct fec_nh *
fec_nh_add(struct fec_node *fn, int af, union ldpd_addr *nexthop,
- uint8_t priority)
+ ifindex_t ifindex, uint8_t priority)
{
struct fec_nh *fnh;
@@ -289,6 +290,7 @@ fec_nh_add(struct fec_node *fn, int af, union ldpd_addr *nexthop,
fnh->af = af;
fnh->nexthop = *nexthop;
+ fnh->ifindex = ifindex;
fnh->remote_label = NO_LABEL;
fnh->priority = priority;
LIST_INSERT_HEAD(&fn->nexthops, fnh, entry);
@@ -303,28 +305,9 @@ fec_nh_del(struct fec_nh *fnh)
free(fnh);
}
-uint32_t
-egress_label(enum fec_type fec_type)
-{
- switch (fec_type) {
- case FEC_TYPE_IPV4:
- if (ldeconf->ipv4.flags & F_LDPD_AF_EXPNULL)
- return (MPLS_LABEL_IPV4NULL);
- break;
- case FEC_TYPE_IPV6:
- if (ldeconf->ipv6.flags & F_LDPD_AF_EXPNULL)
- return (MPLS_LABEL_IPV6NULL);
- break;
- default:
- fatalx("egress_label: unexpected fec type");
- }
-
- return (MPLS_LABEL_IMPLNULL);
-}
-
void
lde_kernel_insert(struct fec *fec, int af, union ldpd_addr *nexthop,
- uint8_t priority, int connected, void *data)
+ ifindex_t ifindex, uint8_t priority, int connected, void *data)
{
struct fec_node *fn;
struct fec_nh *fnh;
@@ -334,7 +317,7 @@ lde_kernel_insert(struct fec *fec, int af, union ldpd_addr *nexthop,
fn = (struct fec_node *)fec_find(&ft, fec);
if (fn == NULL)
fn = fec_add(fec);
- fnh = fec_nh_find(fn, af, nexthop, priority);
+ fnh = fec_nh_find(fn, af, nexthop, ifindex, priority);
if (fnh != NULL) {
lde_send_change_klabel(fn, fnh);
fnh->flags |= F_FEC_NH_NEW;
@@ -345,17 +328,15 @@ lde_kernel_insert(struct fec *fec, int af, union ldpd_addr *nexthop,
fn->data = data;
if (fn->local_label == NO_LABEL) {
- if (connected)
- fn->local_label = egress_label(fn->fec.type);
- else
- fn->local_label = lde_assign_label();
+ fn->local_label = lde_assign_label(&fn->fec, connected);
/* FEC.1: perform lsr label distribution procedure */
- RB_FOREACH(ln, nbr_tree, &lde_nbrs)
- lde_send_labelmapping(ln, fn, 1);
+ if (fn->local_label != NO_LABEL)
+ RB_FOREACH(ln, nbr_tree, &lde_nbrs)
+ lde_send_labelmapping(ln, fn, 1);
}
- fnh = fec_nh_add(fn, af, nexthop, priority);
+ fnh = fec_nh_add(fn, af, nexthop, ifindex, priority);
fnh->flags |= F_FEC_NH_NEW;
lde_send_change_klabel(fn, fnh);
@@ -383,7 +364,7 @@ lde_kernel_insert(struct fec *fec, int af, union ldpd_addr *nexthop,
void
lde_kernel_remove(struct fec *fec, int af, union ldpd_addr *nexthop,
- uint8_t priority)
+ ifindex_t ifindex, uint8_t priority)
{
struct fec_node *fn;
struct fec_nh *fnh;
@@ -392,7 +373,7 @@ lde_kernel_remove(struct fec *fec, int af, union ldpd_addr *nexthop,
if (fn == NULL)
/* route lost */
return;
- fnh = fec_nh_find(fn, af, nexthop, priority);
+ fnh = fec_nh_find(fn, af, nexthop, ifindex, priority);
if (fnh == NULL)
/* route lost */
return;
@@ -428,7 +409,7 @@ lde_kernel_reevaluate(struct fec *fec)
fnh->flags &= ~F_FEC_NH_NEW;
else
lde_kernel_remove(fec, fnh->af, &fnh->nexthop,
- fnh->priority);
+ fnh->ifindex, fnh->priority);
}
}
@@ -444,6 +425,30 @@ lde_check_mapping(struct map *map, struct lde_nbr *ln)
int msgsource = 0;
lde_map2fec(map, ln->id, &fec);
+
+ switch (fec.type) {
+ case FEC_TYPE_IPV4:
+ if (lde_acl_check(ldeconf->ipv4.acl_label_accept_from,
+ AF_INET, (union ldpd_addr *)&ln->id, 32) != FILTER_PERMIT)
+ return;
+ if (lde_acl_check(ldeconf->ipv4.acl_label_accept_for,
+ AF_INET, (union ldpd_addr *)&fec.u.ipv4.prefix,
+ fec.u.ipv4.prefixlen) != FILTER_PERMIT)
+ return;
+ break;
+ case FEC_TYPE_IPV6:
+ if (lde_acl_check(ldeconf->ipv6.acl_label_accept_from,
+ AF_INET, (union ldpd_addr *)&ln->id, 32) != FILTER_PERMIT)
+ return;
+ if (lde_acl_check(ldeconf->ipv6.acl_label_accept_for,
+ AF_INET6, (union ldpd_addr *)&fec.u.ipv6.prefix,
+ fec.u.ipv6.prefixlen) != FILTER_PERMIT)
+ return;
+ break;
+ default:
+ break;
+ }
+
fn = (struct fec_node *)fec_find(&ft, &fec);
if (fn == NULL)
fn = fec_add(&fec);
@@ -772,8 +777,8 @@ lde_gc_timer(struct thread *thread)
fn = (struct fec_node *) fec;
if (!LIST_EMPTY(&fn->nexthops) ||
- !LIST_EMPTY(&fn->downstream) ||
- !LIST_EMPTY(&fn->upstream))
+ !RB_EMPTY(&fn->downstream) ||
+ !RB_EMPTY(&fn->upstream))
continue;
fec_remove(&ft, &fn->fec);