mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-08 12:18:42 +00:00
aspa pdu - work in progress
This commit is contained in:
parent
889943b8f7
commit
e421d37490
@ -375,6 +375,7 @@ channel_roa_subscribe(struct channel *c, rtable *tab, int dir)
|
|||||||
add_tail(&c->roa_subscriptions, &s->roa_node);
|
add_tail(&c->roa_subscriptions, &s->roa_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
channel_roa_unsubscribe(struct roa_subscription *s)
|
channel_roa_unsubscribe(struct roa_subscription *s)
|
||||||
{
|
{
|
||||||
@ -422,6 +423,11 @@ channel_roa_subscribe_filter(struct channel *c, int dir)
|
|||||||
found = 1;
|
found = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FI_ASPA_CHECK_EXPLICIT:
|
||||||
|
tab = fi->i_FI_ASPA_CHECK_EXPLICIT.rtc->table;
|
||||||
|
if (valid) channel_roa_subscribe(c, tab, dir);
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,7 @@ enum pdu_type {
|
|||||||
CACHE_RESET = 8,
|
CACHE_RESET = 8,
|
||||||
ROUTER_KEY = 9,
|
ROUTER_KEY = 9,
|
||||||
ERROR = 10,
|
ERROR = 10,
|
||||||
|
ASPA = 11,
|
||||||
PDU_TYPE_MAX
|
PDU_TYPE_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -76,7 +77,8 @@ static const char *str_pdu_type_[] = {
|
|||||||
[END_OF_DATA] = "End of Data",
|
[END_OF_DATA] = "End of Data",
|
||||||
[CACHE_RESET] = "Cache Reset",
|
[CACHE_RESET] = "Cache Reset",
|
||||||
[ROUTER_KEY] = "Router Key",
|
[ROUTER_KEY] = "Router Key",
|
||||||
[ERROR] = "Error"
|
[ERROR] = "Error",
|
||||||
|
[ASPA] = "ASPA"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *str_pdu_type(uint type) {
|
static const char *str_pdu_type(uint type) {
|
||||||
@ -193,6 +195,41 @@ struct pdu_error {
|
|||||||
* Error Diagnostic Message */
|
* Error Diagnostic Message */
|
||||||
} PACKED;
|
} PACKED;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 0 8 16 24 31
|
||||||
|
* .-------------------------------------------.
|
||||||
|
* | Protocol | PDU | |
|
||||||
|
* | Version | Type | zero |
|
||||||
|
* | 2 | 11 | |
|
||||||
|
* +-------------------------------------------+
|
||||||
|
* | |
|
||||||
|
* | Length |
|
||||||
|
* | |
|
||||||
|
* +-------------------------------------------+
|
||||||
|
* | | | |
|
||||||
|
* | Flags | AFI Flags| Provider AS Count |
|
||||||
|
* | | | |
|
||||||
|
* +-------------------------------------------+
|
||||||
|
* | |
|
||||||
|
* | Customer Autonomous System Number |
|
||||||
|
* | |
|
||||||
|
* +-------------------------------------------+
|
||||||
|
* | |
|
||||||
|
* ~ Provider Autonomous System Numbers ~
|
||||||
|
* | |
|
||||||
|
* ~-------------------------------------------~ */
|
||||||
|
struct pdu_aspa {
|
||||||
|
u8 ver;
|
||||||
|
u8 type;
|
||||||
|
u16 zero;
|
||||||
|
u32 len;
|
||||||
|
u8 flags;
|
||||||
|
u8 afi_flags; /* must be 11000000 in version 2 */
|
||||||
|
u16 provider_as_count;
|
||||||
|
u32 customer_as_num;
|
||||||
|
u32 provider_as_nums[0];
|
||||||
|
} PACKED;
|
||||||
|
|
||||||
struct pdu_reset_query {
|
struct pdu_reset_query {
|
||||||
u8 ver;
|
u8 ver;
|
||||||
u8 type;
|
u8 type;
|
||||||
@ -230,6 +267,7 @@ static const size_t min_pdu_size[] = {
|
|||||||
[END_OF_DATA] = sizeof(struct pdu_end_of_data_v0),
|
[END_OF_DATA] = sizeof(struct pdu_end_of_data_v0),
|
||||||
[CACHE_RESET] = sizeof(struct pdu_cache_response),
|
[CACHE_RESET] = sizeof(struct pdu_cache_response),
|
||||||
[ROUTER_KEY] = sizeof(struct pdu_header), /* FIXME */
|
[ROUTER_KEY] = sizeof(struct pdu_header), /* FIXME */
|
||||||
|
[ASPA] = sizeof(struct pdu_aspa),
|
||||||
[ERROR] = 16,
|
[ERROR] = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -293,7 +331,7 @@ rpki_pdu_to_host_byte_order(struct pdu_header *pdu)
|
|||||||
struct pdu_end_of_data_v0 *eod0 = (void *) pdu;
|
struct pdu_end_of_data_v0 *eod0 = (void *) pdu;
|
||||||
eod0->serial_num = ntohl(eod0->serial_num); /* Same either for version 1 */
|
eod0->serial_num = ntohl(eod0->serial_num); /* Same either for version 1 */
|
||||||
|
|
||||||
if (pdu->ver == RPKI_VERSION_1)
|
if (pdu->ver != RPKI_VERSION_0) //TODO version
|
||||||
{
|
{
|
||||||
struct pdu_end_of_data_v1 *eod1 = (void *) pdu;
|
struct pdu_end_of_data_v1 *eod1 = (void *) pdu;
|
||||||
eod1->expire_interval = ntohl(eod1->expire_interval);
|
eod1->expire_interval = ntohl(eod1->expire_interval);
|
||||||
@ -329,6 +367,21 @@ rpki_pdu_to_host_byte_order(struct pdu_header *pdu)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ASPA:
|
||||||
|
{
|
||||||
|
struct pdu_aspa *aspa = (void *) pdu;
|
||||||
|
aspa->customer_as_num = ntohl(aspa->customer_as_num);
|
||||||
|
|
||||||
|
aspa->provider_as_count = ntohl(aspa->provider_as_count);
|
||||||
|
/* Count provider_as_num_count from length and compare */
|
||||||
|
int provider_num_counted = (aspa->len - sizeof(struct pdu_aspa)) / (sizeof(u32));
|
||||||
|
|
||||||
|
for (int i = 0; i < provider_num_counted ; i++)
|
||||||
|
{
|
||||||
|
aspa->provider_as_nums[i] = ntohl(aspa->provider_as_nums[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case ROUTER_KEY:
|
case ROUTER_KEY:
|
||||||
/* Router Key PDU is not supported yet */
|
/* Router Key PDU is not supported yet */
|
||||||
|
|
||||||
@ -364,7 +417,7 @@ rpki_log_packet(struct rpki_cache *cache, const struct pdu_header *pdu, const en
|
|||||||
{
|
{
|
||||||
if (!(cache->p->p.debug & D_PACKETS))
|
if (!(cache->p->p.debug & D_PACKETS))
|
||||||
return;
|
return;
|
||||||
|
log("packet arrived, version %i", pdu->ver);
|
||||||
const char *str_type = str_pdu_type(pdu->type);
|
const char *str_type = str_pdu_type(pdu->type);
|
||||||
char detail[256];
|
char detail[256];
|
||||||
|
|
||||||
@ -387,7 +440,7 @@ rpki_log_packet(struct rpki_cache *cache, const struct pdu_header *pdu, const en
|
|||||||
case END_OF_DATA:
|
case END_OF_DATA:
|
||||||
{
|
{
|
||||||
const struct pdu_end_of_data_v1 *eod = (void *) pdu;
|
const struct pdu_end_of_data_v1 *eod = (void *) pdu;
|
||||||
if (eod->ver == RPKI_VERSION_1)
|
if (eod->ver != RPKI_VERSION_0) //TODO versions
|
||||||
SAVE(bsnprintf(detail, sizeof(detail), "(session id: %u, serial number: %u, refresh: %us, retry: %us, expire: %us)", eod->session_id, eod->serial_num, eod->refresh_interval, eod->retry_interval, eod->expire_interval));
|
SAVE(bsnprintf(detail, sizeof(detail), "(session id: %u, serial number: %u, refresh: %us, retry: %us, expire: %us)", eod->session_id, eod->serial_num, eod->refresh_interval, eod->retry_interval, eod->expire_interval));
|
||||||
else
|
else
|
||||||
SAVE(bsnprintf(detail, sizeof(detail), "(session id: %u, serial number: %u)", eod->session_id, eod->serial_num));
|
SAVE(bsnprintf(detail, sizeof(detail), "(session id: %u, serial number: %u)", eod->session_id, eod->serial_num));
|
||||||
@ -729,8 +782,8 @@ rpki_prefix_pdu_2_net_addr(const struct pdu_header *pdu, net_addr_union *n)
|
|||||||
static int
|
static int
|
||||||
rpki_handle_prefix_pdu(struct rpki_cache *cache, const struct pdu_header *pdu)
|
rpki_handle_prefix_pdu(struct rpki_cache *cache, const struct pdu_header *pdu)
|
||||||
{
|
{
|
||||||
|
log("prefix pdu");
|
||||||
const struct rpki_config *cf = (void *) cache->p->p.cf;
|
const struct rpki_config *cf = (void *) cache->p->p.cf;
|
||||||
|
|
||||||
const enum pdu_type type = pdu->type;
|
const enum pdu_type type = pdu->type;
|
||||||
ASSERT(type == IPV4_PREFIX || type == IPV6_PREFIX);
|
ASSERT(type == IPV4_PREFIX || type == IPV6_PREFIX);
|
||||||
|
|
||||||
@ -797,6 +850,32 @@ rpki_handle_prefix_pdu(struct rpki_cache *cache, const struct pdu_header *pdu)
|
|||||||
return RPKI_SUCCESS;
|
return RPKI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rpki_handle_aspa_pdu(struct rpki_cache *cache, const struct pdu_header *pdu)
|
||||||
|
{
|
||||||
|
struct pdu_aspa *aspa = (void *) pdu;
|
||||||
|
struct channel *channel = cache->p->aspa_channel;
|
||||||
|
|
||||||
|
if (!channel)
|
||||||
|
{
|
||||||
|
CACHE_TRACE(D_ROUTES, cache, "Skip %i, missing %s channel", aspa->customer_as_num, "aspa");
|
||||||
|
return RPKI_ERROR;
|
||||||
|
}
|
||||||
|
cache->last_rx_prefix = current_time();
|
||||||
|
|
||||||
|
u32 customer_as_num = aspa->customer_as_num;
|
||||||
|
|
||||||
|
/* We reuse pdu memory instead of memcopy all providers numbers to new adata struct.
|
||||||
|
* We can do that, because aspa pdu will not be used anymore and the data will be memcopied in next functions anyway.
|
||||||
|
*/
|
||||||
|
struct adata *providers = SKIP_BACK(adata, data, &aspa->provider_as_nums);
|
||||||
|
providers->length = aspa->len - sizeof(struct pdu_aspa);
|
||||||
|
|
||||||
|
rpki_table_add_aspa(cache, channel, customer_as_num, providers);
|
||||||
|
|
||||||
|
return RPKI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static uint
|
static uint
|
||||||
rpki_check_interval(struct rpki_cache *cache, const char *(check_fn)(uint), uint interval)
|
rpki_check_interval(struct rpki_cache *cache, const char *(check_fn)(uint), uint interval)
|
||||||
{
|
{
|
||||||
@ -822,7 +901,7 @@ rpki_handle_end_of_data_pdu(struct rpki_cache *cache, const struct pdu_end_of_da
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pdu->ver == RPKI_VERSION_1)
|
if (pdu->ver != RPKI_VERSION_0) //TODO versions
|
||||||
{
|
{
|
||||||
if (!cf->keep_refresh_interval && rpki_check_interval(cache, rpki_check_refresh_interval, pdu->refresh_interval))
|
if (!cf->keep_refresh_interval && rpki_check_interval(cache, rpki_check_refresh_interval, pdu->refresh_interval))
|
||||||
cache->refresh_interval = pdu->refresh_interval;
|
cache->refresh_interval = pdu->refresh_interval;
|
||||||
@ -849,6 +928,8 @@ rpki_handle_end_of_data_pdu(struct rpki_cache *cache, const struct pdu_end_of_da
|
|||||||
rt_refresh_end(cache->p->roa4_channel->table, cache->p->roa4_channel);
|
rt_refresh_end(cache->p->roa4_channel->table, cache->p->roa4_channel);
|
||||||
if (cache->p->roa6_channel)
|
if (cache->p->roa6_channel)
|
||||||
rt_refresh_end(cache->p->roa6_channel->table, cache->p->roa6_channel);
|
rt_refresh_end(cache->p->roa6_channel->table, cache->p->roa6_channel);
|
||||||
|
if (cache->p->aspa_channel)
|
||||||
|
rt_refresh_end(cache->p->aspa_channel->table, cache->p->aspa_channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
cache->last_update = current_time();
|
cache->last_update = current_time();
|
||||||
@ -913,6 +994,10 @@ rpki_rx_packet(struct rpki_cache *cache, struct pdu_header *pdu)
|
|||||||
/* TODO: Implement Router Key PDU handling */
|
/* TODO: Implement Router Key PDU handling */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ASPA:
|
||||||
|
rpki_handle_aspa_pdu(cache, (void *) pdu);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
CACHE_TRACE(D_PACKETS, cache, "Received unsupported type (%u)", pdu->type);
|
CACHE_TRACE(D_PACKETS, cache, "Received unsupported type (%u)", pdu->type);
|
||||||
};
|
};
|
||||||
|
@ -140,6 +140,36 @@ rpki_table_remove_roa(struct rpki_cache *cache, struct channel *channel, const n
|
|||||||
rte_update2(channel, &pfxr->n, NULL, p->p.main_source);
|
rte_update2(channel, &pfxr->n, NULL, p->p.main_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rpki_table_add_aspa(struct rpki_cache *cache, struct channel *channel,
|
||||||
|
u32 customer, adata *providers)
|
||||||
|
{
|
||||||
|
struct rpki_proto *p = cache->p;
|
||||||
|
|
||||||
|
net_addr_union n = { .aspa = NET_ADDR_ASPA(customer) };
|
||||||
|
|
||||||
|
ea_list *ea = alloca(sizeof(ea_list) + sizeof(eattr));
|
||||||
|
*ea = (ea_list) { .flags = EALF_SORTED, .count = 1, };
|
||||||
|
ea->attrs[0] = (eattr) {
|
||||||
|
.id = EA_ASPA_PROVIDERS,
|
||||||
|
.type = EAF_TYPE_INT_SET,
|
||||||
|
.u.ptr = providers,
|
||||||
|
};
|
||||||
|
|
||||||
|
rta a0 = {
|
||||||
|
.pref = channel->preference,
|
||||||
|
.source = RTS_RPKI,
|
||||||
|
.scope = SCOPE_UNIVERSE,
|
||||||
|
.dest = RTD_NONE,
|
||||||
|
.eattrs = ea,
|
||||||
|
};
|
||||||
|
|
||||||
|
rta *a = rta_lookup(&a0);
|
||||||
|
rte *e = rte_get_temp(a, p->p.main_source);
|
||||||
|
|
||||||
|
rte_update2(channel, &n.n, e, e->src);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RPKI Protocol Logic
|
* RPKI Protocol Logic
|
||||||
@ -755,7 +785,8 @@ rpki_reconfigure(struct proto *P, struct proto_config *CF)
|
|||||||
struct rpki_cache *cache = p->cache;
|
struct rpki_cache *cache = p->cache;
|
||||||
|
|
||||||
if (!proto_configure_channel(&p->p, &p->roa4_channel, proto_cf_find_channel(CF, NET_ROA4)) ||
|
if (!proto_configure_channel(&p->p, &p->roa4_channel, proto_cf_find_channel(CF, NET_ROA4)) ||
|
||||||
!proto_configure_channel(&p->p, &p->roa6_channel, proto_cf_find_channel(CF, NET_ROA6)))
|
!proto_configure_channel(&p->p, &p->roa6_channel, proto_cf_find_channel(CF, NET_ROA6)) ||
|
||||||
|
!proto_configure_channel(&p->p, &p->aspa_channel, proto_cf_find_channel(CF, NET_ASPA)))
|
||||||
return NEED_RESTART;
|
return NEED_RESTART;
|
||||||
|
|
||||||
if (rpki_reconfigure_cache(p, cache, new, old) != SUCCESSFUL_RECONF)
|
if (rpki_reconfigure_cache(p, cache, new, old) != SUCCESSFUL_RECONF)
|
||||||
@ -777,6 +808,7 @@ rpki_init(struct proto_config *CF)
|
|||||||
|
|
||||||
proto_configure_channel(&p->p, &p->roa4_channel, proto_cf_find_channel(CF, NET_ROA4));
|
proto_configure_channel(&p->p, &p->roa4_channel, proto_cf_find_channel(CF, NET_ROA4));
|
||||||
proto_configure_channel(&p->p, &p->roa6_channel, proto_cf_find_channel(CF, NET_ROA6));
|
proto_configure_channel(&p->p, &p->roa6_channel, proto_cf_find_channel(CF, NET_ROA6));
|
||||||
|
proto_configure_channel(&p->p, &p->aspa_channel, proto_cf_find_channel(CF, NET_ASPA));
|
||||||
|
|
||||||
return P;
|
return P;
|
||||||
}
|
}
|
||||||
@ -886,6 +918,11 @@ rpki_show_proto_info(struct proto *P)
|
|||||||
channel_show_info(p->roa6_channel);
|
channel_show_info(p->roa6_channel);
|
||||||
else
|
else
|
||||||
cli_msg(-1006, " No roa6 channel");
|
cli_msg(-1006, " No roa6 channel");
|
||||||
|
|
||||||
|
if (p->aspa_channel)
|
||||||
|
channel_show_info(p->aspa_channel);
|
||||||
|
else
|
||||||
|
cli_msg(-1006, " No aspa channel");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -957,7 +994,7 @@ struct protocol proto_rpki = {
|
|||||||
.init = rpki_init,
|
.init = rpki_init,
|
||||||
.start = rpki_start,
|
.start = rpki_start,
|
||||||
.postconfig = rpki_postconfig,
|
.postconfig = rpki_postconfig,
|
||||||
.channel_mask = (NB_ROA4 | NB_ROA6),
|
.channel_mask = (NB_ROA4 | NB_ROA6 | NB_ASPA),
|
||||||
.show_proto_info = rpki_show_proto_info,
|
.show_proto_info = rpki_show_proto_info,
|
||||||
.shutdown = rpki_shutdown,
|
.shutdown = rpki_shutdown,
|
||||||
.copy_config = rpki_copy_config,
|
.copy_config = rpki_copy_config,
|
||||||
|
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
#define RPKI_VERSION_0 0
|
#define RPKI_VERSION_0 0
|
||||||
#define RPKI_VERSION_1 1
|
#define RPKI_VERSION_1 1
|
||||||
#define RPKI_MAX_VERSION RPKI_VERSION_1
|
#define RPKI_VERSION_2 2
|
||||||
|
#define RPKI_MAX_VERSION RPKI_VERSION_2
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -83,6 +84,8 @@ const char *rpki_cache_state_to_str(enum rpki_cache_state state);
|
|||||||
void rpki_table_add_roa(struct rpki_cache *cache, struct channel *channel, const net_addr_union *pfxr);
|
void rpki_table_add_roa(struct rpki_cache *cache, struct channel *channel, const net_addr_union *pfxr);
|
||||||
void rpki_table_remove_roa(struct rpki_cache *cache, struct channel *channel, const net_addr_union *pfxr);
|
void rpki_table_remove_roa(struct rpki_cache *cache, struct channel *channel, const net_addr_union *pfxr);
|
||||||
|
|
||||||
|
void rpki_table_add_aspa(struct rpki_cache *cache, struct channel *channel, u32 customer, adata *providers);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RPKI Protocol Logic
|
* RPKI Protocol Logic
|
||||||
@ -110,6 +113,7 @@ struct rpki_proto {
|
|||||||
|
|
||||||
struct channel *roa4_channel;
|
struct channel *roa4_channel;
|
||||||
struct channel *roa6_channel;
|
struct channel *roa6_channel;
|
||||||
|
struct channel *aspa_channel;
|
||||||
u8 refresh_channels; /* For non-incremental updates using rt_refresh_begin(), rt_refresh_end() */
|
u8 refresh_channels; /* For non-incremental updates using rt_refresh_begin(), rt_refresh_end() */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user