diff options
author | Renato Westphal <renato@cvs.openbsd.org> | 2016-06-18 01:25:54 +0000 |
---|---|---|
committer | Renato Westphal <renato@cvs.openbsd.org> | 2016-06-18 01:25:54 +0000 |
commit | e9b20c9afa8bba88e98619240292213e870b55b2 (patch) | |
tree | c28d44bd41c5be9877cf5a6673901818ccc50818 | |
parent | dec78b720b31d789236356d18e5ee4e38aaf8609 (diff) |
Fix small LIB<->LFIB synchronization issue.
ldpd operates only with the best routes of each IP prefix. In other words,
the routes with the lowest priorities.
When a route with a better priority is detected (possibly with a different
nexthop), we should uninstall the labels from the "old" routes and try
to install a new label for the new route (if there's one available in
the LIB).
In this specific case, ldpd was failing to uninstall the labels from the
old routes because it wasn't keeping track of each route's priority in
lde. With this missing bit of information, the parent process had no way
to get the correct label to uninstall when processing a IMSG_KLABEL_DELETE
message.
-rw-r--r-- | usr.sbin/ldpd/kroute.c | 6 | ||||
-rw-r--r-- | usr.sbin/ldpd/l2vpn.c | 10 | ||||
-rw-r--r-- | usr.sbin/ldpd/lde.c | 11 | ||||
-rw-r--r-- | usr.sbin/ldpd/lde.h | 12 | ||||
-rw-r--r-- | usr.sbin/ldpd/lde_lib.c | 26 |
5 files changed, 40 insertions, 25 deletions
diff --git a/usr.sbin/ldpd/kroute.c b/usr.sbin/ldpd/kroute.c index 335590356dd..260eddc651b 100644 --- a/usr.sbin/ldpd/kroute.c +++ b/usr.sbin/ldpd/kroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kroute.c,v 1.60 2016/05/23 19:14:03 renato Exp $ */ +/* $OpenBSD: kroute.c,v 1.61 2016/06/18 01:25:53 renato Exp $ */ /* * Copyright (c) 2015, 2016 Renato Westphal <renato@openbsd.org> @@ -232,7 +232,7 @@ kr_change(struct kroute *kr) if (kp == NULL) goto miss; - kprio = kroute_find_prio(kp, RTP_ANY); + kprio = kroute_find_prio(kp, kr->priority); if (kprio == NULL) goto miss; @@ -277,7 +277,7 @@ kr_delete(struct kroute *kr) kp = kroute_find_prefix(kr->af, &kr->prefix, kr->prefixlen); if (kp == NULL) return (0); - kprio = kroute_find_prio(kp, RTP_ANY); + kprio = kroute_find_prio(kp, kr->priority); if (kprio == NULL) return (0); kn = kroute_find_gw(kprio, &kr->nexthop); diff --git a/usr.sbin/ldpd/l2vpn.c b/usr.sbin/ldpd/l2vpn.c index 75ef27cb0f3..2384e49f36b 100644 --- a/usr.sbin/ldpd/l2vpn.c +++ b/usr.sbin/ldpd/l2vpn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: l2vpn.c,v 1.16 2016/05/23 19:11:42 renato Exp $ */ +/* $OpenBSD: l2vpn.c,v 1.17 2016/06/18 01:25:53 renato Exp $ */ /* * Copyright (c) 2015 Renato Westphal <renato@openbsd.org> @@ -155,7 +155,7 @@ l2vpn_pw_init(struct l2vpn_pw *pw) l2vpn_pw_reset(pw); l2vpn_pw_fec(pw, &fec); - lde_kernel_insert(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, + lde_kernel_insert(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0, 0, (void *)pw); } @@ -165,7 +165,7 @@ l2vpn_pw_exit(struct l2vpn_pw *pw) struct fec fec; l2vpn_pw_fec(pw, &fec); - lde_kernel_remove(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id); + lde_kernel_remove(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0); } static void @@ -332,7 +332,7 @@ l2vpn_recv_pw_status(struct lde_nbr *ln, struct notify_msg *nm) if (pw == NULL) return; - fnh = fec_nh_find(fn, AF_INET, (union ldpd_addr *)&ln->id); + fnh = fec_nh_find(fn, AF_INET, (union ldpd_addr *)&ln->id, 0); if (fnh == NULL) return; @@ -367,7 +367,7 @@ l2vpn_sync_pws(int af, union ldpd_addr *addr) if (fn == NULL) continue; fnh = fec_nh_find(fn, AF_INET, (union ldpd_addr *) - &pw->lsr_id); + &pw->lsr_id, 0); if (fnh == NULL) continue; diff --git a/usr.sbin/ldpd/lde.c b/usr.sbin/ldpd/lde.c index 5431bc5d04f..cb0553d1eed 100644 --- a/usr.sbin/ldpd/lde.c +++ b/usr.sbin/ldpd/lde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lde.c,v 1.58 2016/05/23 19:16:00 renato Exp $ */ +/* $OpenBSD: lde.c,v 1.59 2016/06/18 01:25:53 renato Exp $ */ /* * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org> @@ -436,10 +436,11 @@ lde_dispatch_parent(int fd, short event, void *bula) switch (imsg.hdr.type) { case IMSG_NETWORK_ADD: lde_kernel_insert(&fec, kr.af, &kr.nexthop, - kr.flags & F_CONNECTED, NULL); + kr.priority, kr.flags & F_CONNECTED, NULL); break; case IMSG_NETWORK_DEL: - lde_kernel_remove(&fec, kr.af, &kr.nexthop); + lde_kernel_remove(&fec, kr.af, &kr.nexthop, + kr.priority); break; } break; @@ -574,6 +575,7 @@ lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh) kr.nexthop.v4 = fnh->nexthop.v4; kr.local_label = fn->local_label; kr.remote_label = fnh->remote_label; + kr.priority = fnh->priority; lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr, sizeof(kr)); @@ -590,6 +592,7 @@ lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh) kr.nexthop.v6 = fnh->nexthop.v6; kr.local_label = fn->local_label; kr.remote_label = fnh->remote_label; + kr.priority = fnh->priority; lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr, sizeof(kr)); @@ -637,6 +640,7 @@ lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh) kr.nexthop.v4 = fnh->nexthop.v4; kr.local_label = fn->local_label; kr.remote_label = fnh->remote_label; + kr.priority = fnh->priority; lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr, sizeof(kr)); @@ -653,6 +657,7 @@ lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh) kr.nexthop.v6 = fnh->nexthop.v6; kr.local_label = fn->local_label; kr.remote_label = fnh->remote_label; + kr.priority = fnh->priority; lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr, sizeof(kr)); diff --git a/usr.sbin/ldpd/lde.h b/usr.sbin/ldpd/lde.h index 5decb0f8459..b30c28965e1 100644 --- a/usr.sbin/ldpd/lde.h +++ b/usr.sbin/ldpd/lde.h @@ -1,4 +1,4 @@ -/* $OpenBSD: lde.h,v 1.39 2016/05/23 19:16:00 renato Exp $ */ +/* $OpenBSD: lde.h,v 1.40 2016/06/18 01:25:53 renato Exp $ */ /* * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org> @@ -102,6 +102,7 @@ struct fec_nh { int af; union ldpd_addr nexthop; uint32_t remote_label; + uint8_t priority; }; struct fec_node { @@ -159,10 +160,13 @@ void fec_clear(struct fec_tree *, void (*)(void *)); void rt_dump(pid_t); void fec_snap(struct lde_nbr *); void fec_tree_clear(void); -struct fec_nh *fec_nh_find(struct fec_node *, int, union ldpd_addr *); +struct fec_nh *fec_nh_find(struct fec_node *, int, union ldpd_addr *, + uint8_t); uint32_t egress_label(enum fec_type); -void lde_kernel_insert(struct fec *, int, union ldpd_addr *, int, void *); -void lde_kernel_remove(struct fec *, int, union ldpd_addr *); +void lde_kernel_insert(struct fec *, int, union ldpd_addr *, + uint8_t, int, void *); +void lde_kernel_remove(struct fec *, int, union ldpd_addr *, + uint8_t); void lde_check_mapping(struct map *, struct lde_nbr *); void lde_check_request(struct map *, struct lde_nbr *); void lde_check_release(struct map *, struct lde_nbr *); diff --git a/usr.sbin/ldpd/lde_lib.c b/usr.sbin/ldpd/lde_lib.c index 6024709a770..50ff9cd839f 100644 --- a/usr.sbin/ldpd/lde_lib.c +++ b/usr.sbin/ldpd/lde_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lde_lib.c,v 1.59 2016/06/11 02:03:36 renato Exp $ */ +/* $OpenBSD: lde_lib.c,v 1.60 2016/06/18 01:25:53 renato Exp $ */ /* * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org> @@ -33,7 +33,8 @@ static int lde_nbr_is_nexthop(struct fec_node *, struct lde_nbr *); 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 *); +static struct fec_nh *fec_nh_add(struct fec_node *, int, union ldpd_addr *, + uint8_t priority); static void fec_nh_del(struct fec_nh *); RB_GENERATE(fec_tree, fec, entry, fec_compare) @@ -263,20 +264,23 @@ fec_add(struct fec *fec) } struct fec_nh * -fec_nh_find(struct fec_node *fn, int af, union ldpd_addr *nexthop) +fec_nh_find(struct fec_node *fn, int af, union ldpd_addr *nexthop, + uint8_t priority) { struct fec_nh *fnh; LIST_FOREACH(fnh, &fn->nexthops, entry) if (fnh->af == af && - ldp_addrcmp(af, &fnh->nexthop, nexthop) == 0) + ldp_addrcmp(af, &fnh->nexthop, nexthop) == 0 && + fnh->priority == priority) return (fnh); return (NULL); } static struct fec_nh * -fec_nh_add(struct fec_node *fn, int af, union ldpd_addr *nexthop) +fec_nh_add(struct fec_node *fn, int af, union ldpd_addr *nexthop, + uint8_t priority) { struct fec_nh *fnh; @@ -287,6 +291,7 @@ fec_nh_add(struct fec_node *fn, int af, union ldpd_addr *nexthop) fnh->af = af; fnh->nexthop = *nexthop; fnh->remote_label = NO_LABEL; + fnh->priority = priority; LIST_INSERT_HEAD(&fn->nexthops, fnh, entry); return (fnh); @@ -320,7 +325,7 @@ egress_label(enum fec_type fec_type) void lde_kernel_insert(struct fec *fec, int af, union ldpd_addr *nexthop, - int connected, void *data) + uint8_t priority, int connected, void *data) { struct fec_node *fn; struct fec_nh *fnh; @@ -330,7 +335,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); - if (fec_nh_find(fn, af, nexthop) != NULL) + if (fec_nh_find(fn, af, nexthop, priority) != NULL) return; log_debug("lde add fec %s nexthop %s", @@ -350,7 +355,7 @@ lde_kernel_insert(struct fec *fec, int af, union ldpd_addr *nexthop, lde_send_labelmapping(ln, fn, 1); } - fnh = fec_nh_add(fn, af, nexthop); + fnh = fec_nh_add(fn, af, nexthop, priority); lde_send_change_klabel(fn, fnh); switch (fn->fec.type) { @@ -376,7 +381,8 @@ 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) +lde_kernel_remove(struct fec *fec, int af, union ldpd_addr *nexthop, + uint8_t priority) { struct fec_node *fn; struct fec_nh *fnh; @@ -385,7 +391,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); + fnh = fec_nh_find(fn, af, nexthop, priority); if (fnh == NULL) /* route lost */ return; |