forked from Mirror/frr
Merge pull request #6241 from volta-networks/fix_ldp_acl
ldpd: fix ACL rule modification
This commit is contained in:
commit
31b5355d6f
331
ldpd/lde.c
331
ldpd/lde.c
|
@ -63,6 +63,8 @@ static void on_get_label_chunk_response(uint32_t start, uint32_t end);
|
|||
static uint32_t lde_get_next_label(void);
|
||||
static bool lde_fec_connected(const struct fec_node *);
|
||||
static bool lde_fec_outside_mpls_network(const struct fec_node *);
|
||||
static void lde_check_filter_af(int, struct ldpd_af_conf *,
|
||||
const char *);
|
||||
|
||||
RB_GENERATE(nbr_tree, lde_nbr, entry, lde_nbr_compare)
|
||||
RB_GENERATE(lde_map_head, lde_map, entry, lde_map_compare)
|
||||
|
@ -442,6 +444,7 @@ lde_dispatch_parent(struct thread *thread)
|
|||
ssize_t n;
|
||||
int shut = 0;
|
||||
struct fec fec;
|
||||
struct ldp_access *laccess;
|
||||
|
||||
iev->ev_read = NULL;
|
||||
|
||||
|
@ -634,6 +637,18 @@ lde_dispatch_parent(struct thread *thread)
|
|||
}
|
||||
memcpy(&ldp_debug, imsg.data, sizeof(ldp_debug));
|
||||
break;
|
||||
case IMSG_FILTER_UPDATE:
|
||||
if (imsg.hdr.len != IMSG_HEADER_SIZE +
|
||||
sizeof(struct ldp_access)) {
|
||||
log_warnx("%s: wrong imsg len", __func__);
|
||||
break;
|
||||
}
|
||||
laccess = imsg.data;
|
||||
lde_check_filter_af(AF_INET, &ldeconf->ipv4,
|
||||
laccess->name);
|
||||
lde_check_filter_af(AF_INET6, &ldeconf->ipv6,
|
||||
laccess->name);
|
||||
break;
|
||||
default:
|
||||
log_debug("%s: unexpected imsg %d", __func__,
|
||||
imsg.hdr.type);
|
||||
|
@ -1201,6 +1216,82 @@ lde_send_labelrelease(struct lde_nbr *ln, struct fec_node *fn,
|
|||
lde_imsg_compose_ldpe(IMSG_RELEASE_ADD_END, ln->peerid, 0, NULL, 0);
|
||||
}
|
||||
|
||||
void
|
||||
lde_send_labelrequest(struct lde_nbr *ln, struct fec_node *fn,
|
||||
struct map *wcard, int single)
|
||||
{
|
||||
struct map map;
|
||||
struct fec *f;
|
||||
struct lde_req *lre;
|
||||
|
||||
if (fn) {
|
||||
lde_fec2map(&fn->fec, &map);
|
||||
switch (fn->fec.type) {
|
||||
case FEC_TYPE_IPV4:
|
||||
if (!ln->v4_enabled)
|
||||
return;
|
||||
break;
|
||||
case FEC_TYPE_IPV6:
|
||||
if (!ln->v6_enabled)
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
fatalx("lde_send_labelrequest: unknown af");
|
||||
}
|
||||
} else
|
||||
memcpy(&map, wcard, sizeof(map));
|
||||
|
||||
map.label = NO_LABEL;
|
||||
|
||||
if (fn) {
|
||||
/* SLR1.1: has label request for FEC been previously sent
|
||||
* and still outstanding just return,
|
||||
*/
|
||||
lre = (struct lde_req *)fec_find(&ln->sent_req, &fn->fec);
|
||||
if (lre == NULL) {
|
||||
/* SLRq.3: send label request */
|
||||
lde_imsg_compose_ldpe(IMSG_REQUEST_ADD, ln->peerid, 0,
|
||||
&map, sizeof(map));
|
||||
if (single)
|
||||
lde_imsg_compose_ldpe(IMSG_REQUEST_ADD_END,
|
||||
ln->peerid, 0, NULL, 0);
|
||||
|
||||
/* SLRq.4: record sent request */
|
||||
lde_req_add(ln, &fn->fec, 1);
|
||||
}
|
||||
} else {
|
||||
/* if Wilcard just send label request */
|
||||
/* SLRq.3: send label request */
|
||||
lde_imsg_compose_ldpe(IMSG_REQUEST_ADD,
|
||||
ln->peerid, 0, &map, sizeof(map));
|
||||
if (single)
|
||||
lde_imsg_compose_ldpe(IMSG_REQUEST_ADD_END,
|
||||
ln->peerid, 0, NULL, 0);
|
||||
|
||||
/* SLRq.4: record sent request */
|
||||
RB_FOREACH(f, fec_tree, &ft) {
|
||||
fn = (struct fec_node *)f;
|
||||
lre = (struct lde_req *)fec_find(&ln->sent_req, &fn->fec);
|
||||
if (lde_wildcard_apply(wcard, &fn->fec, NULL) == 0)
|
||||
continue;
|
||||
if (lre == NULL)
|
||||
lde_req_add(ln, f, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lde_send_labelrequest_wcard(struct lde_nbr *ln, uint16_t af)
|
||||
{
|
||||
struct map wcard;
|
||||
|
||||
memset(&wcard, 0, sizeof(wcard));
|
||||
wcard.type = MAP_TYPE_TYPED_WCARD;
|
||||
wcard.fec.twcard.type = MAP_TYPE_PREFIX;
|
||||
wcard.fec.twcard.u.prefix_af = af;
|
||||
lde_send_labelrequest(ln, NULL, &wcard, 1);
|
||||
}
|
||||
|
||||
void
|
||||
lde_send_notification(struct lde_nbr *ln, uint32_t status_code, uint32_t msg_id,
|
||||
uint16_t msg_type)
|
||||
|
@ -1637,13 +1728,14 @@ lde_change_egress_label(int af)
|
|||
}
|
||||
|
||||
void
|
||||
lde_change_host_label(int af)
|
||||
lde_change_allocate_filter(int af)
|
||||
{
|
||||
struct lde_nbr *ln;
|
||||
struct fec *f;
|
||||
struct fec_node *fn;
|
||||
uint32_t new_label;
|
||||
|
||||
/* reallocate labels for fecs that match this filter */
|
||||
RB_FOREACH(f, fec_tree, &ft) {
|
||||
fn = (struct fec_node *)f;
|
||||
|
||||
|
@ -1657,7 +1749,7 @@ lde_change_host_label(int af)
|
|||
continue;
|
||||
break;
|
||||
default:
|
||||
fatalx("lde_change_host_label: unknown af");
|
||||
fatalx("lde_change_allocate_filter: unknown af");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1686,6 +1778,225 @@ lde_change_host_label(int af)
|
|||
NULL, 0);
|
||||
}
|
||||
|
||||
void
|
||||
lde_change_advertise_filter(int af)
|
||||
{
|
||||
struct lde_nbr *ln;
|
||||
struct fec *f;
|
||||
struct fec_node *fn;
|
||||
char *acl_to_filter;
|
||||
char *acl_for_filter;
|
||||
union ldpd_addr *prefix;
|
||||
uint8_t plen;
|
||||
struct lde_map *me;
|
||||
|
||||
/* advertise label for fecs to neighbors if matches advertise filters */
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
acl_to_filter = ldeconf->ipv4.acl_label_advertise_to;
|
||||
acl_for_filter = ldeconf->ipv4.acl_label_advertise_for;
|
||||
break;
|
||||
case AF_INET6:
|
||||
acl_to_filter = ldeconf->ipv6.acl_label_advertise_to;
|
||||
acl_for_filter = ldeconf->ipv6.acl_label_advertise_for;
|
||||
break;
|
||||
default:
|
||||
fatalx("lde_change_advertise_filter: unknown af");
|
||||
}
|
||||
|
||||
RB_FOREACH(ln, nbr_tree, &lde_nbrs) {
|
||||
if (lde_acl_check(acl_to_filter, af, (union ldpd_addr *)&ln->id,
|
||||
IPV4_MAX_BITLEN) != FILTER_PERMIT)
|
||||
lde_send_labelwithdraw_wcard(ln, NO_LABEL);
|
||||
else {
|
||||
/* This neighbor is allowed in to_filter, so
|
||||
* send labels if fec also matches for_filter
|
||||
*/
|
||||
RB_FOREACH(f, fec_tree, &ft) {
|
||||
fn = (struct fec_node *)f;
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
if (fn->fec.type != FEC_TYPE_IPV4)
|
||||
continue;
|
||||
prefix = (union ldpd_addr *)
|
||||
&fn->fec.u.ipv4.prefix;
|
||||
plen = fn->fec.u.ipv4.prefixlen;
|
||||
break;
|
||||
case FEC_TYPE_IPV6:
|
||||
if (fn->fec.type != FEC_TYPE_IPV6)
|
||||
continue;
|
||||
prefix = (union ldpd_addr *)
|
||||
&fn->fec.u.ipv6.prefix;
|
||||
plen = fn->fec.u.ipv6.prefixlen;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
if (lde_acl_check(acl_for_filter, af,
|
||||
prefix, plen) != FILTER_PERMIT) {
|
||||
me = (struct lde_map *)fec_find(
|
||||
&ln->sent_map, &fn->fec);
|
||||
if (me)
|
||||
/* fec filtered withdraw */
|
||||
lde_send_labelwithdraw(ln, fn,
|
||||
NULL, NULL);
|
||||
} else
|
||||
/* fec allowed send map */
|
||||
lde_send_labelmapping(ln, fn, 0);
|
||||
}
|
||||
lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END,
|
||||
ln->peerid, 0, NULL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lde_change_accept_filter(int af)
|
||||
{
|
||||
struct lde_nbr *ln;
|
||||
struct fec *f;
|
||||
struct fec_node *fn;
|
||||
char *acl_for_filter;
|
||||
char *acl_from_filter;
|
||||
union ldpd_addr *prefix;
|
||||
uint8_t plen;
|
||||
struct lde_map *me;
|
||||
enum fec_type type;
|
||||
|
||||
/* accept labels from neighbors specified in the from_filter and for
|
||||
* fecs defined in the for_filter
|
||||
*/
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
acl_for_filter = ldeconf->ipv4.acl_label_accept_for;
|
||||
acl_from_filter = ldeconf->ipv4.acl_label_accept_from;
|
||||
type = FEC_TYPE_IPV4;
|
||||
break;
|
||||
case AF_INET6:
|
||||
acl_for_filter = ldeconf->ipv6.acl_label_accept_for;
|
||||
acl_from_filter = ldeconf->ipv6.acl_label_accept_from;
|
||||
type = FEC_TYPE_IPV6;
|
||||
break;
|
||||
default:
|
||||
fatalx("lde_change_accept_filter: unknown af");
|
||||
}
|
||||
|
||||
RB_FOREACH(ln, nbr_tree, &lde_nbrs) {
|
||||
if (lde_acl_check(acl_from_filter, AF_INET, (union ldpd_addr *)
|
||||
&ln->id, IPV4_MAX_BITLEN) != FILTER_PERMIT) {
|
||||
/* This neighbor is now filtered so remove fecs from
|
||||
* recv list
|
||||
*/
|
||||
RB_FOREACH(f, fec_tree, &ft) {
|
||||
fn = (struct fec_node *)f;
|
||||
if (fn->fec.type == type) {
|
||||
me = (struct lde_map *)fec_find(
|
||||
&ln->recv_map, &fn->fec);
|
||||
if (me)
|
||||
lde_map_del(ln, me, 0);
|
||||
}
|
||||
}
|
||||
} else if (ln->flags & F_NBR_CAP_TWCARD) {
|
||||
/* This neighbor is allowed and supports type
|
||||
* wildcard so send a labelrequest
|
||||
* to get any new labels from neighbor
|
||||
* and make sure any fecs we currently have
|
||||
* match for_filter.
|
||||
*/
|
||||
RB_FOREACH(f, fec_tree, &ft) {
|
||||
fn = (struct fec_node *)f;
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
if (fn->fec.type != FEC_TYPE_IPV4)
|
||||
continue;
|
||||
prefix = (union ldpd_addr *)
|
||||
&fn->fec.u.ipv4.prefix;
|
||||
plen = fn->fec.u.ipv4.prefixlen;
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (fn->fec.type != FEC_TYPE_IPV6)
|
||||
continue;
|
||||
prefix = (union ldpd_addr *)
|
||||
&fn->fec.u.ipv6.prefix;
|
||||
plen = fn->fec.u.ipv6.prefixlen;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
if (lde_acl_check(acl_for_filter, af,
|
||||
prefix, plen) != FILTER_PERMIT) {
|
||||
me = (struct lde_map *)fec_find(
|
||||
&ln->recv_map, &fn->fec);
|
||||
if (me)
|
||||
lde_map_del(ln, me, 0);
|
||||
}
|
||||
}
|
||||
lde_send_labelrequest_wcard(ln, af);
|
||||
} else
|
||||
/* Type Wildcard is not supported so restart session */
|
||||
lde_imsg_compose_ldpe(IMSG_NBR_SHUTDOWN, ln->peerid, 0,
|
||||
NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lde_change_expnull_for_filter(int af)
|
||||
{
|
||||
struct lde_nbr *ln;
|
||||
struct fec *f;
|
||||
struct fec_node *fn;
|
||||
char *acl_name;
|
||||
uint32_t exp_label;
|
||||
union ldpd_addr *prefix;
|
||||
uint8_t plen;
|
||||
|
||||
/* Configure explicit-null advertisement for all fecs in this filter */
|
||||
RB_FOREACH(f, fec_tree, &ft) {
|
||||
fn = (struct fec_node *)f;
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
if (fn->fec.type != FEC_TYPE_IPV4)
|
||||
continue;
|
||||
acl_name = ldeconf->ipv4.acl_label_expnull_for;
|
||||
prefix = (union ldpd_addr *)&fn->fec.u.ipv4.prefix;
|
||||
plen = fn->fec.u.ipv4.prefixlen;
|
||||
exp_label = MPLS_LABEL_IPV4_EXPLICIT_NULL;
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (fn->fec.type != FEC_TYPE_IPV6)
|
||||
continue;
|
||||
acl_name = ldeconf->ipv6.acl_label_expnull_for;
|
||||
prefix = (union ldpd_addr *)&fn->fec.u.ipv6.prefix;
|
||||
plen = fn->fec.u.ipv6.prefixlen;
|
||||
exp_label = MPLS_LABEL_IPV6_EXPLICIT_NULL;
|
||||
break;
|
||||
default:
|
||||
fatalx("lde_change_expnull_for_filter: unknown af");
|
||||
}
|
||||
|
||||
if (lde_acl_check(acl_name, af, prefix, plen) == FILTER_PERMIT) {
|
||||
/* for this fec change any imp-null to exp-null */
|
||||
if (fn->local_label == MPLS_LABEL_IMPLICIT_NULL) {
|
||||
fn->local_label= lde_update_label(fn);
|
||||
RB_FOREACH(ln, nbr_tree, &lde_nbrs)
|
||||
lde_send_labelmapping(ln, fn, 0);
|
||||
}
|
||||
} else {
|
||||
/* for this fec change any exp-null back to imp-null */
|
||||
if (fn->local_label == exp_label) {
|
||||
fn->local_label = lde_update_label(fn);
|
||||
RB_FOREACH(ln, nbr_tree, &lde_nbrs)
|
||||
lde_send_labelmapping(ln, fn, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
RB_FOREACH(ln, nbr_tree, &lde_nbrs)
|
||||
lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, ln->peerid, 0,
|
||||
NULL, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
lde_address_add(struct lde_nbr *ln, struct lde_addr *lde_addr)
|
||||
{
|
||||
|
@ -1947,3 +2258,19 @@ end:
|
|||
|
||||
return (label);
|
||||
}
|
||||
|
||||
static void
|
||||
lde_check_filter_af(int af, struct ldpd_af_conf *af_conf,
|
||||
const char *filter_name)
|
||||
{
|
||||
if (strcmp(af_conf->acl_label_allocate_for, filter_name) == 0)
|
||||
lde_change_allocate_filter(af);
|
||||
if ((strcmp(af_conf->acl_label_advertise_to, filter_name) == 0)
|
||||
|| (strcmp(af_conf->acl_label_advertise_for, filter_name) == 0))
|
||||
lde_change_advertise_filter(af);
|
||||
if ((strcmp(af_conf->acl_label_accept_for, filter_name) == 0)
|
||||
|| (strcmp(af_conf->acl_label_accept_from, filter_name) == 0))
|
||||
lde_change_accept_filter(af);
|
||||
if (strcmp(af_conf->acl_label_expnull_for, filter_name) == 0)
|
||||
lde_change_expnull_for_filter(af);
|
||||
}
|
||||
|
|
|
@ -168,6 +168,9 @@ void lde_send_labelwithdraw_pwid_wcard(struct lde_nbr *, uint16_t,
|
|||
uint32_t);
|
||||
void lde_send_labelrelease(struct lde_nbr *, struct fec_node *,
|
||||
struct map *, uint32_t);
|
||||
void lde_send_labelrequest(struct lde_nbr *, struct fec_node *,
|
||||
struct map *, int);
|
||||
void lde_send_labelrequest_wcard(struct lde_nbr *, uint16_t af);
|
||||
void lde_send_notification(struct lde_nbr *, uint32_t, uint32_t,
|
||||
uint16_t);
|
||||
void lde_send_notification_eol_prefix(struct lde_nbr *, int);
|
||||
|
@ -183,7 +186,10 @@ void lde_req_del(struct lde_nbr *, struct lde_req *, int);
|
|||
struct lde_wdraw *lde_wdraw_add(struct lde_nbr *, struct fec_node *);
|
||||
void lde_wdraw_del(struct lde_nbr *, struct lde_wdraw *);
|
||||
void lde_change_egress_label(int);
|
||||
void lde_change_host_label(int);
|
||||
void lde_change_allocate_filter(int);
|
||||
void lde_change_advertise_filter(int);
|
||||
void lde_change_accept_filter(int);
|
||||
void lde_change_expnull_for_filter(int);
|
||||
struct lde_addr *lde_address_find(struct lde_nbr *, int,
|
||||
union ldpd_addr *);
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ static int ldp_interface_address_delete(ZAPI_CALLBACK_ARGS);
|
|||
static int ldp_zebra_read_route(ZAPI_CALLBACK_ARGS);
|
||||
static int ldp_zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS);
|
||||
static void ldp_zebra_connected(struct zclient *);
|
||||
static void ldp_zebra_filter_update(struct access_list *access);
|
||||
|
||||
static struct zclient *zclient;
|
||||
|
||||
|
@ -525,6 +526,22 @@ ldp_zebra_connected(struct zclient *zclient)
|
|||
ZEBRA_ROUTE_ALL, 0, VRF_DEFAULT);
|
||||
}
|
||||
|
||||
static void
|
||||
ldp_zebra_filter_update(struct access_list *access)
|
||||
{
|
||||
struct ldp_access laccess;
|
||||
|
||||
if (access && access->name[0] != '\0') {
|
||||
strlcpy(laccess.name, access->name, sizeof(laccess.name));
|
||||
laccess.type = access->type;
|
||||
debug_evt("%s ACL update filter name %s type %d", __func__,
|
||||
access->name, access->type);
|
||||
|
||||
main_imsg_compose_both(IMSG_FILTER_UPDATE, &laccess,
|
||||
sizeof(laccess));
|
||||
}
|
||||
}
|
||||
|
||||
extern struct zebra_privs_t ldpd_privs;
|
||||
|
||||
void
|
||||
|
@ -545,6 +562,10 @@ ldp_zebra_init(struct thread_master *master)
|
|||
zclient->redistribute_route_add = ldp_zebra_read_route;
|
||||
zclient->redistribute_route_del = ldp_zebra_read_route;
|
||||
zclient->pw_status_update = ldp_zebra_read_pw_status_update;
|
||||
|
||||
/* Access list initialize. */
|
||||
access_list_add_hook(ldp_zebra_filter_update);
|
||||
access_list_delete_hook(ldp_zebra_filter_update);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1374,8 +1374,7 @@ merge_af(int af, struct ldpd_af_conf *af_conf, struct ldpd_af_conf *xa)
|
|||
}
|
||||
|
||||
/* update ACLs */
|
||||
if (strcmp(af_conf->acl_label_allocate_for,
|
||||
xa->acl_label_allocate_for))
|
||||
if (strcmp(af_conf->acl_label_allocate_for, xa->acl_label_allocate_for))
|
||||
change_host_label = 1;
|
||||
|
||||
if (strcmp(af_conf->acl_label_advertise_to,
|
||||
|
@ -1412,7 +1411,7 @@ merge_af(int af, struct ldpd_af_conf *af_conf, struct ldpd_af_conf *xa)
|
|||
if (change_egress_label)
|
||||
lde_change_egress_label(af);
|
||||
if (change_host_label)
|
||||
lde_change_host_label(af);
|
||||
lde_change_allocate_filter(af);
|
||||
break;
|
||||
case PROC_LDP_ENGINE:
|
||||
if (stop_init_backoff)
|
||||
|
|
|
@ -151,7 +151,9 @@ enum imsg_type {
|
|||
IMSG_LOG,
|
||||
IMSG_ACL_CHECK,
|
||||
IMSG_INIT,
|
||||
IMSG_PW_UPDATE
|
||||
IMSG_PW_UPDATE,
|
||||
IMSG_FILTER_UPDATE,
|
||||
IMSG_NBR_SHUTDOWN
|
||||
};
|
||||
|
||||
struct ldpd_init {
|
||||
|
@ -162,6 +164,11 @@ struct ldpd_init {
|
|||
unsigned short instance;
|
||||
};
|
||||
|
||||
struct ldp_access {
|
||||
char name[ACL_NAMSIZ];
|
||||
enum access_type type;
|
||||
};
|
||||
|
||||
union ldpd_addr {
|
||||
struct in_addr v4;
|
||||
struct in6_addr v6;
|
||||
|
|
35
ldpd/ldpe.c
35
ldpd/ldpe.c
|
@ -42,6 +42,7 @@ static int ldpe_dispatch_pfkey(struct thread *);
|
|||
static void ldpe_setup_sockets(int, int, int, int);
|
||||
static void ldpe_close_sockets(int);
|
||||
static void ldpe_iface_af_ctl(struct ctl_conn *c, int af, ifindex_t ifidx);
|
||||
static void ldpe_check_filter_af(int, struct ldpd_af_conf *, const char *);
|
||||
|
||||
struct ldpd_conf *leconf;
|
||||
#ifdef __OpenBSD__
|
||||
|
@ -292,7 +293,8 @@ ldpe_dispatch_main(struct thread *thread)
|
|||
struct nbr_params *nbrp;
|
||||
#endif
|
||||
int n, shut = 0;
|
||||
|
||||
struct ldp_access *laccess;
|
||||
|
||||
iev->ev_read = NULL;
|
||||
|
||||
if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
|
||||
|
@ -544,6 +546,18 @@ ldpe_dispatch_main(struct thread *thread)
|
|||
}
|
||||
memcpy(&ldp_debug, imsg.data, sizeof(ldp_debug));
|
||||
break;
|
||||
case IMSG_FILTER_UPDATE:
|
||||
if (imsg.hdr.len != IMSG_HEADER_SIZE +
|
||||
sizeof(struct ldp_access)) {
|
||||
log_warnx("%s: wrong imsg len", __func__);
|
||||
break;
|
||||
}
|
||||
laccess = imsg.data;
|
||||
ldpe_check_filter_af(AF_INET, &leconf->ipv4,
|
||||
laccess->name);
|
||||
ldpe_check_filter_af(AF_INET6, &leconf->ipv6,
|
||||
laccess->name);
|
||||
break;
|
||||
default:
|
||||
log_debug("ldpe_dispatch_main: error handling imsg %d",
|
||||
imsg.hdr.type);
|
||||
|
@ -680,6 +694,17 @@ ldpe_dispatch_lde(struct thread *thread)
|
|||
case IMSG_CTL_SHOW_L2VPN_BINDING:
|
||||
control_imsg_relay(&imsg);
|
||||
break;
|
||||
case IMSG_NBR_SHUTDOWN:
|
||||
nbr = nbr_find_peerid(imsg.hdr.peerid);
|
||||
if (nbr == NULL) {
|
||||
log_debug("ldpe_dispatch_lde: cannot find "
|
||||
"neighbor");
|
||||
break;
|
||||
}
|
||||
if (nbr->state != NBR_STA_OPER)
|
||||
break;
|
||||
session_shutdown(nbr,S_SHUTDOWN,0,0);
|
||||
break;
|
||||
default:
|
||||
log_debug("ldpe_dispatch_lde: error handling imsg %d",
|
||||
imsg.hdr.type);
|
||||
|
@ -980,3 +1005,11 @@ mapping_list_clr(struct mapping_head *mh)
|
|||
free(me);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ldpe_check_filter_af(int af, struct ldpd_af_conf *af_conf,
|
||||
const char *filter_name)
|
||||
{
|
||||
if (strcmp(af_conf->acl_thello_accept_from, filter_name) == 0)
|
||||
ldpe_remove_dynamic_tnbrs(af);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue