diff options
author | Maria Matejka <mq@ucw.cz> | 2023-10-15 16:04:36 +0200 |
---|---|---|
committer | Maria Matejka <mq@ucw.cz> | 2024-03-25 14:15:30 +0100 |
commit | 08571b20598c58877e1565403d970efc2b90dba6 (patch) | |
tree | 0471beb4512650ff31f179ba375757f4f9400e01 /proto | |
parent | b95dc8f29f18eb177f91fdc4bf0716fac9b15366 (diff) |
ASPA: basic data structures and Static protocol support
Diffstat (limited to 'proto')
-rw-r--r-- | proto/bgp/attrs.c | 2 | ||||
-rw-r--r-- | proto/static/config.Y | 29 | ||||
-rw-r--r-- | proto/static/static.c | 26 | ||||
-rw-r--r-- | proto/static/static.h | 5 |
4 files changed, 60 insertions, 2 deletions
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 */ + }; }; /* |