mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 17:51:53 +00:00
Merge branch 'mq-aggregator-for-v3' into thread-next
This commit is contained in:
commit
e5c320d44a
@ -176,7 +176,7 @@ CF_ENUM(T_ENUM_SCOPE, SCOPE_, HOST, LINK, SITE, ORGANIZATION, UNIVERSE, UNDEFINE
|
|||||||
CF_ENUM(T_ENUM_RTD, RTD_, BLACKHOLE, UNREACHABLE, PROHIBIT)
|
CF_ENUM(T_ENUM_RTD, RTD_, BLACKHOLE, UNREACHABLE, PROHIBIT)
|
||||||
CF_ENUM(T_ENUM_ROA, ROA_, UNKNOWN, VALID, INVALID)
|
CF_ENUM(T_ENUM_ROA, ROA_, UNKNOWN, VALID, INVALID)
|
||||||
CF_ENUM_PX(T_ENUM_AF, AF_, AFI_, IPV4, IPV6)
|
CF_ENUM_PX(T_ENUM_AF, AF_, AFI_, IPV4, IPV6)
|
||||||
CF_ENUM(T_ENUM_MPLS_POLICY, MPLS_POLICY_, NONE, STATIC, PREFIX, AGGREGATE)
|
CF_ENUM(T_ENUM_MPLS_POLICY, MPLS_POLICY_, NONE, STATIC, PREFIX, AGGREGATE, VRF)
|
||||||
|
|
||||||
%type <i32> idval
|
%type <i32> idval
|
||||||
%type <f> imexport
|
%type <f> imexport
|
||||||
|
@ -20,7 +20,7 @@ static struct mpls_range_config *this_mpls_range;
|
|||||||
|
|
||||||
CF_DECLS
|
CF_DECLS
|
||||||
|
|
||||||
CF_KEYWORDS(MPLS, DOMAIN, LABEL, RANGE, STATIC, DYNAMIC, START, LENGTH, POLICY, PREFIX, AGGREGATE)
|
CF_KEYWORDS(MPLS, DOMAIN, LABEL, RANGE, STATIC, DYNAMIC, START, LENGTH, POLICY, PREFIX, AGGREGATE, VRF)
|
||||||
|
|
||||||
%type <i> mpls_label_policy
|
%type <i> mpls_label_policy
|
||||||
%type <cc> mpls_channel_start mpls_channel
|
%type <cc> mpls_channel_start mpls_channel
|
||||||
@ -112,6 +112,7 @@ mpls_label_policy:
|
|||||||
STATIC { $$ = MPLS_POLICY_STATIC; }
|
STATIC { $$ = MPLS_POLICY_STATIC; }
|
||||||
| PREFIX { $$ = MPLS_POLICY_PREFIX; }
|
| PREFIX { $$ = MPLS_POLICY_PREFIX; }
|
||||||
| AGGREGATE { $$ = MPLS_POLICY_AGGREGATE; }
|
| AGGREGATE { $$ = MPLS_POLICY_AGGREGATE; }
|
||||||
|
| VRF { $$ = MPLS_POLICY_VRF; }
|
||||||
;
|
;
|
||||||
|
|
||||||
mpls_channel_opt:
|
mpls_channel_opt:
|
||||||
|
51
nest/mpls.c
51
nest/mpls.c
@ -52,14 +52,16 @@
|
|||||||
* map, which can be used by the protocols that work with IP-prefix-based FECs.
|
* map, which can be used by the protocols that work with IP-prefix-based FECs.
|
||||||
*
|
*
|
||||||
* The FEC map keeps hash tables of FECs (struct &mpls_fec) based on network
|
* The FEC map keeps hash tables of FECs (struct &mpls_fec) based on network
|
||||||
* prefix, next hop eattr and assigned label. It has three labeling policies:
|
* prefix, next hop eattr and assigned label. It has three general labeling policies:
|
||||||
* static assignment (%MPLS_POLICY_STATIC), per-prefix policy (%MPLS_POLICY_PREFIX),
|
* static assignment (%MPLS_POLICY_STATIC), per-prefix policy (%MPLS_POLICY_PREFIX),
|
||||||
* and aggregating policy (%MPLS_POLICY_AGGREGATE). In per-prefix policy, each
|
* and aggregating policy (%MPLS_POLICY_AGGREGATE). In per-prefix policy, each
|
||||||
* distinct LSP is a separate FEC and uses a separate label, which is kept even
|
* distinct LSP is a separate FEC and uses a separate label, which is kept even
|
||||||
* if the next hop of the LSP changes. In aggregating policy, LSPs with a same
|
* if the next hop of the LSP changes. In aggregating policy, LSPs with a same
|
||||||
* next hop form one FEC and use one label, but when a next hop (or remote
|
* next hop form one FEC and use one label, but when a next hop (or remote
|
||||||
* label) of such LSP changes then the LSP must be moved to a different FEC and
|
* label) of such LSP changes then the LSP must be moved to a different FEC and
|
||||||
* assigned a different label.
|
* assigned a different label. There is also a special VRF policy (%MPLS_POLICY_VRF)
|
||||||
|
* applicable for L3VPN protocols, which uses one label for all routes from a VRF,
|
||||||
|
* while replacing the original next hop with lookup in the VRF.
|
||||||
*
|
*
|
||||||
* The overall process works this way: A protocol wants to announce a LSP route,
|
* The overall process works this way: A protocol wants to announce a LSP route,
|
||||||
* it does that by announcing e.g. IP route with %EA_MPLS_POLICY attribute.
|
* it does that by announcing e.g. IP route with %EA_MPLS_POLICY attribute.
|
||||||
@ -744,6 +746,28 @@ mpls_get_fec_by_destination(struct mpls_fec_map *m, ea_list *dest)
|
|||||||
return fec;
|
return fec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mpls_fec *
|
||||||
|
mpls_get_fec_for_vrf(struct mpls_fec_map *m)
|
||||||
|
{
|
||||||
|
struct mpls_fec *fec = m->vrf_fec;
|
||||||
|
|
||||||
|
if (fec)
|
||||||
|
return fec;
|
||||||
|
|
||||||
|
fec = sl_allocz(mpls_slab(m, 0));
|
||||||
|
|
||||||
|
fec->label = mpls_new_label(m->domain, m->handle);
|
||||||
|
fec->policy = MPLS_POLICY_VRF;
|
||||||
|
fec->iface = m->vrf_iface;
|
||||||
|
|
||||||
|
DBG("New FEC vrf %u\n", fec->label);
|
||||||
|
|
||||||
|
m->vrf_fec = fec;
|
||||||
|
HASH_INSERT2(m->label_hash, LABEL, m->pool, fec);
|
||||||
|
|
||||||
|
return fec;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
mpls_free_fec(struct mpls_fec_map *m, struct mpls_fec *fec)
|
mpls_free_fec(struct mpls_fec_map *m, struct mpls_fec *fec)
|
||||||
{
|
{
|
||||||
@ -769,6 +793,11 @@ mpls_free_fec(struct mpls_fec_map *m, struct mpls_fec *fec)
|
|||||||
HASH_REMOVE2(m->attrs_hash, RTA, m->pool, fec);
|
HASH_REMOVE2(m->attrs_hash, RTA, m->pool, fec);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MPLS_POLICY_VRF:
|
||||||
|
ASSERT(m->vrf_fec == fec);
|
||||||
|
m->vrf_fec = NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
bug("Unknown fec type");
|
bug("Unknown fec type");
|
||||||
}
|
}
|
||||||
@ -890,6 +919,17 @@ mpls_apply_fec(rte *r, struct mpls_fec *fec)
|
|||||||
{
|
{
|
||||||
ea_set_attr_u32(&r->attrs, &ea_gen_mpls_label, 0, fec->label);
|
ea_set_attr_u32(&r->attrs, &ea_gen_mpls_label, 0, fec->label);
|
||||||
ea_set_attr_u32(&r->attrs, &ea_gen_mpls_policy, 0, fec->policy);
|
ea_set_attr_u32(&r->attrs, &ea_gen_mpls_policy, 0, fec->policy);
|
||||||
|
|
||||||
|
if (fec->policy == MPLS_POLICY_VRF)
|
||||||
|
{
|
||||||
|
ea_unset_attr(&r->attrs, 0, &ea_gen_hostentry);
|
||||||
|
|
||||||
|
struct nexthop_adata nhad = {
|
||||||
|
.nh.iface = fec->iface,
|
||||||
|
.ad.length = sizeof nhad - sizeof nhad.ad,
|
||||||
|
};
|
||||||
|
ea_set_attr_data(&r->attrs, &ea_gen_nexthop, 0, nhad.ad.data, nhad.ad.length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -924,6 +964,13 @@ mpls_handle_rte(struct mpls_fec_map *m, const net_addr *n, rte *r)
|
|||||||
fec = mpls_get_fec_by_destination(m, r->attrs);
|
fec = mpls_get_fec_by_destination(m, r->attrs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MPLS_POLICY_VRF:
|
||||||
|
if (!m->vrf_iface)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fec = mpls_get_fec_for_vrf(m);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
log(L_WARN "Route %N has invalid MPLS policy %u", n, policy);
|
log(L_WARN "Route %N has invalid MPLS policy %u", n, policy);
|
||||||
return;
|
return;
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#define MPLS_POLICY_STATIC 1
|
#define MPLS_POLICY_STATIC 1
|
||||||
#define MPLS_POLICY_PREFIX 2
|
#define MPLS_POLICY_PREFIX 2
|
||||||
#define MPLS_POLICY_AGGREGATE 3
|
#define MPLS_POLICY_AGGREGATE 3
|
||||||
|
#define MPLS_POLICY_VRF 4
|
||||||
|
|
||||||
#define MPLS_FEC_DOWN 0
|
#define MPLS_FEC_DOWN 0
|
||||||
#define MPLS_FEC_CLEAN 1
|
#define MPLS_FEC_CLEAN 1
|
||||||
@ -134,6 +135,7 @@ struct mpls_fec {
|
|||||||
struct mpls_fec *next_l; /* Next in mpls_fec.label_hash */
|
struct mpls_fec *next_l; /* Next in mpls_fec.label_hash */
|
||||||
union { /* Primary key */
|
union { /* Primary key */
|
||||||
struct ea_storage *rta;
|
struct ea_storage *rta;
|
||||||
|
struct iface *iface;
|
||||||
net_addr net[0];
|
net_addr net[0];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -144,10 +146,12 @@ struct mpls_fec_map {
|
|||||||
HASH(struct mpls_fec) net_hash; /* Hash table for MPLS_POLICY_PREFIX FECs */
|
HASH(struct mpls_fec) net_hash; /* Hash table for MPLS_POLICY_PREFIX FECs */
|
||||||
HASH(struct mpls_fec) attrs_hash; /* Hash table for MPLS_POLICY_AGGREGATE FECs */
|
HASH(struct mpls_fec) attrs_hash; /* Hash table for MPLS_POLICY_AGGREGATE FECs */
|
||||||
HASH(struct mpls_fec) label_hash; /* Hash table for FEC lookup by label */
|
HASH(struct mpls_fec) label_hash; /* Hash table for FEC lookup by label */
|
||||||
|
struct mpls_fec *vrf_fec; /* Single FEC for MPLS_POLICY_VRF */
|
||||||
|
|
||||||
struct channel *channel; /* MPLS channel for FEC announcement */
|
struct channel *channel; /* MPLS channel for FEC announcement */
|
||||||
struct mpls_domain *domain; /* MPLS domain, keeping reference */
|
struct mpls_domain *domain; /* MPLS domain, keeping reference */
|
||||||
struct mpls_handle *handle; /* Handle for allocation of labels */
|
struct mpls_handle *handle; /* Handle for allocation of labels */
|
||||||
|
struct iface *vrf_iface;
|
||||||
|
|
||||||
u8 mpls_rts; /* Source value used for MPLS routes (RTS_*) */
|
u8 mpls_rts; /* Source value used for MPLS routes (RTS_*) */
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user