aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-bgp.c127
1 files changed, 124 insertions, 3 deletions
diff --git a/epan/dissectors/packet-bgp.c b/epan/dissectors/packet-bgp.c
index eb05d72860..9b0d08b3ea 100644
--- a/epan/dissectors/packet-bgp.c
+++ b/epan/dissectors/packet-bgp.c
@@ -669,6 +669,17 @@ static dissector_handle_t bgp_handle;
#define BGP_LS_SR_ADJACENCY_SID_FLAG_SO 0x10
#define BGP_LS_SR_ADJACENCY_SID_FLAG_SI 0x08
+/* SR-Capabilities TLV flags, draft-gredler-idr-bgp-ls-segment-routing-ext-01:
+
+ 0 1 2 3 4 5 6 7
+ +--+--+--+--+--+--+--+--+
+ if Protocol-ID is IS-IS |I |V |H | | | | | |
+ +--+--+--+--+--+--+--+--+
+*/
+#define BGP_LS_SR_CAPABILITY_FLAG_I 0x80
+#define BGP_LS_SR_CAPABILITY_FLAG_V 0x40
+#define BGP_LS_SR_CAPABILITY_FLAG_H 0x20
+
static const value_string bgptypevals[] = {
{ BGP_OPEN, "OPEN Message" },
{ BGP_UPDATE, "UPDATE Message" },
@@ -1552,6 +1563,17 @@ static int hf_bgp_ls_ipv4_topology_prefix_nlri_type = -1;
static int hf_bgp_ls_ipv6_topology_prefix_nlri_type = -1;
/* BGP-LS + SR */
+static int hf_bgp_ls_sr_tlv_capabilities = -1;
+static int hf_bgp_ls_sr_tlv_capabilities_range_size = -1;
+static int hf_bgp_ls_sr_tlv_capabilities_flags = -1;
+static int hf_bgp_ls_sr_tlv_capabilities_flags_i = -1;
+static int hf_bgp_ls_sr_tlv_capabilities_flags_v = -1;
+static int hf_bgp_ls_sr_tlv_capabilities_flags_h = -1;
+static int hf_bgp_ls_sr_tlv_capabilities_flags_reserved = -1;
+static int hf_bgp_ls_sr_tlv_capabilities_sid_label = -1;
+static int hf_bgp_ls_sr_tlv_capabilities_sid_index = -1;
+static int hf_bgp_ls_sr_tlv_algorithm = -1;
+static int hf_bgp_ls_sr_tlv_algorithm_value = -1;
static int hf_bgp_ls_sr_tlv_prefix_sid = -1;
static int hf_bgp_ls_sr_tlv_prefix_sid_flags = -1;
static int hf_bgp_ls_sr_tlv_prefix_sid_flags_r = -1;
@@ -3583,9 +3605,74 @@ decode_link_state_attribute_tlv(proto_tree *tree, tvbuff_t *tvb, gint offset, pa
break;
case BGP_LS_SR_TLV_SR_CAPABILITY:
+ {
+ /*
+ 0 1 2 3 4 5 6 7
+ +--+--+--+--+--+--+--+--+
+ |I |V |H | | | | | |
+ +--+--+--+--+--+--+--+--+
+ */
+ static const int *sr_capabilities_flags[] = {
+ &hf_bgp_ls_sr_tlv_capabilities_flags_i,
+ &hf_bgp_ls_sr_tlv_capabilities_flags_v,
+ &hf_bgp_ls_sr_tlv_capabilities_flags_h,
+ &hf_bgp_ls_sr_tlv_capabilities_flags_reserved,
+ NULL
+ };
+ gint offset2;
+ gint remaining_data;
+ tlv_item = proto_tree_add_item(tree, hf_bgp_ls_sr_tlv_capabilities, tvb, offset, length + 4, ENC_NA);
+ tlv_tree = proto_item_add_subtree(tlv_item, ett_bgp_link_state);
+ proto_tree_add_item(tlv_tree, hf_bgp_ls_type, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tlv_tree, hf_bgp_ls_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_bitmask(tlv_tree, tvb, offset + 4, hf_bgp_ls_sr_tlv_capabilities_flags,
+ ett_bgp_link_state, sr_capabilities_flags, ENC_BIG_ENDIAN);
+ /* past flags and reserved byte, we got one or more range + SID/Label Sub-TLV entries */
+ offset2 = offset + 4 + 2;
+ remaining_data = length - 2;
+ while (remaining_data > 0) {
+ guint16 sid_len = 0;
+ /* parse and consume the range field */
+ proto_tree_add_item(tlv_tree, hf_bgp_ls_sr_tlv_capabilities_range_size, tvb, offset2, 3, ENC_BIG_ENDIAN);
+ offset2 += 3;
+ /* parse and consume type/len fields */
+ proto_tree_add_item(tlv_tree, hf_bgp_ls_type, tvb, offset2, 2, ENC_BIG_ENDIAN);
+ offset2 += 2;
+ proto_tree_add_item(tlv_tree, hf_bgp_ls_length, tvb, offset2, 2, ENC_BIG_ENDIAN);
+ sid_len = tvb_get_ntohs(tvb, offset2);
+ offset2 += 2;
+ if (sid_len == 3) {
+ /* parse and consume the SID/Label field */
+ proto_tree_add_item(tlv_tree, hf_bgp_ls_sr_tlv_capabilities_sid_label, tvb, offset2, 3, ENC_BIG_ENDIAN);
+ offset2 += 3;
+ remaining_data -= 10;
+ } else {
+ /* parse and consume the SID/Index field */
+ proto_tree_add_item(tlv_tree, hf_bgp_ls_sr_tlv_capabilities_sid_index, tvb, offset2, 4, ENC_BIG_ENDIAN);
+ offset2 += 4;
+ remaining_data -= 11;
+ }
+ }
+ }
break;
case BGP_LS_SR_TLV_SR_ALGORITHM:
+ {
+ gint offset2;
+ gint remaining_data;
+ tlv_item = proto_tree_add_item(tree, hf_bgp_ls_sr_tlv_algorithm, tvb, offset, length+4, ENC_NA);
+ tlv_tree = proto_item_add_subtree(tlv_item, ett_bgp_link_state);
+ proto_tree_add_item(tlv_tree, hf_bgp_ls_type, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tlv_tree, hf_bgp_ls_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
+ /* past type-length fields, we got one or more 'Algorithm N' value */
+ offset2 = offset + 4;
+ remaining_data = length;
+ while (remaining_data > 0) {
+ proto_tree_add_item(tlv_tree, hf_bgp_ls_sr_tlv_algorithm_value, tvb, offset2, 1, ENC_NA);
+ offset2 += 1;
+ remaining_data -= 1;
+ }
+ }
break;
/* NODE & LINK ATTRIBUTE TLVs */
@@ -8619,7 +8706,41 @@ proto_register_bgp(void)
{ "IPv6 Gateway address", "bgp.evpn.nlri.ipv6.gtw_addr", FT_IPv6,
BASE_NONE, NULL, 0x0, NULL, HFILL}},
/* segment routing extentions to link state */
- /* Prefix-SID TLV */
+ /* Node Attributes TLVs */
+ { &hf_bgp_ls_sr_tlv_capabilities,
+ { "SR Capabilities", "bgp.ls.sr.tlv.capabilities", FT_NONE,
+ BASE_NONE, NULL, 0x0, NULL, HFILL}},
+ { &hf_bgp_ls_sr_tlv_capabilities_flags,
+ { "Flags", "bgp.ls.sr.tlv.capabilities.flags", FT_UINT8,
+ BASE_HEX, NULL, 0x0, NULL, HFILL}},
+ { &hf_bgp_ls_sr_tlv_capabilities_flags_i,
+ { "MPLS IPv4 flag (I)", "bgp.ls.sr.tlv.capabilities.flags.i", FT_BOOLEAN,
+ 8, TFS(&tfs_set_notset), BGP_LS_SR_CAPABILITY_FLAG_I, NULL, HFILL}},
+ { &hf_bgp_ls_sr_tlv_capabilities_flags_v,
+ { "MPLS IPv6 flag (V)", "bgp.ls.sr.tlv.capabilities.flags.v", FT_BOOLEAN,
+ 8, TFS(&tfs_set_notset), BGP_LS_SR_CAPABILITY_FLAG_V, NULL, HFILL}},
+ { &hf_bgp_ls_sr_tlv_capabilities_flags_h,
+ { "SR-IPv6 flag (H)", "bgp.ls.sr.tlv.capabilities.flags.h", FT_BOOLEAN,
+ 8, TFS(&tfs_set_notset), BGP_LS_SR_CAPABILITY_FLAG_H, NULL, HFILL}},
+ { &hf_bgp_ls_sr_tlv_capabilities_flags_reserved,
+ { "Reserved", "bgp.ls.sr.tlv.capabilities.flags.reserved", FT_UINT8,
+ BASE_HEX, NULL, 0x1F, NULL, HFILL}},
+ { &hf_bgp_ls_sr_tlv_capabilities_range_size,
+ { "Range Size", "bgp.ls.sr.tlv.capabilities.range_size", FT_UINT24,
+ BASE_DEC, NULL, 0x0, NULL, HFILL}},
+ { &hf_bgp_ls_sr_tlv_capabilities_sid_label,
+ { "From Label", "bgp.ls.sr.tlv.capabilities.sid.label", FT_UINT24,
+ BASE_DEC, NULL, 0x0FFFFF, NULL, HFILL}},
+ { &hf_bgp_ls_sr_tlv_capabilities_sid_index,
+ { "From Index", "bgp.ls.sr.tlv.capabilities.sid.index", FT_UINT32,
+ BASE_DEC, NULL, 0x0, NULL, HFILL}},
+ { &hf_bgp_ls_sr_tlv_algorithm,
+ { "SR Algorithm", "bgp.ls.sr.tlv.algorithm", FT_NONE,
+ BASE_NONE, NULL, 0x0, NULL, HFILL}},
+ { &hf_bgp_ls_sr_tlv_algorithm_value,
+ { "SR Algorithm", "bgp.ls.sr.tlv.algorithm.value", FT_UINT8,
+ BASE_DEC, NULL, 0x0, NULL, HFILL}},
+ /* Prefix Attribute TLVs */
{ &hf_bgp_ls_sr_tlv_prefix_sid,
{ "Prefix SID TLV", "bgp.ls.sr.tlv.prefix.sid", FT_NONE,
BASE_NONE, NULL, 0x0, NULL, HFILL}},
@@ -8655,11 +8776,11 @@ proto_register_bgp(void)
BASE_DEC, NULL, 0x0, NULL, HFILL}},
{ &hf_bgp_ls_sr_tlv_prefix_sid_label,
{ "SID/Label", "bgp.ls.sr.tlv.prefix.sid.label", FT_UINT24,
- BASE_DEC, NULL, 0xFFFFF0, NULL, HFILL}},
+ BASE_DEC, NULL, 0x0FFFFF, NULL, HFILL}},
{ &hf_bgp_ls_sr_tlv_prefix_sid_index,
{ "SID/Index", "bgp.ls.sr.tlv.prefix.sid.index", FT_UINT32,
BASE_DEC, NULL, 0x0, NULL, HFILL}},
- /* Adjacency-SID TLV */
+ /* Adjacency Attribute TLVs */
{ &hf_bgp_ls_sr_tlv_adjacency_sid,
{ "Adjacency SID TLV", "bgp.ls.sr.tlv.adjacency.sid", FT_NONE,
BASE_NONE, NULL, 0x0, NULL, HFILL}},