diff --git a/nest/config.Y b/nest/config.Y index ea16b8fe..5e521396 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -174,7 +174,7 @@ CF_ENUM(T_ENUM_RTS, RTS_, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT, RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE, BABEL, RPKI, L3VPN, AGGREGATED) CF_ENUM(T_ENUM_SCOPE, SCOPE_, HOST, LINK, SITE, ORGANIZATION, UNIVERSE, UNDEFINED) -CF_ENUM(T_ENUM_RTD, RTD_, BLACKHOLE, UNREACHABLE, PROHIBIT) +CF_ENUM(T_ENUM_RTD, RTD_, UNICAST, BLACKHOLE, UNREACHABLE, PROHIBIT) CF_ENUM(T_ENUM_ROA, ROA_, UNKNOWN, VALID, INVALID) CF_ENUM_PX(T_ENUM_AF, AF_, AFI_, IPV4, IPV6) CF_ENUM(T_ENUM_MPLS_POLICY, MPLS_POLICY_, NONE, STATIC, PREFIX, AGGREGATE, VRF) diff --git a/nest/mpls.Y b/nest/mpls.Y index 6cf1f909..1628800f 100644 --- a/nest/mpls.Y +++ b/nest/mpls.Y @@ -53,13 +53,15 @@ mpls_domain_end: { mpls_domain_postconfig(this_mpls_domain); this_mpls_domain = mpls_range: mpls_range_start mpls_range_opt_list mpls_range_end; -mpls_range_start: LABEL RANGE symbol -{ - if (($3->class == SYM_KEYWORD) && ($3->keyword->value == STATIC)) +mpls_range_start: LABEL RANGE STATIC { this_mpls_range = this_mpls_domain->static_range; - else if (($3->class == SYM_KEYWORD) && ($3->keyword->value == DYNAMIC)) +}; + +mpls_range_start: LABEL RANGE DYNAMIC { this_mpls_range = this_mpls_domain->dynamic_range; - else +}; + +mpls_range_start: LABEL RANGE symbol { this_mpls_range = mpls_range_config_new(this_mpls_domain, $3); }; diff --git a/nest/mpls.c b/nest/mpls.c index 0effb339..944659f9 100644 --- a/nest/mpls.c +++ b/nest/mpls.c @@ -1076,23 +1076,24 @@ mpls_get_key_attrs(struct mpls_fec_map *m, ea_list *src) static void mpls_announce_fec(struct mpls_fec_map *m, struct mpls_fec *fec, ea_list *src) { + rte e = { + .src = m->channel->proto->main_source, + }; + + ea_set_attr_u32(&e.attrs, &ea_gen_source, 0, m->mpls_rts); + /* Check existence of hostentry */ const struct eattr *heea = ea_find_by_class(src, &ea_gen_hostentry); if (heea) { /* The same hostentry, but different dependent table */ struct hostentry_adata *head = SKIP_BACK(struct hostentry_adata, ad, heea->u.ad); struct hostentry *he = head->he; - ea_set_hostentry(&src, m->channel->table, he->owner, he->addr, he->link, + ea_set_hostentry(&e.attrs, m->channel->table, he->owner, he->addr, he->link, HOSTENTRY_LABEL_COUNT(head), head->labels); } net_addr_mpls n = NET_ADDR_MPLS(fec->label); - rte e = { - .src = m->channel->proto->main_source, - .attrs = src, - }; - fec->state = MPLS_FEC_CLEAN; rte_update(m->channel, (net_addr *) &n, &e, m->channel->proto->main_source); } diff --git a/proto/l3vpn/l3vpn.c b/proto/l3vpn/l3vpn.c index eace62d0..a3c5de9c 100644 --- a/proto/l3vpn/l3vpn.c +++ b/proto/l3vpn/l3vpn.c @@ -52,7 +52,6 @@ /* * TODO: - * - import/export target reconfiguration * - check for simple nodes in export route * - replace pair of channels with shared channel for one address family * - improve route comparisons in VRFs @@ -120,6 +119,13 @@ l3vpn_export_targets(struct l3vpn_proto *p, const struct adata *src) return dst; } +static inline void +l3vpn_prepare_import_targets(struct l3vpn_proto *p) +{ + const struct f_tree *t = p->import_target; + p->import_target_one = !t->left && !t->right && (t->from.val.ec == t->to.val.ec); +} + static void l3vpn_add_ec(const struct f_tree *t, void *P) { @@ -129,10 +135,10 @@ l3vpn_add_ec(const struct f_tree *t, void *P) } static void -l3vpn_prepare_targets(struct l3vpn_proto *p) +l3vpn_prepare_export_targets(struct l3vpn_proto *p) { - const struct f_tree *t = p->import_target; - p->import_target_one = !t->left && !t->right && (t->from.val.ec == t->to.val.ec); + if (p->export_target_data) + mb_free(p->export_target_data); uint len = 2 * tree_node_count(p->export_target); p->export_target_data = mb_alloc(p->p.pool, len * sizeof(u32)); @@ -403,8 +409,10 @@ l3vpn_start(struct proto *P) p->rd = cf->rd; p->import_target = cf->import_target; p->export_target = cf->export_target; + p->export_target_data = NULL; - l3vpn_prepare_targets(p); + l3vpn_prepare_import_targets(p); + l3vpn_prepare_export_targets(p); proto_setup_mpls_map(P, RTS_L3VPN); @@ -436,30 +444,11 @@ l3vpn_reconfigure(struct proto *P, struct proto_config *CF) !proto_configure_channel(P, &P->mpls_channel, proto_cf_find_channel(CF, NET_MPLS))) return 0; - if ((p->rd != cf->rd) || - !same_tree(p->import_target, cf->import_target) || - !same_tree(p->export_target, cf->export_target)) + if (p->rd != cf->rd) return 0; - /* - if (!same_tree(p->import_target, cf->import_target)) - { - if (p->vpn4_channel && (p->vpn4_channel->channel_state == CS_UP)) - channel_request_feeding(p->vpn4_channel); - - if (p->vpn6_channel && (p->vpn6_channel->channel_state == CS_UP)) - channel_request_feeding(p->vpn6_channel); - } - - if (!same_tree(p->export_target, cf->export_target)) - { - if (p->ip4_channel && (p->ip4_channel->channel_state == CS_UP)) - channel_request_feeding(p->ip4_channel); - - if (p->ip6_channel && (p->ip6_channel->channel_state == CS_UP)) - channel_request_feeding(p->ip6_channel); - } - */ + int import_changed = !same_tree(p->import_target, cf->import_target); + int export_changed = !same_tree(p->export_target, cf->export_target); /* Update pointers to config structures */ p->import_target = cf->import_target; @@ -467,6 +456,32 @@ l3vpn_reconfigure(struct proto *P, struct proto_config *CF) proto_setup_mpls_map(P, RTS_L3VPN); + if (import_changed) + { + TRACE(D_EVENTS, "Import target changed"); + + l3vpn_prepare_import_targets(p); + + if (p->vpn4_channel && (p->vpn4_channel->channel_state == CS_UP)) + channel_request_feeding_dynamic(p->vpn4_channel, CFRT_AUXILIARY); + + if (p->vpn6_channel && (p->vpn6_channel->channel_state == CS_UP)) + channel_request_feeding_dynamic(p->vpn6_channel, CFRT_AUXILIARY); + } + + if (export_changed) + { + TRACE(D_EVENTS, "Export target changed"); + + l3vpn_prepare_export_targets(p); + + if (p->ip4_channel && (p->ip4_channel->channel_state == CS_UP)) + channel_request_feeding_dynamic(p->ip4_channel, CFRT_AUXILIARY); + + if (p->ip6_channel && (p->ip6_channel->channel_state == CS_UP)) + channel_request_feeding_dynamic(p->ip6_channel, CFRT_AUXILIARY); + } + return 1; }