mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
Static: Add syntax for static MPLS labels
Instead of just using route attributes, static routes with static MPLS labels can be defined just by e.g.: route 10.1.1.0/24 mpls 100 via 10.1.2.1 mpls 200;
This commit is contained in:
parent
3572605151
commit
81a20ca5d8
@ -825,7 +825,9 @@ mpls_free_fec(struct mpls_fec_map *m, struct mpls_fec *fec)
|
|||||||
|
|
||||||
DBG("Free FEC %u\n", fec->label);
|
DBG("Free FEC %u\n", fec->label);
|
||||||
|
|
||||||
mpls_free_label(m->domain, m->handle, fec->label);
|
if (fec->policy != MPLS_POLICY_STATIC)
|
||||||
|
mpls_free_label(m->domain, m->handle, fec->label);
|
||||||
|
|
||||||
HASH_REMOVE2(m->label_hash, LABEL, m->pool, fec);
|
HASH_REMOVE2(m->label_hash, LABEL, m->pool, fec);
|
||||||
|
|
||||||
switch (fec->policy)
|
switch (fec->policy)
|
||||||
|
@ -107,15 +107,21 @@ stat_nexthops:
|
|||||||
| stat_nexthops stat_nexthop
|
| stat_nexthops stat_nexthop
|
||||||
;
|
;
|
||||||
|
|
||||||
|
stat_mpls:
|
||||||
|
/* empty */
|
||||||
|
| MPLS expr { this_srt->mpls_label = $2; if ($2 >= MPLS_MAX_LABEL) cf_error("MPLS label must be less than 2^20"); }
|
||||||
|
;
|
||||||
|
|
||||||
stat_route0: ROUTE net_any {
|
stat_route0: ROUTE net_any {
|
||||||
this_srt = cfg_allocz(sizeof(struct static_route));
|
this_srt = cfg_allocz(sizeof(struct static_route));
|
||||||
add_tail(&STATIC_CFG->routes, &this_srt->n);
|
add_tail(&STATIC_CFG->routes, &this_srt->n);
|
||||||
this_srt->net = $2;
|
this_srt->net = $2;
|
||||||
|
this_srt->mpls_label = (uint) -1;
|
||||||
this_srt_cmds = NULL;
|
this_srt_cmds = NULL;
|
||||||
this_srt_last_cmd = NULL;
|
this_srt_last_cmd = NULL;
|
||||||
this_srt->mp_next = NULL;
|
this_srt->mp_next = NULL;
|
||||||
this_snh = NULL;
|
this_snh = NULL;
|
||||||
}
|
} stat_mpls
|
||||||
;
|
;
|
||||||
|
|
||||||
stat_route:
|
stat_route:
|
||||||
|
@ -103,16 +103,37 @@ static_announce_rte(struct static_proto *p, struct static_route *r)
|
|||||||
{
|
{
|
||||||
struct mpls_channel *mc = (void *) p->p.mpls_channel;
|
struct mpls_channel *mc = (void *) p->p.mpls_channel;
|
||||||
|
|
||||||
ea_list *ea = alloca(sizeof(ea_list) + sizeof(eattr));
|
ea_list *ea = alloca(sizeof(ea_list) + 2 * sizeof(eattr));
|
||||||
*ea = (ea_list) { .flags = EALF_SORTED, .count = 1 };
|
*ea = (ea_list) { .flags = EALF_SORTED };
|
||||||
ea->next = a->eattrs;
|
ea->next = a->eattrs;
|
||||||
a->eattrs = ea;
|
a->eattrs = ea;
|
||||||
|
|
||||||
ea->attrs[0] = (eattr) {
|
if (r->mpls_label != (uint) -1)
|
||||||
.id = EA_MPLS_POLICY,
|
{
|
||||||
.type = EAF_TYPE_INT,
|
ea->attrs[0] = (eattr) {
|
||||||
.u.data = mc->label_policy,
|
.id = EA_MPLS_LABEL,
|
||||||
};
|
.type = EAF_TYPE_INT,
|
||||||
|
.u.data = r->mpls_label,
|
||||||
|
};
|
||||||
|
|
||||||
|
ea->attrs[1] = (eattr) {
|
||||||
|
.id = EA_MPLS_POLICY,
|
||||||
|
.type = EAF_TYPE_INT,
|
||||||
|
.u.data = MPLS_POLICY_STATIC,
|
||||||
|
};
|
||||||
|
|
||||||
|
ea->count = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ea->attrs[0] = (eattr) {
|
||||||
|
.id = EA_MPLS_POLICY,
|
||||||
|
.type = EAF_TYPE_INT,
|
||||||
|
.u.data = mc->label_policy,
|
||||||
|
};
|
||||||
|
|
||||||
|
ea->count = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Already announced */
|
/* Already announced */
|
||||||
@ -373,7 +394,7 @@ static inline int
|
|||||||
static_same_rte(struct static_route *or, struct static_route *nr)
|
static_same_rte(struct static_route *or, struct static_route *nr)
|
||||||
{
|
{
|
||||||
/* Note that i_same() requires arguments in (new, old) order */
|
/* Note that i_same() requires arguments in (new, old) order */
|
||||||
return static_same_dest(or, nr) && f_same(nr->cmds, or->cmds);
|
return (or->mpls_label == nr->mpls_label) && static_same_dest(or, nr) && f_same(nr->cmds, or->cmds);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -455,6 +476,7 @@ static_postconfig(struct proto_config *CF)
|
|||||||
cf_error("Channel not specified");
|
cf_error("Channel not specified");
|
||||||
|
|
||||||
struct channel_config *cc = proto_cf_main_channel(CF);
|
struct channel_config *cc = proto_cf_main_channel(CF);
|
||||||
|
struct channel_config *mc = proto_cf_mpls_channel(CF);
|
||||||
|
|
||||||
if (!cf->igp_table_ip4)
|
if (!cf->igp_table_ip4)
|
||||||
cf->igp_table_ip4 = (cc->table->addr_type == NET_IP4) ?
|
cf->igp_table_ip4 = (cc->table->addr_type == NET_IP4) ?
|
||||||
@ -465,9 +487,14 @@ static_postconfig(struct proto_config *CF)
|
|||||||
cc->table : cf->c.global->def_tables[NET_IP6];
|
cc->table : cf->c.global->def_tables[NET_IP6];
|
||||||
|
|
||||||
WALK_LIST(r, cf->routes)
|
WALK_LIST(r, cf->routes)
|
||||||
|
{
|
||||||
if (r->net && (r->net->type != CF->net_type))
|
if (r->net && (r->net->type != CF->net_type))
|
||||||
cf_error("Route %N incompatible with channel type", r->net);
|
cf_error("Route %N incompatible with channel type", r->net);
|
||||||
|
|
||||||
|
if ((r->mpls_label != (uint) -1) && !mc)
|
||||||
|
cf_error("Route %N has MPLS label, but MPLS channel not specified", r->net);
|
||||||
|
}
|
||||||
|
|
||||||
static_index_routes(cf);
|
static_index_routes(cf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ struct static_route {
|
|||||||
byte onlink; /* Gateway is onlink regardless of IP ranges */
|
byte onlink; /* Gateway is onlink regardless of IP ranges */
|
||||||
byte weight; /* Multipath next hop weight */
|
byte weight; /* Multipath next hop weight */
|
||||||
byte use_bfd; /* Configured to use BFD */
|
byte use_bfd; /* Configured to use BFD */
|
||||||
|
uint mpls_label; /* Local MPLS label, -1 if unused */
|
||||||
struct bfd_request *bfd_req; /* BFD request, if BFD is used */
|
struct bfd_request *bfd_req; /* BFD request, if BFD is used */
|
||||||
mpls_label_stack *mls; /* MPLS label stack; may be NULL */
|
mpls_label_stack *mls; /* MPLS label stack; may be NULL */
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user