Skip to content

Commit db6e2a0

Browse files
nikhilgAristafenner
authored andcommitted
OSPF: print the Extended Link Opaque TLV and subTLVs
This adds support for the OSPFv2 Extended Link Opaque TLV as defined in RFC7684 and subTLVs defined in RFC8665 for segment routing.
1 parent 6e1cedb commit db6e2a0

File tree

6 files changed

+447
-0
lines changed

6 files changed

+447
-0
lines changed

CREDITS

+1
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ Additional people who have contributed patches (in alphabetical order):
253253
Nicolas Ferrero <toorop at babylo dot net>
254254
Niels Provos <provos at openbsd dot org>
255255
Nikhil AP <nikhilap at arista dot com>
256+
Nikhil Goyal <nikhilg at arista dot com
256257
Nikolay Edigaryev <edigaryev at gmail dot com>
257258
niks3089 <niks3089 at gmail dot com>
258259
Noritoshi Demizu <demizu at users dot sourceforge dot net>

ospf.h

+17
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,16 @@
118118
#define LS_OPAQUE_RI_TLV_SR_LOCAL_BLOCK 14 /* rfc8865 */
119119
#define LS_OPAQUE_RI_TLV_SRMS_PREFERENCE 15 /* rfc8865 */
120120

121+
#define LS_OPAQUE_EXTENDED_LINK_TLV 1 /* rfc7684 */
122+
123+
#define LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID 2 /* rfc8665 */
124+
125+
#define LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_B 0x80
126+
#define LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_V 0x40
127+
#define LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_L 0x20
128+
#define LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_G 0x10
129+
#define LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_P 0x8
130+
121131
/* rla_link.link_type */
122132
#define RLA_TYPE_ROUTER 1 /* point-to-point to another router */
123133
#define RLA_TYPE_TRANSIT 2 /* connection to transit network */
@@ -266,6 +276,13 @@ struct lsa {
266276
nd_byte data[1]; /* may repeat */
267277
} un_ep_tlv[1]; /* may repeat */
268278

