ospf6d: factor out generic TLV handling

In preperation for Extended LSA types and their TLVs, factor out the TLV
handling from the Gracefull Restart functionality.

Signed-off-by: Andrew Cooks <acooks.at.bda@gmail.com>
This commit is contained in:
Andrew Cooks 2024-04-09 15:01:23 +10:00
parent 81db47a175
commit 7c9a79f182
14 changed files with 92 additions and 63 deletions

View file

@ -39,6 +39,7 @@
#include "ospf6d.h" #include "ospf6d.h"
#include "ospf6_spf.h" #include "ospf6_spf.h"
#include "ospf6_nssa.h" #include "ospf6_nssa.h"
#include "ospf6_tlv.h"
#include "ospf6_gr.h" #include "ospf6_gr.h"
#include "lib/json.h" #include "lib/json.h"

View file

@ -26,6 +26,7 @@
#include "ospf6_flood.h" #include "ospf6_flood.h"
#include "ospf6_nssa.h" #include "ospf6_nssa.h"
#include "ospf6_tlv.h"
#include "ospf6_gr.h" #include "ospf6_gr.h"
unsigned char conf_debug_ospf6_flooding; unsigned char conf_debug_ospf6_flooding;

View file

@ -30,6 +30,7 @@
#include "ospf6d/ospf6_flood.h" #include "ospf6d/ospf6_flood.h"
#include "ospf6d/ospf6_intra.h" #include "ospf6d/ospf6_intra.h"
#include "ospf6d/ospf6_spf.h" #include "ospf6d/ospf6_spf.h"
#include "ospf6d/ospf6_tlv.h"
#include "ospf6d/ospf6_gr.h" #include "ospf6d/ospf6_gr.h"
#include "ospf6d/ospf6_gr_clippy.c" #include "ospf6d/ospf6_gr_clippy.c"
@ -57,13 +58,13 @@ static int ospf6_gr_lsa_originate(struct ospf6_interface *oi,
grace_lsa = (struct ospf6_grace_lsa *)ospf6_lsa_header_end(lsa_header); grace_lsa = (struct ospf6_grace_lsa *)ospf6_lsa_header_end(lsa_header);
/* Put grace period. */ /* Put grace period. */
grace_lsa->tlv_period.header.type = htons(GRACE_PERIOD_TYPE); grace_lsa->tlv_period.header.type = htons(TLV_GRACE_PERIOD_TYPE);
grace_lsa->tlv_period.header.length = htons(GRACE_PERIOD_LENGTH); grace_lsa->tlv_period.header.length = htons(TLV_GRACE_PERIOD_LENGTH);
grace_lsa->tlv_period.interval = htonl(gr_info->grace_period); grace_lsa->tlv_period.interval = htonl(gr_info->grace_period);
/* Put restart reason. */ /* Put restart reason. */
grace_lsa->tlv_reason.header.type = htons(RESTART_REASON_TYPE); grace_lsa->tlv_reason.header.type = htons(TLV_GRACE_RESTART_REASON_TYPE);
grace_lsa->tlv_reason.header.length = htons(RESTART_REASON_LENGTH); grace_lsa->tlv_reason.header.length = htons(TLV_GRACE_RESTART_REASON_LENGTH);
grace_lsa->tlv_reason.reason = reason; grace_lsa->tlv_reason.reason = reason;
/* Fill LSA Header */ /* Fill LSA Header */

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
/* /*
* OSPF6 Graceful Retsart helper functions. * OSPF6 Graceful Restart helper functions.
* Ref RFC 5187
* *
* Copyright (C) 2021-22 Vmware, Inc. * Copyright (C) 2021-22 Vmware, Inc.
* Rajesh Kumar Girada * Rajesh Kumar Girada
@ -60,58 +61,16 @@ enum ospf6_gr_helper_rejected_reason {
OSPF6_HELPER_RESTARTING, OSPF6_HELPER_RESTARTING,
}; };
#ifdef roundup
#define ROUNDUP(val, gran) roundup(val, gran)
#else /* roundup */
#define ROUNDUP(val, gran) (((val)-1 | (gran)-1) + 1)
#endif /* roundup */
/* #define GRACE_PERIOD_TLV_SIZE sizeof(struct tlv_grace_period)
* Generic TLV (type, length, value) macros #define GRACE_RESTART_REASON_TLV_SIZE sizeof(struct tlv_grace_restart_reason)
*/
struct tlv_header {
uint16_t type; /* Type of Value */
uint16_t length; /* Length of Value portion only, in bytes */
};
#define TLV_HDR_SIZE (sizeof(struct tlv_header))
#define TLV_BODY_SIZE(tlvh) (ROUNDUP(ntohs((tlvh)->length), sizeof(uint32_t)))
#define TLV_SIZE(tlvh) (uint32_t)(TLV_HDR_SIZE + TLV_BODY_SIZE(tlvh))
#define TLV_HDR_TOP(lsah) \
(struct tlv_header *)((char *)(lsah) + OSPF6_LSA_HEADER_SIZE)
#define TLV_HDR_NEXT(tlvh) \
(struct tlv_header *)((char *)(tlvh) + TLV_SIZE(tlvh))
/* Ref RFC5187 appendix-A */
/* Grace period TLV */
#define GRACE_PERIOD_TYPE 1
#define GRACE_PERIOD_LENGTH 4
struct grace_tlv_graceperiod {
struct tlv_header header;
uint32_t interval;
};
#define GRACE_PERIOD_TLV_SIZE sizeof(struct grace_tlv_graceperiod)
/* Restart reason TLV */
#define RESTART_REASON_TYPE 2
#define RESTART_REASON_LENGTH 1
struct grace_tlv_restart_reason {
struct tlv_header header;
uint8_t reason;
uint8_t reserved[3];
};
#define GRACE_RESTART_REASON_TLV_SIZE sizeof(struct grace_tlv_restart_reason)
#define OSPF6_GRACE_LSA_MIN_SIZE \ #define OSPF6_GRACE_LSA_MIN_SIZE \
GRACE_PERIOD_TLV_SIZE + GRACE_RESTART_REASON_TLV_SIZE GRACE_PERIOD_TLV_SIZE + GRACE_RESTART_REASON_TLV_SIZE
struct ospf6_grace_lsa { struct ospf6_grace_lsa {
struct grace_tlv_graceperiod tlv_period; struct tlv_grace_period tlv_period;
struct grace_tlv_restart_reason tlv_reason; struct tlv_grace_restart_reason tlv_reason;
}; };
struct advRtr { struct advRtr {

View file

@ -32,6 +32,7 @@
#include "ospf6_neighbor.h" #include "ospf6_neighbor.h"
#include "ospf6_intra.h" #include "ospf6_intra.h"
#include "ospf6d.h" #include "ospf6d.h"
#include "ospf6_tlv.h"
#include "ospf6_gr.h" #include "ospf6_gr.h"
#include "lib/json.h" #include "lib/json.h"
#include "ospf6d/ospf6_gr_helper_clippy.c" #include "ospf6d/ospf6_gr_helper_clippy.c"
@ -129,8 +130,8 @@ static int ospf6_extract_grace_lsa_fields(struct ospf6_lsa *lsa,
{ {
struct ospf6_lsa_header *lsah = NULL; struct ospf6_lsa_header *lsah = NULL;
struct tlv_header *tlvh = NULL; struct tlv_header *tlvh = NULL;
struct grace_tlv_graceperiod *gracePeriod; struct tlv_grace_period *gracePeriod;
struct grace_tlv_restart_reason *grReason; struct tlv_grace_restart_reason *grReason;
uint16_t length = 0; uint16_t length = 0;
int sum = 0; int sum = 0;
@ -157,8 +158,8 @@ static int ospf6_extract_grace_lsa_fields(struct ospf6_lsa *lsa,
} }
switch (ntohs(tlvh->type)) { switch (ntohs(tlvh->type)) {
case GRACE_PERIOD_TYPE: case TLV_GRACE_PERIOD_TYPE:
gracePeriod = (struct grace_tlv_graceperiod *)tlvh; gracePeriod = (struct tlv_grace_period *)tlvh;
*interval = ntohl(gracePeriod->interval); *interval = ntohl(gracePeriod->interval);
sum += TLV_SIZE(tlvh); sum += TLV_SIZE(tlvh);
@ -167,8 +168,8 @@ static int ospf6_extract_grace_lsa_fields(struct ospf6_lsa *lsa,
|| *interval < OSPF6_MIN_GRACE_INTERVAL) || *interval < OSPF6_MIN_GRACE_INTERVAL)
return OSPF6_FAILURE; return OSPF6_FAILURE;
break; break;
case RESTART_REASON_TYPE: case TLV_GRACE_RESTART_REASON_TYPE:
grReason = (struct grace_tlv_restart_reason *)tlvh; grReason = (struct tlv_grace_restart_reason *)tlvh;
*reason = grReason->reason; *reason = grReason->reason;
sum += TLV_SIZE(tlvh); sum += TLV_SIZE(tlvh);
@ -1218,8 +1219,8 @@ static int ospf6_grace_lsa_show_info(struct vty *vty, struct ospf6_lsa *lsa,
{ {
struct ospf6_lsa_header *lsah = NULL; struct ospf6_lsa_header *lsah = NULL;
struct tlv_header *tlvh = NULL; struct tlv_header *tlvh = NULL;
struct grace_tlv_graceperiod *gracePeriod; struct tlv_grace_period *gracePeriod;
struct grace_tlv_restart_reason *grReason; struct tlv_grace_restart_reason *grReason;
uint16_t length = 0; uint16_t length = 0;
int sum = 0; int sum = 0;
@ -1255,8 +1256,8 @@ static int ospf6_grace_lsa_show_info(struct vty *vty, struct ospf6_lsa *lsa,
} }
switch (ntohs(tlvh->type)) { switch (ntohs(tlvh->type)) {
case GRACE_PERIOD_TYPE: case TLV_GRACE_PERIOD_TYPE:
gracePeriod = (struct grace_tlv_graceperiod *)tlvh; gracePeriod = (struct tlv_grace_period *)tlvh;
sum += TLV_SIZE(tlvh); sum += TLV_SIZE(tlvh);
if (vty) { if (vty) {
@ -1272,8 +1273,8 @@ static int ospf6_grace_lsa_show_info(struct vty *vty, struct ospf6_lsa *lsa,
ntohl(gracePeriod->interval)); ntohl(gracePeriod->interval));
} }
break; break;
case RESTART_REASON_TYPE: case TLV_GRACE_RESTART_REASON_TYPE:
grReason = (struct grace_tlv_restart_reason *)tlvh; grReason = (struct tlv_grace_restart_reason *)tlvh;
sum += TLV_SIZE(tlvh); sum += TLV_SIZE(tlvh);
if (vty) { if (vty) {
if (use_json) if (use_json)

View file

@ -30,6 +30,7 @@
#include "ospf6d.h" #include "ospf6d.h"
#include "ospf6_bfd.h" #include "ospf6_bfd.h"
#include "ospf6_zebra.h" #include "ospf6_zebra.h"
#include "ospf6_tlv.h"
#include "ospf6_gr.h" #include "ospf6_gr.h"
#include "lib/json.h" #include "lib/json.h"
#include "ospf6_proto.h" #include "ospf6_proto.h"

View file

@ -32,6 +32,7 @@
#include "ospf6_flood.h" #include "ospf6_flood.h"
#include "ospf6d.h" #include "ospf6d.h"
#include "ospf6_spf.h" #include "ospf6_spf.h"
#include "ospf6_tlv.h"
#include "ospf6_gr.h" #include "ospf6_gr.h"
unsigned char conf_debug_ospf6_brouter = 0; unsigned char conf_debug_ospf6_brouter = 0;

View file

@ -33,6 +33,7 @@
#include "ospf6_flood.h" #include "ospf6_flood.h"
#include "ospf6d.h" #include "ospf6d.h"
#include "ospf6_tlv.h"
#include "ospf6_gr.h" #include "ospf6_gr.h"
#include <netinet/ip6.h> #include <netinet/ip6.h>
#include "lib/libospf.h" #include "lib/libospf.h"

View file

@ -30,6 +30,7 @@
#include "ospf6_lsa.h" #include "ospf6_lsa.h"
#include "ospf6_spf.h" #include "ospf6_spf.h"
#include "ospf6_zebra.h" #include "ospf6_zebra.h"
#include "ospf6_tlv.h"
#include "ospf6_gr.h" #include "ospf6_gr.h"
#include "lib/json.h" #include "lib/json.h"

58
ospf6d/ospf6_tlv.h Normal file
View file

@ -0,0 +1,58 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* OSPFv3 Type Length Value.
*
*/
#ifndef OSPF6_TLV_H
#define OSPF6_TLV_H
/*
* Generic TLV (type, length, value) macros
*/
struct tlv_header {
uint16_t type; /* Type of Value */
uint16_t length; /* Length of Value portion only, in bytes */
};
#ifdef roundup
#define ROUNDUP(val, gran) roundup(val, gran)
#else /* roundup */
#define ROUNDUP(val, gran) (((val)-1 | (gran)-1) + 1)
#endif /* roundup */
#define TLV_HDR_SIZE (sizeof(struct tlv_header))
#define TLV_BODY_SIZE(tlvh) (ROUNDUP(ntohs((tlvh)->length), sizeof(uint32_t)))
#define TLV_SIZE(tlvh) ((uint32_t)(TLV_HDR_SIZE + TLV_BODY_SIZE(tlvh)))
#define TLV_HDR_TOP(lsah) \
((struct tlv_header *)((char *)(lsah) + OSPF6_LSA_HEADER_SIZE))
#define TLV_HDR_NEXT(tlvh) \
((struct tlv_header *)((char *)(tlvh) + TLV_SIZE(tlvh)))
/*
* RFC 5187 - OSPFv3 Graceful Restart - Grace-LSA
* Graceful restart predates Extended-LSA TLVs and IANA TLV register.
*/
/* Grace period TLV. */
#define TLV_GRACE_PERIOD_TYPE 1
#define TLV_GRACE_PERIOD_LENGTH 4
struct tlv_grace_period {
struct tlv_header header;
uint32_t interval;
};
/* Restart reason TLV. */
#define TLV_GRACE_RESTART_REASON_TYPE 2
#define TLV_GRACE_RESTART_REASON_LENGTH 1
struct tlv_grace_restart_reason {
struct tlv_header header;
uint8_t reason;
uint8_t reserved[3];
};
#endif /* OSPF6_TLV_H */

View file

@ -37,6 +37,7 @@
#include "ospf6_intra.h" #include "ospf6_intra.h"
#include "ospf6_spf.h" #include "ospf6_spf.h"
#include "ospf6d.h" #include "ospf6d.h"
#include "ospf6_tlv.h"
#include "ospf6_gr.h" #include "ospf6_gr.h"
#include "lib/json.h" #include "lib/json.h"
#include "ospf6_nssa.h" #include "ospf6_nssa.h"

View file

@ -27,6 +27,7 @@
#include "ospf6_zebra.h" #include "ospf6_zebra.h"
#include "ospf6d.h" #include "ospf6d.h"
#include "ospf6_area.h" #include "ospf6_area.h"
#include "ospf6_tlv.h"
#include "ospf6_gr.h" #include "ospf6_gr.h"
#include "lib/json.h" #include "lib/json.h"

View file

@ -30,6 +30,7 @@
#include "ospf6_flood.h" #include "ospf6_flood.h"
#include "ospf6d.h" #include "ospf6d.h"
#include "ospf6_bfd.h" #include "ospf6_bfd.h"
#include "ospf6_tlv.h"
#include "ospf6_gr.h" #include "ospf6_gr.h"
#include "lib/json.h" #include "lib/json.h"
#include "ospf6_nssa.h" #include "ospf6_nssa.h"

View file

@ -58,6 +58,7 @@ noinst_HEADERS += \
ospf6d/ospf6_route.h \ ospf6d/ospf6_route.h \
ospf6d/ospf6_routemap_nb.h \ ospf6d/ospf6_routemap_nb.h \
ospf6d/ospf6_spf.h \ ospf6d/ospf6_spf.h \
ospf6d/ospf6_tlv.h \
ospf6d/ospf6_top.h \ ospf6d/ospf6_top.h \
ospf6d/ospf6_zebra.h \ ospf6d/ospf6_zebra.h \
ospf6d/ospf6d.h \ ospf6d/ospf6d.h \