mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-13 17:40:04 +00:00
ldpd: introduce advanced filtering capabilities
This patch introduces several new configuration commands to ldpd. These commands should allow the operator to define advanced filtering policies for things like label advertisement, label allocation, etc. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This commit is contained in:
parent
28e8294caa
commit
45a8eba972
12
ldpd/hello.c
12
ldpd/hello.c
@ -265,9 +265,15 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
|
||||
}
|
||||
|
||||
if (!tnbr) {
|
||||
if (!((flags & F_HELLO_REQ_TARG) &&
|
||||
((ldp_af_conf_get(leconf, af))->flags &
|
||||
F_LDPD_AF_THELLO_ACCEPT)))
|
||||
struct ldpd_af_conf *af_conf;
|
||||
|
||||
if (!(flags & F_HELLO_REQ_TARG))
|
||||
return;
|
||||
af_conf = ldp_af_conf_get(leconf, af);
|
||||
if (!(af_conf->flags & F_LDPD_AF_THELLO_ACCEPT))
|
||||
return;
|
||||
if (ldpe_acl_check(af_conf->acl_thello_accept_from, af,
|
||||
src, (af == AF_INET) ? 32 : 128) != FILTER_PERMIT)
|
||||
return;
|
||||
|
||||
tnbr = tnbr_new(af, src);
|
||||
|
97
ldpd/lde.c
97
ldpd/lde.c
@ -577,11 +577,67 @@ lde_dispatch_parent(struct thread *thread)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
lde_acl_check(char *acl_name, int af, union ldpd_addr *addr, uint8_t prefixlen)
|
||||
{
|
||||
return ldp_acl_request(iev_main_sync, acl_name, af, addr, prefixlen);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
lde_assign_label(void)
|
||||
lde_assign_label(struct fec *fec, int connected)
|
||||
{
|
||||
static uint32_t label = MPLS_LABEL_RESERVED_MAX;
|
||||
|
||||
/* should we allocate a label for this fec? */
|
||||
switch (fec->type) {
|
||||
case FEC_TYPE_IPV4:
|
||||
if ((ldeconf->ipv4.flags & F_LDPD_AF_ALLOCHOSTONLY) &&
|
||||
fec->u.ipv4.prefixlen != 32)
|
||||
return (NO_LABEL);
|
||||
if (lde_acl_check(ldeconf->ipv4.acl_label_allocate_for,
|
||||
AF_INET, (union ldpd_addr *)&fec->u.ipv4.prefix,
|
||||
fec->u.ipv4.prefixlen) != FILTER_PERMIT)
|
||||
return (NO_LABEL);
|
||||
break;
|
||||
case FEC_TYPE_IPV6:
|
||||
if ((ldeconf->ipv6.flags & F_LDPD_AF_ALLOCHOSTONLY) &&
|
||||
fec->u.ipv6.prefixlen != 128)
|
||||
return (NO_LABEL);
|
||||
if (lde_acl_check(ldeconf->ipv6.acl_label_allocate_for,
|
||||
AF_INET6, (union ldpd_addr *)&fec->u.ipv6.prefix,
|
||||
fec->u.ipv6.prefixlen) != FILTER_PERMIT)
|
||||
return (NO_LABEL);
|
||||
break;
|
||||
default:
|
||||
fatalx("lde_assign_label: unexpected fec type");
|
||||
break;
|
||||
}
|
||||
|
||||
if (connected) {
|
||||
/* choose implicit or explicit-null depending on configuration */
|
||||
switch (fec->type) {
|
||||
case FEC_TYPE_IPV4:
|
||||
if (!(ldeconf->ipv4.flags & F_LDPD_AF_EXPNULL))
|
||||
return (MPLS_LABEL_IMPLNULL);
|
||||
if (lde_acl_check(ldeconf->ipv4.acl_label_expnull_for,
|
||||
AF_INET, (union ldpd_addr *)&fec->u.ipv4.prefix,
|
||||
fec->u.ipv4.prefixlen) != FILTER_PERMIT)
|
||||
return (MPLS_LABEL_IMPLNULL);
|
||||
return (MPLS_LABEL_IPV4NULL);
|
||||
case FEC_TYPE_IPV6:
|
||||
if (!(ldeconf->ipv6.flags & F_LDPD_AF_EXPNULL))
|
||||
return (MPLS_LABEL_IMPLNULL);
|
||||
if (lde_acl_check(ldeconf->ipv6.acl_label_expnull_for,
|
||||
AF_INET6, (union ldpd_addr *)&fec->u.ipv6.prefix,
|
||||
fec->u.ipv6.prefixlen) != FILTER_PERMIT)
|
||||
return (MPLS_LABEL_IMPLNULL);
|
||||
return (MPLS_LABEL_IPV6NULL);
|
||||
default:
|
||||
fatalx("lde_assign_label: unexpected fec type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: request label to zebra or define a range of labels for ldpd.
|
||||
*/
|
||||
@ -801,10 +857,24 @@ lde_send_labelmapping(struct lde_nbr *ln, struct fec_node *fn, int single)
|
||||
case FEC_TYPE_IPV4:
|
||||
if (!ln->v4_enabled)
|
||||
return;
|
||||
if (lde_acl_check(ldeconf->ipv4.acl_label_advertise_to,
|
||||
AF_INET, (union ldpd_addr *)&ln->id, 32) != FILTER_PERMIT)
|
||||
return;
|
||||
if (lde_acl_check(ldeconf->ipv4.acl_label_advertise_for,
|
||||
AF_INET, (union ldpd_addr *)&fn->fec.u.ipv4.prefix,
|
||||
fn->fec.u.ipv4.prefixlen) != FILTER_PERMIT)
|
||||
return;
|
||||
break;
|
||||
case FEC_TYPE_IPV6:
|
||||
if (!ln->v6_enabled)
|
||||
return;
|
||||
if (lde_acl_check(ldeconf->ipv6.acl_label_advertise_to,
|
||||
AF_INET, (union ldpd_addr *)&ln->id, 32) != FILTER_PERMIT)
|
||||
return;
|
||||
if (lde_acl_check(ldeconf->ipv6.acl_label_advertise_for,
|
||||
AF_INET6, (union ldpd_addr *)&fn->fec.u.ipv6.prefix,
|
||||
fn->fec.u.ipv6.prefixlen) != FILTER_PERMIT)
|
||||
return;
|
||||
break;
|
||||
case FEC_TYPE_PWID:
|
||||
pw = (struct l2vpn_pw *) fn->data;
|
||||
@ -1266,7 +1336,7 @@ lde_wdraw_del(struct lde_nbr *ln, struct lde_wdraw *lw)
|
||||
}
|
||||
|
||||
void
|
||||
lde_change_egress_label(int af, int was_implicit)
|
||||
lde_change_egress_label(int af)
|
||||
{
|
||||
struct lde_nbr *ln;
|
||||
struct fec *f;
|
||||
@ -1274,17 +1344,13 @@ lde_change_egress_label(int af, int was_implicit)
|
||||
|
||||
/* explicitly withdraw all null labels */
|
||||
RB_FOREACH(ln, nbr_tree, &lde_nbrs) {
|
||||
if (was_implicit)
|
||||
lde_send_labelwithdraw(ln, NULL, MPLS_LABEL_IMPLNULL,
|
||||
lde_send_labelwithdraw(ln, NULL, MPLS_LABEL_IMPLNULL, NULL);
|
||||
if (ln->v4_enabled)
|
||||
lde_send_labelwithdraw(ln, NULL, MPLS_LABEL_IPV4NULL,
|
||||
NULL);
|
||||
if (ln->v6_enabled)
|
||||
lde_send_labelwithdraw(ln, NULL, MPLS_LABEL_IPV6NULL,
|
||||
NULL);
|
||||
else {
|
||||
if (ln->v4_enabled)
|
||||
lde_send_labelwithdraw(ln, NULL,
|
||||
MPLS_LABEL_IPV4NULL, NULL);
|
||||
if (ln->v6_enabled)
|
||||
lde_send_labelwithdraw(ln, NULL,
|
||||
MPLS_LABEL_IPV6NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* update label of connected routes */
|
||||
@ -1306,9 +1372,10 @@ lde_change_egress_label(int af, int was_implicit)
|
||||
fatalx("lde_change_egress_label: unknown af");
|
||||
}
|
||||
|
||||
fn->local_label = egress_label(fn->fec.type);
|
||||
RB_FOREACH(ln, nbr_tree, &lde_nbrs)
|
||||
lde_send_labelmapping(ln, fn, 0);
|
||||
fn->local_label = lde_assign_label(&fn->fec, 1);
|
||||
if (fn->local_label != NO_LABEL)
|
||||
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,
|
||||
|
@ -133,7 +133,8 @@ extern struct thread *gc_timer;
|
||||
void lde(const char *, const char *);
|
||||
int lde_imsg_compose_parent(int, pid_t, void *, uint16_t);
|
||||
int lde_imsg_compose_ldpe(int, uint32_t, pid_t, void *, uint16_t);
|
||||
uint32_t lde_assign_label(void);
|
||||
int lde_acl_check(char *, int, union ldpd_addr *, uint8_t);
|
||||
uint32_t lde_assign_label(struct fec *, int);
|
||||
void lde_send_change_klabel(struct fec_node *, struct fec_nh *);
|
||||
void lde_send_delete_klabel(struct fec_node *, struct fec_nh *);
|
||||
void lde_fec2map(struct fec *, struct map *);
|
||||
@ -154,7 +155,7 @@ struct lde_req *lde_req_add(struct lde_nbr *, struct fec *, int);
|
||||
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, int);
|
||||
void lde_change_egress_label(int);
|
||||
struct lde_addr *lde_address_find(struct lde_nbr *, int,
|
||||
union ldpd_addr *);
|
||||
|
||||
@ -169,7 +170,6 @@ void fec_snap(struct lde_nbr *);
|
||||
void fec_tree_clear(void);
|
||||
struct fec_nh *fec_nh_find(struct fec_node *, int, union ldpd_addr *,
|
||||
ifindex_t, uint8_t);
|
||||
uint32_t egress_label(enum fec_type);
|
||||
void lde_kernel_insert(struct fec *, int, union ldpd_addr *,
|
||||
ifindex_t, uint8_t, int, void *);
|
||||
void lde_kernel_remove(struct fec *, int, union ldpd_addr *,
|
||||
|
@ -305,25 +305,6 @@ 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,
|
||||
ifindex_t ifindex, uint8_t priority, int connected, void *data)
|
||||
@ -347,14 +328,12 @@ 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, ifindex, priority);
|
||||
@ -446,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);
|
||||
|
@ -47,7 +47,10 @@ int ldp_vty_session_holdtime(struct vty *, struct vty_arg *[]);
|
||||
int ldp_vty_interface(struct vty *, struct vty_arg *[]);
|
||||
int ldp_vty_trans_addr(struct vty *, struct vty_arg *[]);
|
||||
int ldp_vty_neighbor_targeted(struct vty *, struct vty_arg *[]);
|
||||
int ldp_vty_explicit_null(struct vty *, struct vty_arg *[]);
|
||||
int ldp_vty_label_advertise(struct vty *, struct vty_arg *[]);
|
||||
int ldp_vty_label_allocate(struct vty *, struct vty_arg *[]);
|
||||
int ldp_vty_label_expnull(struct vty *, struct vty_arg *[]);
|
||||
int ldp_vty_label_accept(struct vty *, struct vty_arg *[]);
|
||||
int ldp_vty_ttl_security(struct vty *, struct vty_arg *[]);
|
||||
int ldp_vty_router_id(struct vty *, struct vty_arg *[]);
|
||||
int ldp_vty_ds_cisco_interop(struct vty *, struct vty_arg *[]);
|
||||
|
@ -30,7 +30,48 @@
|
||||
<option name="sent" help="Sent messages"/>
|
||||
</options>
|
||||
|
||||
<!-- ACL -->
|
||||
<options name="acl">
|
||||
<option input="acl_range" help="IP access-list number"/>
|
||||
<option input="acl_expanded_range" help="IP access-list number (expanded range)"/>
|
||||
<option input="word" help="IP access-list name"/>
|
||||
</options>
|
||||
|
||||
<!-- shared subtrees -->
|
||||
<subtree name="label_local_acls">
|
||||
<option name="to" help="IP Access-list specifying controls on LDP Peers">
|
||||
<select options="acl" arg="to_acl" function="inherited">
|
||||
<option name="for" help="IP access-list for destination prefixes">
|
||||
<select options="acl" arg="for_acl" function="inherited"/>
|
||||
</option>
|
||||
</select>
|
||||
</option>
|
||||
<option name="for" help="IP access-list for destination prefixes">
|
||||
<select options="acl" arg="for_acl" function="inherited">
|
||||
<option name="to" help="IP Access-list specifying controls on LDP Peers">
|
||||
<select options="acl" arg="to_acl" function="inherited"/>
|
||||
</option>
|
||||
</select>
|
||||
</option>
|
||||
</subtree>
|
||||
|
||||
<subtree name="label_remote_acls">
|
||||
<option name="from" help="Neighbor from whom to accept label advertisement">
|
||||
<select options="acl" arg="from_acl" function="inherited">
|
||||
<option name="for" help="IP access-list for destination prefixes">
|
||||
<select options="acl" arg="for_acl" function="inherited"/>
|
||||
</option>
|
||||
</select>
|
||||
</option>
|
||||
<option name="for" help="IP access-list for destination prefixes">
|
||||
<select options="acl" arg="for_acl" function="inherited">
|
||||
<option name="from" help="Neighbor from whom to accept label advertisement">
|
||||
<select options="acl" arg="from_acl" function="inherited"/>
|
||||
</option>
|
||||
</select>
|
||||
</option>
|
||||
</subtree>
|
||||
|
||||
<subtree name="discovery_link">
|
||||
<option name="discovery" help="Configure discovery parameters">
|
||||
<option name="hello" arg="hello_type" help="LDP Link Hellos">
|
||||
@ -70,13 +111,33 @@
|
||||
<include subtree="discovery_targeted"/>
|
||||
<option name="discovery" help="Configure discovery parameters">
|
||||
<option name="targeted-hello" arg="hello_type" help="LDP Targeted Hellos">
|
||||
<option name="accept" help="Accept and respond to targeted hellos" function="ldp_vty_targeted_hello_accept"/>
|
||||
<option name="accept" help="Accept and respond to targeted hellos" function="ldp_vty_targeted_hello_accept">
|
||||
<option name="from" help="Access list to specify acceptable targeted hello source">
|
||||
<select options="acl" arg="from_acl" function="inherited"/>
|
||||
</option>
|
||||
</option>
|
||||
</option>
|
||||
</option>
|
||||
<option name="label" help="Configure label control and policies">
|
||||
<option name="local" help="Configure local label control and policies">
|
||||
<option name="advertise" help="Configure outbound label advertisement control">
|
||||
<option name="explicit-null" help="Configure explicit-null advertisement" function="ldp_vty_explicit_null"/>
|
||||
<option name="advertise" help="Configure outbound label advertisement control" function="ldp_vty_label_advertise">
|
||||
<include subtree="label_local_acls"/>
|
||||
<option name="explicit-null" help="Configure explicit-null advertisement" function="ldp_vty_label_expnull">
|
||||
<option name="for" help="IP access-list for destination prefixes">
|
||||
<select options="acl" arg="for_acl" function="inherited"/>
|
||||
</option>
|
||||
</option>
|
||||
</option>
|
||||
<option name="allocate" help="Configure label allocation control">
|
||||
<option name="for" help="IP access-list">
|
||||
<select options="acl" arg="for_acl" function="ldp_vty_label_allocate"/>
|
||||
</option>
|
||||
<option name="host-routes" arg="host-routes" help="allocate local label for host routes only" function="ldp_vty_label_allocate"/>
|
||||
</option>
|
||||
</option>
|
||||
<option name="remote" help="Configure remote/peer label control and policies">
|
||||
<option name="accept" help="Configure inbound label acceptance control" function="ldp_vty_label_accept">
|
||||
<include subtree="label_remote_acls"/>
|
||||
</option>
|
||||
</option>
|
||||
</option>
|
||||
|
@ -182,9 +182,13 @@ ldp_af_config_write(struct vty *vty, int af, struct ldpd_conf *conf,
|
||||
vty_out(vty, " discovery hello interval %u%s",
|
||||
af_conf->lhello_interval, VTY_NEWLINE);
|
||||
|
||||
if (af_conf->flags & F_LDPD_AF_THELLO_ACCEPT)
|
||||
vty_out(vty, " discovery targeted-hello accept%s",
|
||||
VTY_NEWLINE);
|
||||
if (af_conf->flags & F_LDPD_AF_THELLO_ACCEPT) {
|
||||
vty_out(vty, " discovery targeted-hello accept");
|
||||
if (af_conf->acl_thello_accept_from[0] != '\0')
|
||||
vty_out(vty, " from %s",
|
||||
af_conf->acl_thello_accept_from);
|
||||
vty_out(vty, "%s", VTY_NEWLINE);
|
||||
}
|
||||
|
||||
if (af_conf->thello_holdtime != TARGETED_DFLT_HOLDTIME &&
|
||||
af_conf->thello_holdtime != 0)
|
||||
@ -202,9 +206,48 @@ ldp_af_config_write(struct vty *vty, int af, struct ldpd_conf *conf,
|
||||
vty_out(vty, " ! Incomplete config, specify a discovery "
|
||||
"transport-address%s", VTY_NEWLINE);
|
||||
|
||||
if (af_conf->flags & F_LDPD_AF_EXPNULL)
|
||||
vty_out(vty, " label local advertise explicit-null%s",
|
||||
VTY_NEWLINE);
|
||||
if ((af_conf->flags & F_LDPD_AF_ALLOCHOSTONLY) ||
|
||||
af_conf->acl_label_allocate_for[0] != '\0') {
|
||||
vty_out(vty, " label local allocate");
|
||||
if (af_conf->flags & F_LDPD_AF_ALLOCHOSTONLY)
|
||||
vty_out(vty, " host-routes");
|
||||
else
|
||||
vty_out(vty, " for %s",
|
||||
af_conf->acl_label_allocate_for);
|
||||
vty_out(vty, "%s", VTY_NEWLINE);
|
||||
}
|
||||
|
||||
if (af_conf->acl_label_advertise_for[0] != '\0' ||
|
||||
af_conf->acl_label_advertise_to[0] != '\0') {
|
||||
vty_out(vty, " label local advertise");
|
||||
if (af_conf->acl_label_advertise_to[0] != '\0')
|
||||
vty_out(vty, " to %s",
|
||||
af_conf->acl_label_advertise_to);
|
||||
if (af_conf->acl_label_advertise_for[0] != '\0')
|
||||
vty_out(vty, " for %s",
|
||||
af_conf->acl_label_advertise_for);
|
||||
vty_out(vty, "%s", VTY_NEWLINE);
|
||||
}
|
||||
|
||||
if (af_conf->flags & F_LDPD_AF_EXPNULL) {
|
||||
vty_out(vty, " label local advertise explicit-null");
|
||||
if (af_conf->acl_label_expnull_for[0] != '\0')
|
||||
vty_out(vty, " for %s",
|
||||
af_conf->acl_label_expnull_for);
|
||||
vty_out(vty, "%s", VTY_NEWLINE);
|
||||
}
|
||||
|
||||
if (af_conf->acl_label_accept_for[0] != '\0' ||
|
||||
af_conf->acl_label_accept_from[0] != '\0') {
|
||||
vty_out(vty, " label remote accept");
|
||||
if (af_conf->acl_label_accept_from[0] != '\0')
|
||||
vty_out(vty, " from %s",
|
||||
af_conf->acl_label_accept_from);
|
||||
if (af_conf->acl_label_accept_for[0] != '\0')
|
||||
vty_out(vty, " for %s",
|
||||
af_conf->acl_label_accept_for);
|
||||
vty_out(vty, "%s", VTY_NEWLINE);
|
||||
}
|
||||
|
||||
if (af_conf->flags & F_LDPD_AF_NO_GTSM)
|
||||
vty_out(vty, " ttl-security disable%s", VTY_NEWLINE);
|
||||
@ -681,19 +724,28 @@ ldp_vty_targeted_hello_accept(struct vty *vty, struct vty_arg *args[])
|
||||
struct ldpd_conf *vty_conf;
|
||||
struct ldpd_af_conf *af_conf;
|
||||
int af;
|
||||
const char *acl_from_str;
|
||||
int disable;
|
||||
|
||||
vty_conf = ldp_dup_config(ldpd_conf);
|
||||
|
||||
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
|
||||
acl_from_str = vty_get_arg_value(args, "from_acl");
|
||||
|
||||
af = ldp_vty_get_af(vty);
|
||||
af_conf = ldp_af_conf_get(vty_conf, af);
|
||||
|
||||
if (disable)
|
||||
if (disable) {
|
||||
af_conf->flags &= ~F_LDPD_AF_THELLO_ACCEPT;
|
||||
else
|
||||
af_conf->acl_thello_accept_from[0] = '\0';
|
||||
} else {
|
||||
af_conf->flags |= F_LDPD_AF_THELLO_ACCEPT;
|
||||
if (acl_from_str)
|
||||
strlcpy(af_conf->acl_thello_accept_from, acl_from_str,
|
||||
sizeof(af_conf->acl_thello_accept_from));
|
||||
else
|
||||
af_conf->acl_thello_accept_from[0] = '\0';
|
||||
}
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
|
||||
@ -978,23 +1030,143 @@ cancel:
|
||||
}
|
||||
|
||||
int
|
||||
ldp_vty_explicit_null(struct vty *vty, struct vty_arg *args[])
|
||||
ldp_vty_label_advertise(struct vty *vty, struct vty_arg *args[])
|
||||
{
|
||||
struct ldpd_conf *vty_conf;
|
||||
struct ldpd_af_conf *af_conf;
|
||||
int af;
|
||||
const char *acl_to_str;
|
||||
const char *acl_for_str;
|
||||
int disable;
|
||||
|
||||
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
|
||||
acl_to_str = vty_get_arg_value(args, "to_acl");
|
||||
acl_for_str = vty_get_arg_value(args, "for_acl");
|
||||
|
||||
vty_conf = ldp_dup_config(ldpd_conf);
|
||||
af = ldp_vty_get_af(vty);
|
||||
af_conf = ldp_af_conf_get(vty_conf, af);
|
||||
|
||||
if (disable)
|
||||
if (disable) {
|
||||
af_conf->acl_label_advertise_to[0] = '\0';
|
||||
af_conf->acl_label_advertise_for[0] = '\0';
|
||||
} else {
|
||||
if (acl_to_str)
|
||||
strlcpy(af_conf->acl_label_advertise_to, acl_to_str,
|
||||
sizeof(af_conf->acl_label_advertise_to));
|
||||
else
|
||||
af_conf->acl_label_advertise_to[0] = '\0';
|
||||
if (acl_for_str)
|
||||
strlcpy(af_conf->acl_label_advertise_for, acl_for_str,
|
||||
sizeof(af_conf->acl_label_advertise_for));
|
||||
else
|
||||
af_conf->acl_label_advertise_for[0] = '\0';
|
||||
}
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
|
||||
return (CMD_SUCCESS);
|
||||
}
|
||||
|
||||
int
|
||||
ldp_vty_label_allocate(struct vty *vty, struct vty_arg *args[])
|
||||
{
|
||||
struct ldpd_conf *vty_conf;
|
||||
struct ldpd_af_conf *af_conf;
|
||||
int af;
|
||||
const char *acl_for_str;
|
||||
const char *host_routes_str;
|
||||
int disable;
|
||||
|
||||
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
|
||||
acl_for_str = vty_get_arg_value(args, "for_acl");
|
||||
host_routes_str = vty_get_arg_value(args, "host-routes");
|
||||
|
||||
vty_conf = ldp_dup_config(ldpd_conf);
|
||||
af = ldp_vty_get_af(vty);
|
||||
af_conf = ldp_af_conf_get(vty_conf, af);
|
||||
|
||||
af_conf->flags &= ~F_LDPD_AF_ALLOCHOSTONLY;
|
||||
af_conf->acl_label_allocate_for[0] = '\0';
|
||||
if (!disable) {
|
||||
if (host_routes_str)
|
||||
af_conf->flags |= F_LDPD_AF_ALLOCHOSTONLY;
|
||||
else
|
||||
strlcpy(af_conf->acl_label_allocate_for, acl_for_str,
|
||||
sizeof(af_conf->acl_label_allocate_for));
|
||||
}
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
|
||||
return (CMD_SUCCESS);
|
||||
}
|
||||
|
||||
int
|
||||
ldp_vty_label_expnull(struct vty *vty, struct vty_arg *args[])
|
||||
{
|
||||
struct ldpd_conf *vty_conf;
|
||||
struct ldpd_af_conf *af_conf;
|
||||
int af;
|
||||
const char *acl_for_str;
|
||||
int disable;
|
||||
|
||||
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
|
||||
acl_for_str = vty_get_arg_value(args, "for_acl");
|
||||
|
||||
vty_conf = ldp_dup_config(ldpd_conf);
|
||||
af = ldp_vty_get_af(vty);
|
||||
af_conf = ldp_af_conf_get(vty_conf, af);
|
||||
|
||||
if (disable) {
|
||||
af_conf->flags &= ~F_LDPD_AF_EXPNULL;
|
||||
else
|
||||
af_conf->acl_label_expnull_for[0] = '\0';
|
||||
} else {
|
||||
af_conf->flags |= F_LDPD_AF_EXPNULL;
|
||||
if (acl_for_str)
|
||||
strlcpy(af_conf->acl_label_expnull_for, acl_for_str,
|
||||
sizeof(af_conf->acl_label_expnull_for));
|
||||
else
|
||||
af_conf->acl_label_expnull_for[0] = '\0';
|
||||
}
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
|
||||
return (CMD_SUCCESS);
|
||||
}
|
||||
|
||||
int
|
||||
ldp_vty_label_accept(struct vty *vty, struct vty_arg *args[])
|
||||
{
|
||||
struct ldpd_conf *vty_conf;
|
||||
struct ldpd_af_conf *af_conf;
|
||||
int af;
|
||||
const char *acl_from_str;
|
||||
const char *acl_for_str;
|
||||
int disable;
|
||||
|
||||
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
|
||||
acl_from_str = vty_get_arg_value(args, "from_acl");
|
||||
acl_for_str = vty_get_arg_value(args, "for_acl");
|
||||
|
||||
vty_conf = ldp_dup_config(ldpd_conf);
|
||||
af = ldp_vty_get_af(vty);
|
||||
af_conf = ldp_af_conf_get(vty_conf, af);
|
||||
|
||||
if (disable) {
|
||||
af_conf->acl_label_accept_from[0] = '\0';
|
||||
af_conf->acl_label_accept_for[0] = '\0';
|
||||
} else {
|
||||
if (acl_from_str)
|
||||
strlcpy(af_conf->acl_label_accept_from, acl_from_str,
|
||||
sizeof(af_conf->acl_label_accept_from));
|
||||
else
|
||||
af_conf->acl_label_accept_from[0] = '\0';
|
||||
if (acl_for_str)
|
||||
strlcpy(af_conf->acl_label_accept_for, acl_for_str,
|
||||
sizeof(af_conf->acl_label_accept_for));
|
||||
else
|
||||
af_conf->acl_label_accept_for[0] = '\0';
|
||||
}
|
||||
|
||||
ldp_reload(vty_conf);
|
||||
|
||||
|
175
ldpd/ldpd.c
175
ldpd/ldpd.c
@ -39,6 +39,7 @@
|
||||
#include "sigevent.h"
|
||||
#include "zclient.h"
|
||||
#include "vrf.h"
|
||||
#include "filter.h"
|
||||
#include "qobj.h"
|
||||
|
||||
static void ldpd_shutdown(void);
|
||||
@ -326,6 +327,7 @@ main(int argc, char *argv[])
|
||||
vty_config_lockless ();
|
||||
vty_init(master);
|
||||
vrf_init();
|
||||
access_list_init ();
|
||||
ldp_vty_init();
|
||||
ldp_vty_if_init();
|
||||
|
||||
@ -479,6 +481,7 @@ ldpd_shutdown(void)
|
||||
log_info("terminating");
|
||||
|
||||
vrf_terminate();
|
||||
access_list_reset();
|
||||
cmd_terminate();
|
||||
vty_terminate();
|
||||
ldp_zebra_destroy();
|
||||
@ -572,6 +575,12 @@ main_dispatch_ldpe(struct thread *thread)
|
||||
af = imsg.hdr.pid;
|
||||
main_imsg_send_net_sockets(af);
|
||||
break;
|
||||
case IMSG_ACL_CHECK:
|
||||
if (imsg.hdr.len != IMSG_HEADER_SIZE +
|
||||
sizeof(struct acl_check))
|
||||
fatalx("IMSG_ACL_CHECK imsg with wrong len");
|
||||
ldp_acl_reply(iev, (struct acl_check *)imsg.data);
|
||||
break;
|
||||
default:
|
||||
log_debug("%s: error handling imsg %d", __func__,
|
||||
imsg.hdr.type);
|
||||
@ -653,6 +662,12 @@ main_dispatch_lde(struct thread *thread)
|
||||
log_warnx("%s: error unsetting pseudowire",
|
||||
__func__);
|
||||
break;
|
||||
case IMSG_ACL_CHECK:
|
||||
if (imsg.hdr.len != IMSG_HEADER_SIZE +
|
||||
sizeof(struct acl_check))
|
||||
fatalx("IMSG_ACL_CHECK imsg with wrong len");
|
||||
ldp_acl_reply(iev, (struct acl_check *)imsg.data);
|
||||
break;
|
||||
default:
|
||||
log_debug("%s: error handling imsg %d", __func__,
|
||||
imsg.hdr.type);
|
||||
@ -831,6 +846,70 @@ main_imsg_send_net_socket(int af, enum socket_type type)
|
||||
sizeof(type));
|
||||
}
|
||||
|
||||
int
|
||||
ldp_acl_request(struct imsgev *iev, char *acl_name, int af,
|
||||
union ldpd_addr *addr, uint8_t prefixlen)
|
||||
{
|
||||
struct imsg imsg;
|
||||
ssize_t n;
|
||||
struct acl_check acl_check;
|
||||
|
||||
if (acl_name[0] == '\0')
|
||||
return FILTER_PERMIT;
|
||||
|
||||
/* build request */
|
||||
strlcpy(acl_check.acl, acl_name, sizeof(acl_check.acl));
|
||||
acl_check.af = af;
|
||||
acl_check.addr = *addr;
|
||||
acl_check.prefixlen = prefixlen;
|
||||
|
||||
/* send (blocking) */
|
||||
imsg_compose_event(iev, IMSG_ACL_CHECK, 0, 0, -1, &acl_check,
|
||||
sizeof(acl_check));
|
||||
imsg_flush(&iev->ibuf);
|
||||
|
||||
/* receive (blocking) and parse result */
|
||||
if ((n = imsg_read(&iev->ibuf)) == -1)
|
||||
fatal("imsg_read error");
|
||||
if ((n = imsg_get(&iev->ibuf, &imsg)) == -1)
|
||||
fatal("imsg_get");
|
||||
if (imsg.hdr.type != IMSG_ACL_CHECK ||
|
||||
imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(int))
|
||||
fatalx("ldp_acl_request: invalid response");
|
||||
|
||||
return (*((int *)imsg.data));
|
||||
}
|
||||
|
||||
void
|
||||
ldp_acl_reply(struct imsgev *iev, struct acl_check *acl_check)
|
||||
{
|
||||
struct access_list *alist;
|
||||
struct prefix prefix;
|
||||
int result;
|
||||
|
||||
alist = access_list_lookup(family2afi(acl_check->af), acl_check->acl);
|
||||
if (alist == NULL)
|
||||
result = FILTER_DENY;
|
||||
else {
|
||||
prefix.family = acl_check->af;
|
||||
switch (prefix.family) {
|
||||
case AF_INET:
|
||||
prefix.u.prefix4 = acl_check->addr.v4;
|
||||
break;
|
||||
case AF_INET6:
|
||||
prefix.u.prefix6 = acl_check->addr.v6;
|
||||
break;
|
||||
default:
|
||||
fatalx("ldp_acl_reply: unknown af");
|
||||
}
|
||||
prefix.prefixlen = acl_check->prefixlen;
|
||||
result = access_list_apply(alist, &prefix);
|
||||
}
|
||||
|
||||
imsg_compose_event(iev, IMSG_ACL_CHECK, 0, 0, -1, &result,
|
||||
sizeof(result));
|
||||
}
|
||||
|
||||
struct ldpd_af_conf *
|
||||
ldp_af_conf_get(struct ldpd_conf *xconf, int af)
|
||||
{
|
||||
@ -1177,8 +1256,7 @@ merge_global(struct ldpd_conf *conf, struct ldpd_conf *xconf)
|
||||
/* change of router-id requires resetting all neighborships */
|
||||
if (conf->rtr_id.s_addr != xconf->rtr_id.s_addr) {
|
||||
if (ldpd_process == PROC_LDP_ENGINE) {
|
||||
ldpe_reset_nbrs(AF_INET);
|
||||
ldpe_reset_nbrs(AF_INET6);
|
||||
ldpe_reset_nbrs(AF_UNSPEC);
|
||||
if (conf->rtr_id.s_addr == INADDR_ANY ||
|
||||
xconf->rtr_id.s_addr == INADDR_ANY) {
|
||||
if_update_all(AF_UNSPEC);
|
||||
@ -1211,61 +1289,98 @@ merge_global(struct ldpd_conf *conf, struct ldpd_conf *xconf)
|
||||
static void
|
||||
merge_af(int af, struct ldpd_af_conf *af_conf, struct ldpd_af_conf *xa)
|
||||
{
|
||||
int egress_label_changed = 0;
|
||||
int update_sockets = 0;
|
||||
int stop_init_backoff = 0;
|
||||
int remove_dynamic_tnbrs = 0;
|
||||
int change_egress_label = 0;
|
||||
int reset_nbrs_ipv4 = 0;
|
||||
int reset_nbrs = 0;
|
||||
int update_sockets = 0;
|
||||
|
||||
/* update timers */
|
||||
if (af_conf->keepalive != xa->keepalive) {
|
||||
af_conf->keepalive = xa->keepalive;
|
||||
if (ldpd_process == PROC_LDP_ENGINE)
|
||||
ldpe_stop_init_backoff(af);
|
||||
stop_init_backoff = 1;
|
||||
}
|
||||
|
||||
af_conf->lhello_holdtime = xa->lhello_holdtime;
|
||||
af_conf->lhello_interval = xa->lhello_interval;
|
||||
af_conf->thello_holdtime = xa->thello_holdtime;
|
||||
af_conf->thello_interval = xa->thello_interval;
|
||||
|
||||
/* update flags */
|
||||
if (ldpd_process == PROC_LDP_ENGINE &&
|
||||
(af_conf->flags & F_LDPD_AF_THELLO_ACCEPT) &&
|
||||
if ((af_conf->flags & F_LDPD_AF_THELLO_ACCEPT) &&
|
||||
!(xa->flags & F_LDPD_AF_THELLO_ACCEPT))
|
||||
ldpe_remove_dynamic_tnbrs(af);
|
||||
|
||||
remove_dynamic_tnbrs = 1;
|
||||
if ((af_conf->flags & F_LDPD_AF_NO_GTSM) !=
|
||||
(xa->flags & F_LDPD_AF_NO_GTSM)) {
|
||||
if (af == AF_INET6)
|
||||
/* need to set/unset IPV6_MINHOPCOUNT */
|
||||
update_sockets = 1;
|
||||
else if (ldpd_process == PROC_LDP_ENGINE)
|
||||
else
|
||||
/* for LDPv4 just resetting the neighbors is enough */
|
||||
ldpe_reset_nbrs(af);
|
||||
reset_nbrs_ipv4 = 1;
|
||||
}
|
||||
|
||||
if ((af_conf->flags & F_LDPD_AF_EXPNULL) !=
|
||||
(xa->flags & F_LDPD_AF_EXPNULL))
|
||||
egress_label_changed = 1;
|
||||
|
||||
change_egress_label = 1;
|
||||
af_conf->flags = xa->flags;
|
||||
|
||||
if (egress_label_changed) {
|
||||
switch (ldpd_process) {
|
||||
case PROC_LDE_ENGINE:
|
||||
lde_change_egress_label(af, af_conf->flags &
|
||||
F_LDPD_AF_EXPNULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* update the transport address */
|
||||
if (ldp_addrcmp(af, &af_conf->trans_addr, &xa->trans_addr)) {
|
||||
af_conf->trans_addr = xa->trans_addr;
|
||||
update_sockets = 1;
|
||||
}
|
||||
|
||||
if (ldpd_process == PROC_MAIN && iev_ldpe && update_sockets)
|
||||
imsg_compose_event(iev_ldpe, IMSG_CLOSE_SOCKETS, af, 0, -1,
|
||||
NULL, 0);
|
||||
/* update ACLs */
|
||||
if (strcmp(af_conf->acl_label_advertise_to,
|
||||
xa->acl_label_advertise_to) ||
|
||||
strcmp(af_conf->acl_label_advertise_for,
|
||||
xa->acl_label_advertise_for) ||
|
||||
strcmp(af_conf->acl_label_accept_from,
|
||||
xa->acl_label_accept_from) ||
|
||||
strcmp(af_conf->acl_label_accept_for,
|
||||
xa->acl_label_accept_for))
|
||||
reset_nbrs = 1;
|
||||
if (strcmp(af_conf->acl_thello_accept_from, xa->acl_thello_accept_from))
|
||||
remove_dynamic_tnbrs = 1;
|
||||
if (strcmp(af_conf->acl_label_expnull_for, xa->acl_label_expnull_for))
|
||||
change_egress_label = 1;
|
||||
strlcpy(af_conf->acl_thello_accept_from, xa->acl_thello_accept_from,
|
||||
sizeof(af_conf->acl_thello_accept_from));
|
||||
strlcpy(af_conf->acl_label_allocate_for, xa->acl_label_allocate_for,
|
||||
sizeof(af_conf->acl_label_allocate_for));
|
||||
strlcpy(af_conf->acl_label_advertise_to, xa->acl_label_advertise_to,
|
||||
sizeof(af_conf->acl_label_advertise_to));
|
||||
strlcpy(af_conf->acl_label_advertise_for, xa->acl_label_advertise_for,
|
||||
sizeof(af_conf->acl_label_advertise_for));
|
||||
strlcpy(af_conf->acl_label_accept_from, xa->acl_label_accept_from,
|
||||
sizeof(af_conf->acl_label_accept_from));
|
||||
strlcpy(af_conf->acl_label_accept_for, xa->acl_label_accept_for,
|
||||
sizeof(af_conf->acl_label_accept_for));
|
||||
strlcpy(af_conf->acl_label_expnull_for, xa->acl_label_expnull_for,
|
||||
sizeof(af_conf->acl_label_expnull_for));
|
||||
|
||||
/* apply the new configuration */
|
||||
switch (ldpd_process) {
|
||||
case PROC_LDE_ENGINE:
|
||||
if (change_egress_label)
|
||||
lde_change_egress_label(af);
|
||||
break;
|
||||
case PROC_LDP_ENGINE:
|
||||
if (stop_init_backoff)
|
||||
ldpe_stop_init_backoff(af);
|
||||
if (remove_dynamic_tnbrs)
|
||||
ldpe_remove_dynamic_tnbrs(af);
|
||||
if (reset_nbrs)
|
||||
ldpe_reset_nbrs(AF_UNSPEC);
|
||||
else if (reset_nbrs_ipv4)
|
||||
ldpe_reset_nbrs(AF_INET);
|
||||
break;
|
||||
case PROC_MAIN:
|
||||
if (update_sockets && iev_ldpe)
|
||||
imsg_compose_event(iev_ldpe, IMSG_CLOSE_SOCKETS, af,
|
||||
0, -1, NULL, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
22
ldpd/ldpd.h
22
ldpd/ldpd.h
@ -27,6 +27,7 @@
|
||||
#include "imsg.h"
|
||||
#include "thread.h"
|
||||
#include "qobj.h"
|
||||
#include "filter.h"
|
||||
|
||||
#include "ldp.h"
|
||||
|
||||
@ -138,7 +139,8 @@ enum imsg_type {
|
||||
IMSG_RECONF_L2VPN_IPW,
|
||||
IMSG_RECONF_END,
|
||||
IMSG_DEBUG_UPDATE,
|
||||
IMSG_LOG
|
||||
IMSG_LOG,
|
||||
IMSG_ACL_CHECK
|
||||
};
|
||||
|
||||
union ldpd_addr {
|
||||
@ -411,12 +413,20 @@ struct ldpd_af_conf {
|
||||
uint16_t thello_holdtime;
|
||||
uint16_t thello_interval;
|
||||
union ldpd_addr trans_addr;
|
||||
char acl_thello_accept_from[ACL_NAMSIZ];
|
||||
char acl_label_allocate_for[ACL_NAMSIZ];
|
||||
char acl_label_advertise_to[ACL_NAMSIZ];
|
||||
char acl_label_advertise_for[ACL_NAMSIZ];
|
||||
char acl_label_expnull_for[ACL_NAMSIZ];
|
||||
char acl_label_accept_from[ACL_NAMSIZ];
|
||||
char acl_label_accept_for[ACL_NAMSIZ];
|
||||
int flags;
|
||||
};
|
||||
#define F_LDPD_AF_ENABLED 0x0001
|
||||
#define F_LDPD_AF_THELLO_ACCEPT 0x0002
|
||||
#define F_LDPD_AF_EXPNULL 0x0004
|
||||
#define F_LDPD_AF_NO_GTSM 0x0008
|
||||
#define F_LDPD_AF_ALLOCHOSTONLY 0x0010
|
||||
|
||||
struct ldpd_conf {
|
||||
struct in_addr rtr_id;
|
||||
@ -500,6 +510,13 @@ struct kif {
|
||||
int mtu;
|
||||
};
|
||||
|
||||
struct acl_check {
|
||||
char acl[ACL_NAMSIZ];
|
||||
int af;
|
||||
union ldpd_addr addr;
|
||||
uint8_t prefixlen;
|
||||
};
|
||||
|
||||
/* control data structures */
|
||||
struct ctl_iface {
|
||||
int af;
|
||||
@ -630,6 +647,9 @@ void evbuf_event_add(struct evbuf *);
|
||||
void evbuf_init(struct evbuf *, int,
|
||||
int (*)(struct thread *), void *);
|
||||
void evbuf_clear(struct evbuf *);
|
||||
int ldp_acl_request(struct imsgev *, char *, int,
|
||||
union ldpd_addr *, uint8_t);
|
||||
void ldp_acl_reply(struct imsgev *, struct acl_check *);
|
||||
struct ldpd_af_conf *ldp_af_conf_get(struct ldpd_conf *, int);
|
||||
struct ldpd_af_global *ldp_af_global_get(struct ldpd_global *, int);
|
||||
int ldp_is_dual_stack(struct ldpd_conf *);
|
||||
|
11
ldpd/ldpe.c
11
ldpd/ldpe.c
@ -408,8 +408,7 @@ ldpe_dispatch_main(struct thread *thread)
|
||||
memcpy(&global.rtr_id, imsg.data,
|
||||
sizeof(global.rtr_id));
|
||||
if (leconf->rtr_id.s_addr == INADDR_ANY) {
|
||||
ldpe_reset_nbrs(AF_INET);
|
||||
ldpe_reset_nbrs(AF_INET6);
|
||||
ldpe_reset_nbrs(AF_UNSPEC);
|
||||
}
|
||||
if_update_all(AF_UNSPEC);
|
||||
tnbr_update_all(AF_UNSPEC);
|
||||
@ -722,13 +721,19 @@ ldpe_close_sockets(int af)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ldpe_acl_check(char *acl_name, int af, union ldpd_addr *addr, uint8_t prefixlen)
|
||||
{
|
||||
return ldp_acl_request(iev_main_sync, acl_name, af, addr, prefixlen);
|
||||
}
|
||||
|
||||
void
|
||||
ldpe_reset_nbrs(int af)
|
||||
{
|
||||
struct nbr *nbr;
|
||||
|
||||
RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) {
|
||||
if (nbr->af == af)
|
||||
if (af == AF_UNSPEC || nbr->af == af)
|
||||
session_shutdown(nbr, S_SHUTDOWN, 0, 0);
|
||||
}
|
||||
}
|
||||
|
@ -192,6 +192,7 @@ int ldpe_imsg_compose_parent(int, pid_t, void *,
|
||||
uint16_t);
|
||||
int ldpe_imsg_compose_lde(int, uint32_t, pid_t, void *,
|
||||
uint16_t);
|
||||
int ldpe_acl_check(char *, int, union ldpd_addr *, uint8_t);
|
||||
void ldpe_reset_nbrs(int);
|
||||
void ldpe_reset_ds_nbrs(void);
|
||||
void ldpe_remove_dynamic_tnbrs(int);
|
||||
|
@ -1259,6 +1259,14 @@ filter_set_zebra (struct vty *vty, const char *name_str, const char *type_str,
|
||||
struct access_list *access;
|
||||
struct prefix p;
|
||||
|
||||
if (strlen(name_str) > ACL_NAMSIZ)
|
||||
{
|
||||
vty_out (vty, "%% ACL name %s is invalid: length exceeds "
|
||||
"%d characters%s",
|
||||
name_str, ACL_NAMSIZ, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
/* Check of filter type. */
|
||||
if (strncmp (type_str, "p", 1) == 0)
|
||||
type = FILTER_PERMIT;
|
||||
|
@ -25,6 +25,9 @@
|
||||
|
||||
#include "if.h"
|
||||
|
||||
/* Maximum ACL name length */
|
||||
#define ACL_NAMSIZ 128
|
||||
|
||||
/* Filter direction. */
|
||||
#define FILTER_IN 0
|
||||
#define FILTER_OUT 1
|
||||
|
@ -42,6 +42,8 @@ use XML::LibXML;
|
||||
"ipv6" => "X:X::X:X",
|
||||
"ipv6m" => "X:X::X:X/M",
|
||||
"mtu" => "(1500-9180)",
|
||||
"acl_range" => "(1-199)",
|
||||
"acl_expanded_range" => "(1300-2699)",
|
||||
# BGP specific
|
||||
"rd" => "ASN:nn_or_IP-address:nn",
|
||||
"asn" => "(1-4294967295)",
|
||||
@ -207,7 +209,7 @@ sub generate_code {
|
||||
}
|
||||
|
||||
# update the command string
|
||||
if ($node{'function'} ne "inherited") {
|
||||
if ($node{'function'} ne "inherited" and $node{'function'}) {
|
||||
$function = $node{'function'};
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user