mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-03 07:31:54 +00:00
MPLS: FEC Map moved from protocol to MPLS channel
This commit is contained in:
parent
34d040a034
commit
e711a991d4
21
nest/mpls.c
21
nest/mpls.c
@ -565,6 +565,7 @@ mpls_channel_init(struct channel *C, struct channel_config *CC)
|
||||
c->domain = cc->domain->domain;
|
||||
c->range = cc->range->range;
|
||||
c->label_policy = cc->label_policy;
|
||||
c->rts = cc->rts;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -575,6 +576,9 @@ mpls_channel_start(struct channel *C)
|
||||
mpls_lock_domain(c->domain);
|
||||
mpls_lock_range(c->range);
|
||||
|
||||
ASSERT_DIE(c->rts);
|
||||
c->mpls_map = mpls_fec_map_new(C->proto->pool, C, c->rts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -592,6 +596,9 @@ mpls_channel_cleanup(struct channel *C)
|
||||
{
|
||||
struct mpls_channel *c = (void *) C;
|
||||
|
||||
mpls_fec_map_free(c->mpls_map);
|
||||
c->mpls_map = NULL;
|
||||
|
||||
mpls_unlock_range(c->range);
|
||||
mpls_unlock_domain(c->domain);
|
||||
}
|
||||
@ -623,6 +630,8 @@ mpls_channel_reconfigure(struct channel *C, struct channel_config *CC, int *impo
|
||||
*import_changed = 1;
|
||||
}
|
||||
|
||||
mpls_fec_map_reconfigure(c->mpls_map, C);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1141,8 +1150,10 @@ mpls_apply_fec(rte *r, struct mpls_fec *fec)
|
||||
|
||||
|
||||
int
|
||||
mpls_handle_rte(struct mpls_fec_map *m, const net_addr *n, rte *r)
|
||||
mpls_handle_rte(struct channel *c, const net_addr *n, rte *r)
|
||||
{
|
||||
struct mpls_channel *mc = SKIP_BACK(struct mpls_channel, c, c->proto->mpls_channel);
|
||||
struct mpls_fec_map *m = mc->mpls_map;
|
||||
struct mpls_fec *fec = NULL;
|
||||
|
||||
/* Select FEC for route */
|
||||
@ -1214,13 +1225,13 @@ mpls_handle_rte(struct mpls_fec_map *m, const net_addr *n, rte *r)
|
||||
static inline struct mpls_fec_tmp_lock
|
||||
mpls_rte_get_fec_lock(const rte *r)
|
||||
{
|
||||
struct mpls_fec_tmp_lock mt = {
|
||||
.m = SKIP_BACK(struct proto, sources, r->src->owner)->mpls_map,
|
||||
};
|
||||
struct mpls_fec_tmp_lock mt = {};
|
||||
|
||||
if (!mt.m)
|
||||
struct channel *c = SKIP_BACK(struct proto, sources, r->src->owner)->mpls_channel;
|
||||
if (!c)
|
||||
return mt;
|
||||
|
||||
mt.m = SKIP_BACK(struct mpls_channel, c, c)->mpls_map;
|
||||
uint label = ea_get_int(r->attrs, &ea_gen_mpls_label, 0);
|
||||
if (label < 16)
|
||||
return mt;
|
||||
|
16
nest/mpls.h
16
nest/mpls.h
@ -70,6 +70,7 @@ struct mpls_channel_config {
|
||||
struct mpls_range_config *range;
|
||||
|
||||
uint label_policy;
|
||||
uint rts;
|
||||
};
|
||||
|
||||
struct mpls_channel {
|
||||
@ -79,12 +80,25 @@ struct mpls_channel {
|
||||
struct mpls_range *range;
|
||||
|
||||
uint label_policy;
|
||||
uint rts;
|
||||
|
||||
struct mpls_fec_map *mpls_map; /* Maps protocol routes to FECs / labels */
|
||||
};
|
||||
|
||||
|
||||
void mpls_channel_postconfig(struct channel_config *CF);
|
||||
extern struct channel_class channel_mpls;
|
||||
|
||||
static inline int
|
||||
proto_configure_mpls_channel(struct proto *p, struct proto_config *pc, uint rts)
|
||||
{
|
||||
struct channel_config *cf = proto_cf_mpls_channel(pc);
|
||||
if (cf)
|
||||
SKIP_BACK(struct mpls_channel_config, c, cf)->rts = rts;
|
||||
|
||||
return proto_configure_channel(p, &p->mpls_channel, cf);
|
||||
}
|
||||
|
||||
|
||||
struct mpls_fec {
|
||||
u32 label; /* Label for FEC */
|
||||
@ -134,7 +148,7 @@ struct mpls_fec *mpls_get_fec_by_label(struct mpls_fec_map *m, u32 label);
|
||||
struct mpls_fec *mpls_get_fec_by_net(struct mpls_fec_map *m, const net_addr *net, u32 path_id);
|
||||
struct mpls_fec *mpls_get_fec_by_destination(struct mpls_fec_map *m, ea_list *dest);
|
||||
void mpls_free_fec(struct mpls_fec_map *x, struct mpls_fec *fec);
|
||||
int mpls_handle_rte(struct mpls_fec_map *m, const net_addr *n, rte *r);
|
||||
int mpls_handle_rte(struct channel *c, const net_addr *n, rte *r);
|
||||
void mpls_rte_preimport(rte *new, const rte *old);
|
||||
|
||||
|
||||
|
64
nest/proto.c
64
nest/proto.c
@ -1512,70 +1512,6 @@ proto_configure_channel(struct proto *p, struct channel **pc, struct channel_con
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* proto_setup_mpls_map - automatically setup FEC map for protocol
|
||||
* @p: affected protocol
|
||||
* @rts: RTS_* value for generated MPLS routes
|
||||
* @hooks: whether to update rte_insert / rte_remove hooks
|
||||
*
|
||||
* Add, remove or reconfigure MPLS FEC map of the protocol @p, depends on
|
||||
* whether MPLS channel exists, and setup rte_insert / rte_remove hooks with
|
||||
* default MPLS handlers. It is a convenience function supposed to be called
|
||||
* from the protocol start and configure hooks, after reconfiguration of
|
||||
* channels. For shutdown, use proto_shutdown_mpls_map(). If caller uses its own
|
||||
* rte_insert / rte_remove hooks, it is possible to disable updating hooks and
|
||||
* doing that manually.
|
||||
*/
|
||||
void
|
||||
proto_setup_mpls_map(struct proto *p, uint rts)
|
||||
{
|
||||
struct mpls_fec_map *m = p->mpls_map;
|
||||
struct channel *c = p->mpls_channel;
|
||||
|
||||
if (!m && c)
|
||||
{
|
||||
/*
|
||||
* Note that when called from a protocol start hook, it is called before
|
||||
* mpls_channel_start(). But FEC map locks MPLS domain internally so it does
|
||||
* not depend on lock from MPLS channel.
|
||||
*/
|
||||
p->mpls_map = mpls_fec_map_new(p->pool, c, rts);
|
||||
}
|
||||
else if (m && !c)
|
||||
{
|
||||
/*
|
||||
* Note that for reconfiguration, it is called after the MPLS channel has
|
||||
* been already removed. But removal of active MPLS channel would trigger
|
||||
* protocol restart anyways.
|
||||
*/
|
||||
mpls_fec_map_free(m);
|
||||
p->mpls_map = NULL;
|
||||
}
|
||||
else if (m && c)
|
||||
{
|
||||
mpls_fec_map_reconfigure(m, c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* proto_shutdown_mpls_map - automatically shutdown FEC map for protocol
|
||||
* @p: affected protocol
|
||||
* @hooks: whether to update rte_insert / rte_remove hooks
|
||||
*
|
||||
* Remove MPLS FEC map of the protocol @p during protocol shutdown.
|
||||
*/
|
||||
void
|
||||
proto_shutdown_mpls_map(struct proto *p)
|
||||
{
|
||||
struct mpls_fec_map *m = p->mpls_map;
|
||||
|
||||
if (!m)
|
||||
return;
|
||||
|
||||
mpls_fec_map_free(m);
|
||||
p->mpls_map = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
proto_cleanup(struct proto *p)
|
||||
|
@ -34,7 +34,6 @@ struct channel;
|
||||
struct ea_list;
|
||||
struct eattr;
|
||||
struct symbol;
|
||||
struct mpls_fec_map;
|
||||
|
||||
|
||||
/*
|
||||
@ -160,7 +159,6 @@ struct proto {
|
||||
TLIST_LIST(proto_neigh) neighbors; /* List of neighbor structures */
|
||||
struct iface_subscription iface_sub; /* Interface notification subscription */
|
||||
struct channel *mpls_channel; /* MPLS channel, when used */
|
||||
struct mpls_fec_map *mpls_map; /* Maps protocol routes to FECs / labels */
|
||||
|
||||
const char *name; /* Name of this instance (== cf->name) */
|
||||
u32 debug; /* Debugging flags */
|
||||
@ -687,8 +685,6 @@ struct channel *proto_find_channel_by_name(struct proto *p, const char *n);
|
||||
struct channel *proto_add_channel(struct proto *p, struct channel_config *cf);
|
||||
void proto_remove_channel(struct proto *p, struct channel *c);
|
||||
int proto_configure_channel(struct proto *p, struct channel **c, struct channel_config *cf);
|
||||
void proto_setup_mpls_map(struct proto *p, uint rts);
|
||||
void proto_shutdown_mpls_map(struct proto *p);
|
||||
|
||||
void channel_set_state(struct channel *c, uint state);
|
||||
void channel_schedule_reload(struct channel *c, struct channel_import_request *cir);
|
||||
|
@ -1789,8 +1789,8 @@ rte_update(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
|
||||
new = NULL;
|
||||
}
|
||||
|
||||
if (new && c->proto->mpls_map)
|
||||
if (mpls_handle_rte(c->proto->mpls_map, n, new) < 0)
|
||||
if (new && c->proto->mpls_channel)
|
||||
if (mpls_handle_rte(c->proto->mpls_channel, n, new) < 0)
|
||||
{
|
||||
channel_rte_trace_in(D_FILTERS, c, new, "invalid");
|
||||
stats->updates_invalid++;
|
||||
|
@ -116,6 +116,7 @@
|
||||
#include "nest/iface.h"
|
||||
#include "nest/protocol.h"
|
||||
#include "nest/route.h"
|
||||
#include "nest/mpls.h"
|
||||
#include "nest/cli.h"
|
||||
#include "nest/locks.h"
|
||||
#include "conf/conf.h"
|
||||
@ -621,8 +622,6 @@ bgp_spawn(struct bgp_proto *pp, ip_addr remote_ip)
|
||||
void
|
||||
bgp_stop(struct bgp_proto *p, int subcode, byte *data, uint len)
|
||||
{
|
||||
proto_shutdown_mpls_map(&p->p);
|
||||
|
||||
proto_notify_state(&p->p, PS_STOP);
|
||||
p->uncork_ev->data = NULL;
|
||||
bgp_graceful_close_conn(&p->outgoing_conn, subcode, data, len);
|
||||
@ -1794,8 +1793,6 @@ bgp_start(struct proto *P)
|
||||
p->remote_id = 0;
|
||||
p->link_addr = IPA_NONE;
|
||||
|
||||
proto_setup_mpls_map(P, RTS_BGP);
|
||||
|
||||
/* Lock all channels when in GR recovery mode */
|
||||
if (p->p.gr_recovery && p->cf->gr_mode)
|
||||
{
|
||||
@ -1966,7 +1963,7 @@ bgp_init(struct proto_config *CF)
|
||||
proto_add_channel(P, &cc->c);
|
||||
|
||||
/* Add MPLS channel */
|
||||
proto_configure_channel(P, &P->mpls_channel, proto_cf_mpls_channel(CF));
|
||||
proto_configure_mpls_channel(P, CF, RTS_BGP);
|
||||
|
||||
return P;
|
||||
}
|
||||
@ -2392,15 +2389,12 @@ bgp_reconfigure(struct proto *P, struct proto_config *CF)
|
||||
}
|
||||
|
||||
/* Reconfigure MPLS channel */
|
||||
same = proto_configure_channel(P, &P->mpls_channel, proto_cf_mpls_channel(CF)) && same;
|
||||
same = proto_configure_mpls_channel(P, CF, RTS_BGP) && same;
|
||||
|
||||
WALK_LIST_DELSAFE(C, C2, p->p.channels)
|
||||
if (C->stale)
|
||||
same = proto_configure_channel(P, &C, NULL) && same;
|
||||
|
||||
if (same)
|
||||
proto_setup_mpls_map(P, RTS_BGP);
|
||||
|
||||
if (same && (p->start_state > BSS_PREPARE))
|
||||
bgp_update_bfd(p, new->bfd);
|
||||
|
||||
|
@ -391,7 +391,8 @@ l3vpn_init(struct proto_config *CF)
|
||||
proto_configure_channel(P, &p->ip6_channel, proto_cf_find_channel(CF, NET_IP6));
|
||||
proto_configure_channel(P, &p->vpn4_channel, proto_cf_find_channel(CF, NET_VPN4));
|
||||
proto_configure_channel(P, &p->vpn6_channel, proto_cf_find_channel(CF, NET_VPN6));
|
||||
proto_configure_channel(P, &P->mpls_channel, proto_cf_find_channel(CF, NET_MPLS));
|
||||
|
||||
proto_configure_mpls_channel(P, CF, RTS_L3VPN);
|
||||
|
||||
P->rt_notify = l3vpn_rt_notify;
|
||||
P->preexport = l3vpn_preexport;
|
||||
@ -414,22 +415,20 @@ l3vpn_start(struct proto *P)
|
||||
l3vpn_prepare_import_targets(p);
|
||||
l3vpn_prepare_export_targets(p);
|
||||
|
||||
proto_setup_mpls_map(P, RTS_L3VPN);
|
||||
|
||||
P->mpls_map->vrf_iface = P->vrf;
|
||||
SKIP_BACK(struct mpls_channel, c, P->mpls_channel)->mpls_map->vrf_iface = P->vrf;
|
||||
|
||||
return PS_UP;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int
|
||||
l3vpn_shutdown(struct proto *P)
|
||||
l3vpn_shutdown(struct proto *P UNUSED)
|
||||
{
|
||||
// struct l3vpn_proto *p = (void *) P;
|
||||
|
||||
proto_shutdown_mpls_map(P);
|
||||
|
||||
return PS_DOWN;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
l3vpn_reconfigure(struct proto *P, struct proto_config *CF)
|
||||
@ -441,7 +440,7 @@ l3vpn_reconfigure(struct proto *P, struct proto_config *CF)
|
||||
!proto_configure_channel(P, &p->ip6_channel, proto_cf_find_channel(CF, NET_IP6)) ||
|
||||
!proto_configure_channel(P, &p->vpn4_channel, proto_cf_find_channel(CF, NET_VPN4)) ||
|
||||
!proto_configure_channel(P, &p->vpn6_channel, proto_cf_find_channel(CF, NET_VPN6)) ||
|
||||
!proto_configure_channel(P, &P->mpls_channel, proto_cf_find_channel(CF, NET_MPLS)))
|
||||
!proto_configure_mpls_channel(P, CF, RTS_L3VPN))
|
||||
return 0;
|
||||
|
||||
if (p->rd != cf->rd)
|
||||
@ -454,8 +453,6 @@ l3vpn_reconfigure(struct proto *P, struct proto_config *CF)
|
||||
p->import_target = cf->import_target;
|
||||
p->export_target = cf->export_target;
|
||||
|
||||
proto_setup_mpls_map(P, RTS_L3VPN);
|
||||
|
||||
if (import_changed)
|
||||
{
|
||||
TRACE(D_EVENTS, "Import target changed");
|
||||
@ -518,7 +515,7 @@ struct protocol proto_l3vpn = {
|
||||
.postconfig = l3vpn_postconfig,
|
||||
.init = l3vpn_init,
|
||||
.start = l3vpn_start,
|
||||
.shutdown = l3vpn_shutdown,
|
||||
// .shutdown = l3vpn_shutdown,
|
||||
.reconfigure = l3vpn_reconfigure,
|
||||
.copy_config = l3vpn_copy_config,
|
||||
};
|
||||
|
@ -507,7 +507,7 @@ static_init(struct proto_config *CF)
|
||||
|
||||
P->main_channel = proto_add_channel(P, proto_cf_main_channel(CF));
|
||||
|
||||
proto_configure_channel(P, &P->mpls_channel, proto_cf_mpls_channel(CF));
|
||||
proto_configure_mpls_channel(P, CF, RTS_STATIC);
|
||||
|
||||
P->iface_sub.neigh_notify = static_neigh_notify;
|
||||
P->reload_routes = static_reload_routes;
|
||||
@ -539,8 +539,6 @@ static_start(struct proto *P)
|
||||
|
||||
BUFFER_INIT(p->marked, p->p.pool, 4);
|
||||
|
||||
proto_setup_mpls_map(P, RTS_STATIC);
|
||||
|
||||
/* We have to go UP before routes could be installed */
|
||||
proto_notify_state(P, PS_UP);
|
||||
|
||||
@ -558,8 +556,6 @@ static_shutdown(struct proto *P)
|
||||
struct static_config *cf = (void *) P->cf;
|
||||
struct static_route *r;
|
||||
|
||||
proto_shutdown_mpls_map(P);
|
||||
|
||||
/* Just reset the flag, the routes will be flushed by the nest */
|
||||
WALK_LIST(r, cf->routes)
|
||||
static_reset_rte(p, r);
|
||||
@ -657,11 +653,9 @@ static_reconfigure(struct proto *P, struct proto_config *CF)
|
||||
return 0;
|
||||
|
||||
if (!proto_configure_channel(P, &P->main_channel, proto_cf_main_channel(CF)) ||
|
||||
!proto_configure_channel(P, &P->mpls_channel, proto_cf_mpls_channel(CF)))
|
||||
!proto_configure_mpls_channel(P, CF, RTS_STATIC))
|
||||
return 0;
|
||||
|
||||
proto_setup_mpls_map(P, RTS_STATIC);
|
||||
|
||||
p->p.cf = CF;
|
||||
|
||||
/* Reset route lists in neighbor entries */
|
||||
|
Loading…
Reference in New Issue
Block a user