From 08571b20598c58877e1565403d970efc2b90dba6 Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Sun, 15 Oct 2023 16:04:36 +0200 Subject: ASPA: basic data structures and Static protocol support --- proto/bgp/attrs.c | 2 +- proto/static/config.Y | 29 +++++++++++++++++++++++++++++ proto/static/static.c | 26 ++++++++++++++++++++++++++ proto/static/static.h | 5 ++++- 4 files changed, 60 insertions(+), 2 deletions(-) (limited to 'proto') diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index 85646647..5bd05fb2 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -690,7 +690,7 @@ static void bgp_format_cluster_list(const eattr *a, byte *buf, uint size) { /* Truncates cluster lists larger than buflen, probably not a problem */ - int_set_format(a->u.ptr, 0, -1, buf, size); + int_set_format(a->u.ptr, ISF_ROUTER_ID, -1, buf, size); } diff --git a/proto/static/config.Y b/proto/static/config.Y index f1825edf..58d22d3a 100644 --- a/proto/static/config.Y +++ b/proto/static/config.Y @@ -15,6 +15,7 @@ CF_DEFINES #define STATIC_CFG ((struct static_config *) this_proto) static struct static_route *this_srt, *this_snh; static struct f_inst *this_srt_cmds, *this_srt_last_cmd; +static uint this_srt_aspa_max; static struct static_route * static_nexthop_new(void) @@ -47,6 +48,7 @@ CF_DECLS CF_KEYWORDS(STATIC, ROUTE, VIA, DROP, REJECT, PROHIBIT, PREFERENCE, CHECK, LINK, DEV) CF_KEYWORDS(ONLINK, WEIGHT, RECURSIVE, IGP, TABLE, BLACKHOLE, UNREACHABLE, BFD, MPLS) +CF_KEYWORDS(TRANSIT, PROVIDERS) CF_GRAMMAR @@ -148,8 +150,35 @@ stat_route: | stat_route0 BLACKHOLE { this_srt->dest = RTD_BLACKHOLE; } | stat_route0 UNREACHABLE { this_srt->dest = RTD_UNREACHABLE; } | stat_route0 PROHIBIT { this_srt->dest = RTD_PROHIBIT; } + | stat_route0 PROVIDER { + if (this_srt->net->type != NET_ASPA) cf_error("Provider settings available only for ASPA"); + this_srt->aspa = cfg_alloc(sizeof (adata) + (this_srt_aspa_max = 8) * sizeof (u32)); + this_srt->aspa->length = 0; + } stat_aspa_providers + | stat_route0 TRANSIT { + if (this_srt->net->type != NET_ASPA) cf_error("Transit settings available only for ASPA"); + /* Allocate an explicit zero */ + this_srt->aspa = cfg_alloc(sizeof (adata) + sizeof (u32)); + this_srt->aspa->length = sizeof(u32); + ((u32 *) this_srt->aspa->data)[0] = 0; + } ; +stat_aspa_provider: NUM { + if (this_srt->aspa->length == this_srt_aspa_max * sizeof(u32)) + { + adata *new = cfg_alloc(sizeof (adata) + (this_srt_aspa_max * 2) * sizeof (u32)); + memcpy(new, this_srt->aspa, this_srt->aspa->length + sizeof(adata)); + this_srt->aspa = new; + this_srt_aspa_max *= 2; + } + + ((u32 *) this_srt->aspa->data)[this_srt->aspa->length / sizeof(u32)] = $1; + this_srt->aspa->length += sizeof(u32); +} + +stat_aspa_providers: stat_aspa_provider | stat_aspa_providers ',' stat_aspa_provider ; + stat_route_item: cmd { if (this_srt_last_cmd) diff --git a/proto/static/static.c b/proto/static/static.c index 071803a8..661d04aa 100644 --- a/proto/static/static.c +++ b/proto/static/static.c @@ -99,6 +99,32 @@ static_announce_rte(struct static_proto *p, struct static_route *r) rta_set_recursive_next_hop(p->p.main_channel->table, a, tab, r->via, IPA_NONE, r->mls); } + if (r->net->type == NET_ASPA) + { + if (r->dest != RTD_NONE) + { + log(L_WARN "%s: ASPA %u configured with nexthop, ignoring the nexthop", + p->p.name, ((struct net_addr_aspa *) r->net)->asn); + r->dest = RTD_NONE; + } + + if (!r->aspa) + { + log(L_WARN "%s: ASPA %u configured with no provider list, ignoring the whole rule", + p->p.name, ((struct net_addr_aspa *) r->net)->asn); + goto withdraw; + } + + ea_list *ea = alloca(sizeof(ea_list) + sizeof(eattr)); + *ea = (ea_list) { .flags = EALF_SORTED, .count = 1, .next = a->eattrs, }; + ea->attrs[0] = (eattr) { + .id = EA_ASPA_PROVIDERS, + .type = EAF_TYPE_INT_SET, + .u.ptr = r->aspa, + }; + a->eattrs = ea; + } + if (p->p.mpls_channel) { struct mpls_channel *mc = (void *) p->p.mpls_channel; diff --git a/proto/static/static.h b/proto/static/static.h index a0a95a4b..edd2dc22 100644 --- a/proto/static/static.h +++ b/proto/static/static.h @@ -50,7 +50,10 @@ struct static_route { 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 */ - mpls_label_stack *mls; /* MPLS label stack; may be NULL */ + union { + mpls_label_stack *mls; /* MPLS label stack; may be NULL */ + adata *aspa; /* ASPA provider list; may be NULL */ + }; }; /* -- cgit v1.2.3