279+
/* Extended Link LSA */
280+
struct {
281+
nd_uint16_t type;
282+
nd_uint16_t length;
283+
nd_byte data[1]; /* may repeat */
284+
} un_el_tlv[1]; /* may repeat */
285+
269286
/* Unknown LSA */
270287
struct unknown {
271288
nd_byte data[1]; /* may repeat */

print-ospf.c

+141
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,33 @@ static const struct tok lsa_opaque_ri_tlv_sr_algos[] = {
217217
{ 0, NULL }
218218
};
219219

220+
static const struct tok lsa_opaque_el_tlv_values[] = {
221+
{ LS_OPAQUE_EXTENDED_LINK_TLV, "Extended Link" },
222+
{ 0, NULL }
223+
};
224+
225+
static const struct tok lsa_opaque_extended_link_link_type_values[] = {
226+
{ RLA_TYPE_ROUTER, "Point-to-Point Link" },
227+
{ RLA_TYPE_TRANSIT, "Link to Transit Network" },
228+
{ RLA_TYPE_STUB, "Link to Stub Network" },
229+
{ RLA_TYPE_VIRTUAL, "Virtual Link" },
230+
{ 0, NULL }
231+
};
232+
233+
static const struct tok lsa_opaque_extended_link_subtlv_adj_sid_flag_values[] = {
234+
{ LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_B, "Backup" },
235+
{ LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_V, "Value/Index" },
236+
{ LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_L, "Local/Global" },
237+
{ LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_G, "Group" },
238+
{ LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_P, "Persistent" },
239+
{ 0, NULL }
240+
};
241+
242+
static const struct tok lsa_opaque_extended_link_subtlv_values[] = {
243+
{ LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID, "Adj-SID Sub-TLV" },
244+
{ 0, NULL }
245+
};
246+
220247
static const struct tok ospf_lls_tlv_values[] = {
221248
{ OSPF_LLS_EO, "Extended Options" },
222249
{ OSPF_LLS_MD5, "MD5 Authentication" },
@@ -930,6 +957,113 @@ ospf_ep_lsa_print(netdissect_options *ndo, const uint8_t *tptr, u_int lsa_length
930957
return 0;
931958
}
932959

960+
static int
961+
ospf_el_lsa_print(netdissect_options *ndo, const uint8_t *tptr, u_int lsa_length)
962+
{
963+
u_int tlv_type, tlv_length, link_type, sub_tlv_flags;
964+
u_int sub_tlv_type, sub_tlv_length, sub_tlv_remaining;
965+
const uint8_t *sub_tlv_tptr;
966+
u_int vflag, lflag;
967+
968+
while (lsa_length >= 4) {
969+
tlv_type = GET_BE_U_2(tptr);
970+
tlv_length = GET_BE_U_2(tptr+2);
971+
tptr+=4;
972+
lsa_length-=4;
973+
974+
/* Infinite loop protection. */
975+
if (tlv_type == 0 || tlv_length == 0) {
976+
return -1;
977+
}
978+
979+
ND_PRINT("\n\t %s TLV (%u), length: %u, value: ",
980+
tok2str(lsa_opaque_el_tlv_values,"unknown",tlv_type),
981+
tlv_type,
982+
tlv_length);
983+
984+
switch (tlv_type) {
985+
case LS_OPAQUE_EXTENDED_LINK_TLV:
986+
link_type = GET_U_1(tptr);
987+
988+
ND_PRINT("\n\t Link Type: %s (%u)",
989+
tok2str(lsa_opaque_extended_link_link_type_values,"unknown",link_type),
990+
link_type);
991+
ND_PRINT("\n\t Reserved: %u", GET_BE_U_3(tptr+1));
992+
ND_PRINT("\n\t Link ID: %s", GET_IPADDR_STRING(tptr+4));
993+
ND_PRINT("\n\t Link Data: %s", GET_IPADDR_STRING(tptr+8));
994+
995+
sub_tlv_tptr = tptr + 12;
996+
sub_tlv_remaining = tlv_length - 12;
997+
998+
while(sub_tlv_remaining > 0) {
999+
sub_tlv_type = GET_BE_U_2(sub_tlv_tptr);
1000+
sub_tlv_length = GET_BE_U_2(sub_tlv_tptr + 2);
1001+
sub_tlv_remaining-=4;
1002+
sub_tlv_tptr+=4;
1003+
1004+
ND_PRINT("\n\t %s (%u), length: %u, value: ",
1005+
tok2str(lsa_opaque_extended_link_subtlv_values,"unknown",sub_tlv_type),
1006+
sub_tlv_type,
1007+
sub_tlv_length);
1008+
1009+
switch(sub_tlv_type){
1010+
1011+
case LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID:
1012+
sub_tlv_flags = GET_U_1(sub_tlv_tptr);
1013+
1014+
ND_PRINT("\n\t Flags: [%s]",
1015+
bittok2str(lsa_opaque_extended_link_subtlv_adj_sid_flag_values, "none", sub_tlv_flags));
1016+
ND_PRINT("\n\t Reserved: %u", GET_U_1(sub_tlv_tptr+1));
1017+
ND_PRINT("\n\t MT-ID: %u", GET_U_1(sub_tlv_tptr+2));
1018+
ND_PRINT("\n\t Weight: %u", GET_U_1(sub_tlv_tptr+3));
1019+
1020+
vflag = sub_tlv_flags & LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_V;
1021+
lflag = sub_tlv_flags & LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_L;
1022+
if (vflag && lflag) {
1023+
ND_PRINT("\n\t SID/Label: %u",GET_BE_U_3(sub_tlv_tptr + 4));
1024+
}
1025+
else if ( !vflag && !lflag ) {
1026+
ND_PRINT("\n\t SID/Label: %u",GET_BE_U_4(sub_tlv_tptr + 4));
1027+
}
1028+
else {
1029+
ND_PRINT("\n\t Invalid V-Flag and L-flag combination");
1030+
if (!print_unknown_data(ndo, sub_tlv_tptr, "\n\t ", sub_tlv_length))
1031+
return(-1);
1032+
}
1033+
break;
1034+
1035+
default:
1036+
if (ndo->ndo_vflag <= 1) {
1037+
if (!print_unknown_data(ndo, sub_tlv_tptr, "\n\t ", sub_tlv_length))
1038+
return(-1);
1039+
}
1040+
break;
1041+
}
1042+
1043+
if (sub_tlv_length % 4) {
1044+
sub_tlv_length += (4 - (sub_tlv_length % 4));
1045+
}
1046+
sub_tlv_tptr+=sub_tlv_length;
1047+
sub_tlv_remaining-=sub_tlv_length;
1048+
}
1049+
break;
1050+
default:
1051+
if (ndo->ndo_vflag <= 1) {
1052+
if (!print_unknown_data(ndo, tptr, "\n\t ", tlv_length))
1053+
return -1;
1054+
}
1055+
}
1056+
1057+
/* in OSPF everything has to be 32-bit aligned, including TLVs */
1058+
if (tlv_length % 4) {
1059+
tlv_length += (4 - (tlv_length % 4));
1060+
}
1061+
tptr+=tlv_length;
1062+
lsa_length-=tlv_length;
1063+
}
1064+
return 0;
1065+
}
1066+
9331067
/*
9341068
* Print a single link state advertisement. If truncated or if LSA length
9351069
* field is less than the length of the LSA header, return NULl, else
@@ -1231,6 +1365,13 @@ ospf_print_lsa(netdissect_options *ndo,
12311365
}
12321366
break;
12331367

1368+
case LS_OPAQUE_TYPE_EL:
1369+
if (ospf_el_lsa_print(ndo, (const u_char *)(lsap->lsa_un.un_el_tlv),
1370+
ls_length) == -1) {
1371+
return(ls_end);
1372+
}
1373+
break;
1374+
12341375
default:
12351376
if (ndo->ndo_vflag <= 1) {
12361377
if (!print_unknown_data(ndo, (const uint8_t *)lsap->lsa_un.un_unknown,

tests/TESTLIST

+1
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ ospf-ack ospf-ack.pcap ospf-ack.out -v
146146
ospf-sr ospf-sr.pcapng ospf-sr-v.out -v
147147
ospf-sr2 ospf-sr2.pcapng ospf-sr2-v.out -v
148148
ospf-sr-ri-sid ospf-sr-ri-sid.pcap ospf-sr-ri-sid-v.out -v
149+
ospf-sr-link ospf-sr-link.pcap ospf-sr-link-v.out -v
149150
ospf3_ah-vv OSPFv3_with_AH.pcap ospf3_ah-vv.out -v -v
150151
ospf3_auth-vv ospf3_auth.pcapng ospf3_auth-vv.out -v -v
151152
ospf3_bc-vv OSPFv3_broadcast_adjacency.pcap ospf3_bc-vv.out -v -v

0 commit comments

Comments
 (0)