isisd: implement 'max-area-addresses-mismatch' notification

Note that the original IETF YANG model also included
a requirement to throttle such notifications so that they would
not be sent more often than once every 5 seconds. I did not
implement any throttling mechanism yet, mostly because I am
not sure whether this limit should apply to the entire isis daemon,
to each area, to each neighbor etc.

Signed-off-by: Emanuele Di Pascale <emanuele@voltanet.io>
This commit is contained in:
Emanuele Di Pascale 2018-11-14 15:12:15 +01:00
parent b21b068dc9
commit 2ab5a2d155
3 changed files with 41 additions and 0 deletions

View File

@ -2588,6 +2588,32 @@ void isis_notif_lsp_exceed_max(const struct isis_area *area, const char *lsp_id)
nb_notification_send(xpath, arguments);
}
/*
* XPath:
* /frr-isisd:max-area-addresses-mismatch
*/
void isis_notif_max_area_addr_mismatch(const struct isis_circuit *circuit,
uint8_t max_area_addrs,
const char *raw_pdu)
{
const char *xpath = "/frr-isisd:max-area-addresses-mismatch";
struct list *arguments = yang_data_list_new();
char xpath_arg[XPATH_MAXLEN];
struct yang_data *data;
struct isis_area *area = circuit->area;
notif_prep_instance_hdr(xpath, area, "default", arguments);
notif_prepr_iface_hdr(xpath, circuit, arguments);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/max-area-addresses", xpath);
data = yang_data_new_uint8(xpath_arg, max_area_addrs);
listnode_add(arguments, data);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
data = yang_data_new(xpath_arg, raw_pdu);
listnode_add(arguments, data);
nb_notification_send(xpath, arguments);
}
/* clang-format off */
const struct frr_yang_module_info frr_isisd_info = {
.name = "frr-isisd",

View File

@ -1423,6 +1423,12 @@ static int pdu_size(uint8_t pdu_type, uint8_t *size)
int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
{
int retval = ISIS_OK;
size_t pdu_start = stream_get_getp(circuit->rcv_stream);
size_t pdu_end = stream_get_endp(circuit->rcv_stream);
char raw_pdu[pdu_end - pdu_start];
stream_get_from(raw_pdu, circuit->rcv_stream, pdu_start,
pdu_end - pdu_start);
/* Verify that at least the 8 bytes fixed header have been received */
if (stream_get_endp(circuit->rcv_stream) < ISIS_FIXED_HDR_LEN) {
@ -1437,6 +1443,7 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
uint8_t pdu_type = stream_getc(circuit->rcv_stream)
& 0x1f; /* bits 6-8 are reserved */
uint8_t version2 = stream_getc(circuit->rcv_stream);
stream_forward_getp(circuit->rcv_stream, 1); /* reserved */
uint8_t max_area_addrs = stream_getc(circuit->rcv_stream);
@ -1509,6 +1516,11 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
"maximumAreaAddressesMismatch: maximumAreaAdresses in a received PDU %" PRIu8
" while the parameter for this IS is %u",
max_area_addrs, isis->max_area_addrs);
#ifndef FABRICD
/* send northbound notification */
isis_notif_max_area_addr_mismatch(circuit, max_area_addrs,
raw_pdu);
#endif /* ifndef FABRICD */
return ISIS_ERROR;
}

View File

@ -231,6 +231,9 @@ extern void isis_notif_corrupted_lsp(const struct isis_area *area,
const char *lsp_id); /* currently unused */
extern void isis_notif_lsp_exceed_max(const struct isis_area *area,
const char *lsp_id);
extern void
isis_notif_max_area_addr_mismatch(const struct isis_circuit *circuit,
uint8_t max_area_addrs, const char *raw_pdu);
/* Master of threads. */
extern struct thread_master *master;