From Roberto Morro:
authorjake <jake@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 3 Feb 2011 20:14:38 +0000 (20:14 +0000)
committerjake <jake@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 3 Feb 2011 20:14:38 +0000 (20:14 +0000)
- add PATH-KEY object, PKSv4 and PKSv6 subobjects in ERO (RFC5520)
- new METRIC types, Objective Function (OF) object and TLV (RFC5541)
- new RP object Flags
- restructured PCEP_ERROR object dissection (easier to add new
  error_types, error_values)

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@35789 f5534014-38df-0310-8fa8-9805f1628bb7

epan/dissectors/packet-pcep.c

index 5b4910f2b2ef92337edf24b5f1bbf277d89223f9..1b35146c9f34a9e109741561c6ea542a10cd2493 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for PCEP packet disassembly
  * draft-ietf-pce-pcep-09
  * draft-ietf-pce-pcep-xro-02
- * See also RFC 4655 and RFC 4657
+ * See also RFC 4655, RFC 4657, RFC 5520 and RFC 5541
  *
  * (c) Copyright 2007 Silvia Cristina Tejedor <silviacristina.tejedor@gmail.com>
  *
@@ -56,8 +56,9 @@
 #define PCEP_PCEP_ERROR_OBJ            13
 #define PCEP_LOAD_BALANCING_OBJ                14
 #define PCEP_CLOSE_OBJ                 15
-#define NO_DEFINED_OBJ                 16
+#define PCEP_PATH_KEY_OBJ              16
 #define PCEP_XRO_OBJ                   17
+#define PCEP_OF_OBJ                    21
 
 /*Subobjects of EXPLICIT ROUTE Object*/
 #define PCEP_SUB_IPv4                          1
@@ -67,6 +68,8 @@
 #define PCEP_SUB_SRLG                          5
 #define PCEP_SUB_AUTONOMOUS_SYS_NUM            32
 #define PCEP_SUB_EXRS                          33
+#define PCEP_SUB_PKSv4                         64
+#define PCEP_SUB_PKSv6                         65
 #define PCEP_SUB_AUTONOMOUS_SYS_NUM_XRO                4
 #define PCEP_SUB_UNNUMB_INTERFACE_ID_XRO       3
 
 #define NO_SATISFYING                  0
 #define CHAIN_BROKEN                   1
 
-/*Possible values of "Type (T)" in the METRIC object */
-#define NO_DEFINED                     0
-#define IGP_METRIC                     1
-#define TE_METRIC                      2
-#define HOP_COUNTS                     3
-
 /*Possible values of L in the ERO and IRO objects */
 #define STRICT_HOP                     0
 #define LOOSE_HOP                      1
 #define SYNCH_PCREQ_MIS                        7
 #define UNKNOWN_REQ_REF                        8
 #define ATTEMPT_2_SESSION              9
-#define UNRECO_IRO_SUBOBJ              11
-#define UNRECO_EXRS_SUBOBJ             12
-
-/*Different values of errors type=1*/
-#define RX_MALFORM_PKT                 1
-#define NO_OPEN_MSG                    2
-#define UNACEP_NO_NEGO_SSESION         3
-#define UNACEP_NEG_SESSION             4
-#define TWO_OPEN_MSG_UNACEP            5
-#define RX_PCEPERR_UNACEP_SESSION      6
-#define NO_KEEPALIVE_PCEPERR           7
-
-/*Different values of errors type=3*/
-#define UNRECON_OBJ_CLASS              1
-#define UNRECON_OBJ_TYPE               2
-
-/*Different values of errors type=4*/
-#define NO_SUPP_OBJ                    1
-#define NO_SUPP_TYPE                   2
-
-/*Different values of errors type=5*/
-#define C_METRIC_SET                   1
-#define O_OBJ_SET                      2
-
-/*Different values of errors type=6*/
-#define RP_OBJ_MISS                    1
-#define RRO_OBJ_MISS                   2
-#define END_POINT_OBJ_MISS             3
+#define INVALID_OBJ                    10
+#define UNRECO_EXRS_SUBOBJ             11
+#define DIFFSERV_TE_ERROR              12
+#define BRPC_FAILURE                   13
+#define GCO_ERROR                      15
+#define P2MP_CAPABILITY_ERROR          16
+#define P2MP_END_POINTS_ERROR          17
+#define P2MP_FRAGMENT_ERROR            18
 
 /*Different values of Reason in the CLOSE object */
 #define NO_EXP_PROV                    1
 #define  PCEP_RP_R                     0x000008
 #define  PCEP_RP_B                     0x000010
 #define  PCEP_RP_O                     0x000020
-#define  PCEP_RP_RESERVED              0xFFFFC0
+#define  PCEP_RP_V                     0x000040
+#define  PCEP_RP_S                     0x000080
+#define  PCEP_RP_P                     0x000100
+#define  PCEP_RP_D                     0x000200
+#define  PCEP_RP_M                     0x000400
+#define  PCEP_RP_E                     0x000800
+#define  PCEP_RP_N                     0x001000
+#define  PCEP_RP_F                     0x002000
+#define  PCEP_RP_RESERVED              0xFFC000
 
 /*Mask for the flags of NO PATH Object*/
 #define  PCEP_NO_PATH_C                        0x8000
 
 /*Mask for the flags of METRIC Object*/
-#define  PCEP_METRIC_C                 0x01
-#define  PCEP_METRIC_B                 0x02
+#define  PCEP_METRIC_B                 0x01
+#define  PCEP_METRIC_C                 0x02
 
 /*Mask for the flags of LSPA Object*/
 #define  PCEP_LSPA_L                   0x01
@@ -219,6 +204,14 @@ static gint pcep_rp_flags_pri = -1;
 static gint pcep_rp_flags_r = -1;
 static gint pcep_rp_flags_b = -1;
 static gint pcep_rp_flags_o = -1;
+static gint pcep_rp_flags_v = -1;
+static gint pcep_rp_flags_s = -1;
+static gint pcep_rp_flags_p = -1;
+static gint pcep_rp_flags_d = -1;
+static gint pcep_rp_flags_m = -1;
+static gint pcep_rp_flags_e = -1;
+static gint pcep_rp_flags_n = -1;
+static gint pcep_rp_flags_f = -1;
 static gint pcep_rp_flags_reserved = -1;
 static gint ett_pcep_obj_no_path = -1;
 static gint pcep_no_path_flags_c = -1;
@@ -240,6 +233,7 @@ static gint ett_pcep_obj_notification = -1;
 static gint ett_pcep_obj_error = -1;
 static gint ett_pcep_obj_load_balancing = -1;
 static gint ett_pcep_obj_close = -1;
+static gint ett_pcep_obj_path_key = -1;
 static gint ett_pcep_obj_xro = -1;
 static gint pcep_xro_flags_f= -1;
 static gint pcep_subobj_flags_lpa= -1;
@@ -286,8 +280,9 @@ static const value_string pcep_class_vals[] = {
        {PCEP_PCEP_ERROR_OBJ,           "PCEP ERROR OBJECT"             },
        {PCEP_LOAD_BALANCING_OBJ,       "LOAD BALANCING OBJECT"         },
        {PCEP_CLOSE_OBJ,                "CLOSE OBJECT"                  },
-       {NO_DEFINED_OBJ,                "Non Defined OBJECT"            },
+       {PCEP_PATH_KEY_OBJ,             "PATH-KEY OBJECT"               },
        {PCEP_XRO_OBJ,                  "EXCLUDE ROUTE OBJECT (XRO)"    },
+       {PCEP_OF_OBJ,                   "OBJECTIVE FUNCTION OBJECT (OF)"},
        {0,                              NULL                           }
 };
 
@@ -298,6 +293,8 @@ static const value_string pcep_subobj_vals[] = {
        {PCEP_SUB_UNNUMB_INTERFACE_ID,  "SUBOBJECT UNNUMBERED INTERFACE-ID"     },
        {PCEP_SUB_SRLG,                 "SUBOBJECT SRLG"                        },
        {PCEP_SUB_AUTONOMOUS_SYS_NUM,   "SUBOBJECT AUTONOMOUS SYSTEM NUMBER"    },
+       {PCEP_SUB_PKSv4,                "SUBOBJECT PATH KEY (IPv4)"             },
+       {PCEP_SUB_PKSv6,                "SUBOBJECT PATH KEY (IPv6)"             },
        {0,                              NULL                                   }
 };
 
@@ -320,25 +317,32 @@ static const value_string pcep_no_path_obj_vals[] = {
 
 /*Different values of "Type (T)" in the METRIC Obj */
 static const value_string pcep_metric_obj_vals[] = {
-       {NO_DEFINED,            "Type not defined"              },
-       {IGP_METRIC,            "Type: IGP Metric (T=1)"        },
-       {TE_METRIC,             "Type: TE Metric (T=2)"         },
-       {HOP_COUNTS,            "Type: Hop Counts (T=3)"        },
-       {0,                      NULL                           }
+       {0,     "not defined"                           },
+       {1,     "IGP Metric"                            },
+       {2,     "TE Metric"                             },
+       {3,     "Hop Counts"                            },
+       {4,     "Aggregate bandwidth consumption"       },
+       {5,     "Load of the most loaded link"          },
+       {6,     "Cumulative IGP cost"                   },
+       {7,     "Cumulative TE cost"                    },
+       {8,     "P2MP IGM metric"                       },
+       {9,     "P2MP TE metric"                        },
+       {10,    "P2MP hop count metric"                 },
+       {0,     NULL                                    }
 };
 
 /*Different values for (L) in the ERO and IRO Objs */
 static const value_string pcep_route_l_obj_vals[] = {
-       {STRICT_HOP,                    "L=0 Strict Hop in the Explicit Route"          },
-       {LOOSE_HOP,                     "L=1 Loose Hop in the Explicit Route"           },
-       {0,                              NULL                                           }
+       {STRICT_HOP,                    "L=0 Strict Hop"        },
+       {LOOSE_HOP,                     "L=1 Loose Hop"         },
+       {0,                             NULL                    }
 };
 
 /*Different values of the direction of the label (U) in the ERO and RRO Objs */
 static const value_string pcep_route_u_obj_vals[] = {
-       {DOWNSTREAM_LABEL,                      "U=0 S Downstream Label" },
-       {UPSTREAM_LABEL,                        "U=1 Upstream Label"     },
-       {0,                                     NULL                     }
+       {DOWNSTREAM_LABEL,              "U=0 Downstream Label"  },
+       {UPSTREAM_LABEL,                "U=1 Upstream Label"    },
+       {0,                             NULL                    }
 };
 
 /*Values of Notification type*/
@@ -363,35 +367,164 @@ static const value_string pcep_notification_values2_vals[] = {
 };
 
 
+/* PCEP TLVs */
+static const value_string pcep_tlvs_vals[] = {
+       {1,             "NO-PATH-VECTOR TLV"    },
+       {2,             "OVERLOAD-DURATION TLV" },
+       {3,             "REQ-MISSING TLV"       },
+       {4,             "OF-list TLV"           },
+       {5,             "Order TLV"             },
+       {6,             "P2MP Capable"          },
+       {0,             NULL                    }
+};
+
+
+/*Values of Objective Functions*/
+static const value_string pcep_of_vals[] = {
+       {1,             "Minimum Cost Path"                             },
+       {2,             "Minimum Load Path"                             },
+       {3,             "Maximum residual Bandwidth Path"               },
+       {4,             "Minimize aggregate Bandwidth Consumption"      },
+       {5,             "Minimize the Load of the most loaded Link"     },
+       {6,             "Minimize the Cumulative Cost of a set of paths"},
+       {0,             NULL                                            }
+};
+
+
 /*Values of different types of errors*/
 static const value_string pcep_error_types_obj_vals[] = {
-       {ESTABLISH_FAILURE,             "1 PCEP Session Establishment Failure"          },
-       {CAP_NOT_SUPPORTED,             "2 Capability non supported"                    },
-       {UNKNOWN_OBJ,                   "3 Unknown Object"                                      },
-       {NOT_SUPP_OBJ,                  "4 Not Supported Object"                                },
-       {POLICY_VIOLATION,              "5 Policy Violation"                            },
-       {MANDATORY_OBJ_MIS,             "6 Mandatory Object Missing"                    },
-       {SYNCH_PCREQ_MIS,               "7 Synchronized Path Computation Request Missing"       },
-       {UNKNOWN_REQ_REF,               "8 Unknown Request Reference"                   },
-       {ATTEMPT_2_SESSION,             "9 Attempt to Establish a Second PCEP Session"  },
-       {UNRECO_IRO_SUBOBJ,             "11 Unrecognized IRO Subobject" },
-       {UNRECO_EXRS_SUBOBJ,            "12 Unrecognized EXRS Subobject"        },
-       {0,                              NULL                                                   }
+       {ESTABLISH_FAILURE,     "PCEP Session Establishment Failure"            },
+       {CAP_NOT_SUPPORTED,     "Capability non supported"                      },
+       {UNKNOWN_OBJ,           "Unknown Object"                                },
+       {NOT_SUPP_OBJ,          "Not Supported Object"                          },
+       {POLICY_VIOLATION,      "Policy Violation"                              },
+       {MANDATORY_OBJ_MIS,     "Mandatory Object Missing"                      },
+       {SYNCH_PCREQ_MIS,       "Synchronized Path Computation Request Missing" },
+       {UNKNOWN_REQ_REF,       "Unknown Request Reference"                     },
+       {ATTEMPT_2_SESSION,     "Attempt to Establish a Second PCEP Session"    },
+       {INVALID_OBJ,           "Reception of an invalid object"                },
+       {UNRECO_EXRS_SUBOBJ,    "Unrecognized EXRS Subobject"                   },
+       {DIFFSERV_TE_ERROR,     "Differsv-aware TE error"                       },
+       {BRPC_FAILURE,          "BRPC procedure completion failure"             },
+       {GCO_ERROR,             "Global Concurrent Optimization error"          },
+       {P2MP_CAPABILITY_ERROR, "P2PM capability error"                         },
+       {P2MP_END_POINTS_ERROR, "P2PM END-POINTS error"                         },
+       {P2MP_FRAGMENT_ERROR,   "P2PM Fragmentation error"                      },
+       {0,                      NULL                                           }
+};
+
+/*Error values for error type 1*/
+static const value_string pcep_error_value_1_vals[] = {
+       {1,     "Reception of an invalid Open msg or a non Open msg"},
+       {2,     "No Open Message received before the expiration of the OpenWait Timer "},
+       {3,     "Unacceptable and non Negotiable session characteristics"},
+       {4,     "Unacceptable but Negotiable session characteristics"},
+       {5,     "Reception of a second Open Message with still Unacceptable Session characteristics"},
+       {6,     "Reception of a PCEPrr message proposing unacceptable session characteristics"},
+       {7,     "NO Keepalive or PCEPrr message received before the expiration of the Keepwait timer supported"},
+       {8,     "PCEP version not supported"},
+       {0,     NULL}
+};
+
+/*Error values for error type 3*/
+static const value_string pcep_error_value_3_vals[] = {
+       {1,     "Unrecognized object class"},
+       {2,     "Unrecognized object type"},
+       {0,     NULL}
+};
+
+/*Error values for error type 4*/
+static const value_string pcep_error_value_4_vals[] = {
+       {1,     "Not supported object class"},
+       {2,     "Not supported object type"},
+       {4,     "Not supported parameter"},
+       {0,     NULL}
+};
+
+/*Error values for error type 5*/
+static const value_string pcep_error_value_5_vals[] = {
+       {1,     "C bit of the METRIC object set (Request Rejected)"},
+       {2,     "O bit of the RP object set (Request Rejected)"},
+       {3,     "Objective Function not allowed (Request Rejected)"},
+       {4,     "OF bit of the RP object set (Request Rejected)"},
+       {5,     "Global concurrent optimization not allowed"},
+       {6,     "Monitoring message supported but rejected due to policy violation"},
+       {7,     "P2MP path computation is not allowed"},
+       {0,     NULL}
+};
+
+
+/*Error values for error type 6*/
+static const value_string pcep_error_value_6_vals[] = {
+       {1,     "RP object missing"},
+       {2,     "RRO object missing for a reoptimization request (R bit of the RP Object set)"},
+       {3,     "END-POINTS object missing"},
+       {4,     "MONITORINS object missing"},
+       {0,     NULL}
+};
+
+/*Error values for error type 10*/
+static const value_string pcep_error_value_10_vals[] = {
+       {1,     "Reception of an object with P flag not set although the P-flag must be set"},
+       {0,     NULL}
+};
+
+/*Error values for error type 12*/
+static const value_string pcep_error_value_12_vals[] = {
+       {1,     "Unsupported class-type"},
+       {2,     "Invalid class-type"},
+       {3,     "Class-type ans setup priority do not form a configured TE-class"},
+       {0,     NULL}
+};
+
+/*Error values for error type 13*/
+static const value_string pcep_error_value_13_vals[] = {
+       {1,     "BRPC procedure not supported by one or more PCEs along the domain path"},
+       {0,     NULL}
+};
+
+/*Error values for error type 15*/
+static const value_string pcep_error_value_15_vals[] = {
+       {1,     "Insufficient memory"},
+       {2,     "Global concurrent optimization not supported"},
+       {0,     NULL}
+};
+
+/*Error values for error type 16*/
+static const value_string pcep_error_value_16_vals[] = {
+       {1,     "The PCE cannot satisfy the request due to insufficient memory"},
+       {2,     "The PCE is not capable of P2MP computation"},
+       {0,     NULL}
+};
+
+/*Error values for error type 17*/
+static const value_string pcep_error_value_17_vals[] = {
+       {1,     "The PCE cannot satisfy the request due to no END-POINTS with leaf type 2"},
+       {2,     "The PCE cannot satisfy the request due to no END-POINTS with leaf type 3"},
+       {3,     "The PCE cannot satisfy the request due to no END-POINTS with leaf type 4"},
+       {4,     "The PCE cannot satisfy the request due to inconsistent END-POINTS"},
+       {0,     NULL}
+};
+
+/*Error values for error type 18*/
+static const value_string pcep_error_value_18_vals[] = {
+       {1,     "Fragmented request failure"},
+       {0,     NULL}
 };
 
 static const value_string pcep_close_reason_obj_vals[] = {
-       {NO_DEFINED,                    "Reason = 0 no defined"                                 },
-       {NO_EXP_PROV,                   "Reason = 1 No Explanation Provided "                   },
-       {DEADTIME_PROV,                 "Reason = 2 Deadtime Expired"                           },
-       {RECEP_MALFORM_MSG,             "Reason = 3 Reception of a Malformed PCEP Message"      },
+       {0,                             "Not defined"                           },
+       {NO_EXP_PROV,                   "No Explanation Provided"               },
+       {DEADTIME_PROV,                 "Deadtime Expired"                      },
+       {RECEP_MALFORM_MSG,             "Reception of a Malformed PCEP Message" },
        {0,                              NULL                                                   }
 };
 
 static const value_string pcep_xro_attribute_obj_vals[] = {
-       {ATTR_INTERFACE,                "Attribute = 0 Interface"       },
-       {ATTR_NODE,                     "Attribute = 1 Node "           },
-       {ATTR_SRLG,                     "Attribute = 2 SRLG"            },
-       {0,                              NULL                   }
+       {ATTR_INTERFACE,                "Interface"     },
+       {ATTR_NODE,                     "Node"          },
+       {ATTR_SRLG,                     "SRLG"          },
+       {0,                             NULL            }
 };
 
 /* The PCEP filtering keys */
@@ -427,6 +560,7 @@ enum pcep_filter_keys{
     PCEPF_ERROR_TYPE,
     PCEPF_OBJ_LOAD_BALANCING,
     PCEPF_OBJ_CLOSE,
+    PCEPF_OBJ_PATH_KEY,
     PCEPF_OBJ_XRO,
     PCEPF_SUBOBJ,
     PCEPF_SUBOBJ_IPv4,
@@ -436,6 +570,8 @@ enum pcep_filter_keys{
     PCEPF_SUBOBJ_AUTONOMOUS_SYS_NUM,
     PCEPF_SUBOBJ_SRLG,
     PCEPF_SUBOBJ_EXRS,
+    PCEPF_SUBOBJ_PKSv4,
+    PCEPF_SUBOBJ_PKSv6,
     PCEPF_SUBOBJ_XRO,
     PCEPF_SUB_XRO_ATTRIB,
 
@@ -463,6 +599,7 @@ static gint *ett[] = {
        &ett_pcep_obj_error,
        &ett_pcep_obj_load_balancing,
        &ett_pcep_obj_close,
+       &ett_pcep_obj_path_key,
        &ett_pcep_obj_xro,
        &ett_pcep_obj_unknown
 };
@@ -480,7 +617,7 @@ dissect_pcep_tlvs(proto_tree *pcep_obj, tvbuff_t *tvb, int offset, gint length,
        proto_item *ti;
        guint16 tlv_length;
        guint16 tlv_type;
-       int j;
+       int i, j;
        int m = 0;
        int padding = 0;
 
@@ -489,12 +626,37 @@ dissect_pcep_tlvs(proto_tree *pcep_obj, tvbuff_t *tvb, int offset, gint length,
 
                tlv_type = tvb_get_ntohs(tvb, offset+j);
                tlv_length = tvb_get_ntohs(tvb, offset + j + 2);
-               ti = proto_tree_add_text(pcep_obj, tvb, offset + j, tlv_length+4, "TLV %u", m);
+               ti = proto_tree_add_text(pcep_obj, tvb, offset + j, tlv_length+4, "%s", val_to_str(tlv_type, pcep_tlvs_vals, "Unknown TLV (%u). "));
                tlv = proto_item_add_subtree(ti, ett_pcep_obj);
                proto_tree_add_text(tlv, tvb, offset + j, 2, "Type: %u", tlv_type);
                proto_tree_add_text(tlv, tvb, offset + 2 + j, 2, "Length: %u", tlv_length);
-               proto_tree_add_text(tlv, tvb, offset+4+j, tlv_length, "Data: %s",
-                               bytestring_to_str(tvb_get_ptr(tvb, (offset) + 4 + j, tlv_length), tlv_length, ' '));
+               switch (tlv_type)
+               {
+                   case 1:    /* NO-PATH TLV */
+                       proto_tree_add_text(tlv, tvb, offset+4+j, tlv_length, "%s", 
+                                           decode_boolean_bitfield(tvb_get_ntohl(tvb, offset+4+j), 0x0001, 32, "PCE currently unavailable", ""));
+                       proto_tree_add_text(tlv, tvb, offset+4+j, tlv_length, "%s", 
+                                           decode_boolean_bitfield(tvb_get_ntohl(tvb, offset+4+j), 0x0002, 32, "Unknown destination", ""));
+                       proto_tree_add_text(tlv, tvb, offset+4+j, tlv_length, "%s", 
+                                           decode_boolean_bitfield(tvb_get_ntohl(tvb, offset+4+j), 0x0004, 32, "Unknown source", ""));
+                       break;
+
+                   case 3:   /* REQ-MISSING TLV */
+                       proto_tree_add_text(tlv, tvb, offset+4+j, tlv_length, "Request-ID: %u", tvb_get_ntohl(tvb, offset+4+j));
+                       break;
+
+                   case 4:   /* OF TLV */
+                       for (i=0; i<tlv_length/2; i++)
+                           proto_tree_add_text(tlv, tvb, offset+4+j+i*2, 2, "OF-Code #%d: %s (%u)",
+                                               i+1, val_to_str(tvb_get_ntohs(tvb, offset+4+j+i), pcep_of_vals, "Unknown"),
+                                               tvb_get_ntohs(tvb, offset+4+j+i*2));
+                       break;
+
+                   default:
+                       proto_tree_add_text(tlv, tvb, offset+4+j, tlv_length, "Data: %s", 
+                                       bytestring_to_str(tvb_get_ptr(tvb, (offset) + 4 + j, tlv_length), tlv_length, ' '));
+               }
+
                padding = (4 - (tlv_length % 4)) % 4;
                if (padding != 0){
                        proto_tree_add_text(tlv, tvb, offset+4+j+tlv_length, padding, "Padding: %s",
@@ -516,9 +678,6 @@ dissect_subobj_ipv4(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, int offset, int
        guint8 resvd;
        guint l;
 
-       prefix_length = tvb_get_guint8(tvb, offset+6);
-       resvd = tvb_get_guint8(tvb, offset+7);
-
        ti = proto_tree_add_item(pcep_subobj_tree, pcep_filter[PCEPF_SUBOBJ_IPv4], tvb, offset, length, FALSE);
        pcep_subobj_ipv4 = proto_item_add_subtree(ti, ett_pcep_obj);
 
@@ -528,6 +687,11 @@ dissect_subobj_ipv4(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, int offset, int
                return;
        }
 
+       prefix_length = tvb_get_guint8(tvb, offset+6);
+       resvd = tvb_get_guint8(tvb, offset+7);
+       proto_item_append_text(ti, ": %s/%u", tvb_ip_to_str(tvb, offset+2),
+                              prefix_length);
+
        switch(obj_class){
 
        case PCEP_EXPLICIT_ROUTE_OBJ:
@@ -535,7 +699,7 @@ dissect_subobj_ipv4(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, int offset, int
                proto_tree_add_text(pcep_subobj_ipv4, tvb, offset, 1,  "%s",val_to_str(l, pcep_route_l_obj_vals, "Unknown Object (%u). "));
                proto_tree_add_uint(pcep_subobj_ipv4, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, (l_and_or_type & 0x7f));
                proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+1, 1, "Length: %u", length);
-               proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+2, 4, "IPv4 Address: (%s)", tvb_ip_to_str(tvb, offset+2));
+               proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+2, 4, "IPv4 Address: %s", tvb_ip_to_str(tvb, offset+2));
                proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+6, 1, "Prefix Length: %u", prefix_length);
                proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+7, 1, "Padding: 0x%02x", resvd);
                break;
@@ -543,7 +707,7 @@ dissect_subobj_ipv4(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, int offset, int
        case PCEP_RECORD_ROUTE_OBJ:
                proto_tree_add_uint(pcep_subobj_ipv4, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, l_and_or_type);
                proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+1, 1, "Length: %u", length);
-               proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+2, 4, "IPv4 Address: (%s)", tvb_ip_to_str(tvb, offset+2));
+               proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+2, 4, "IPv4 Address: %s", tvb_ip_to_str(tvb, offset+2));
                proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+6, 1, "Prefix Length: %u", prefix_length);
                ti = proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+7, 1, "Flags: 0x%02x ", resvd);
                pcep_subobj_ipv4_flags = proto_item_add_subtree(ti, ett_pcep_obj);
@@ -555,7 +719,7 @@ dissect_subobj_ipv4(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, int offset, int
                proto_tree_add_text(pcep_subobj_ipv4, tvb, offset, 1, "l: %x", (l_and_or_type & 0x80)>>7);
                proto_tree_add_uint(pcep_subobj_ipv4, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, (l_and_or_type & 0x7f));
                proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+1, 1, "Length: %u", length);
-               proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+2, 4, "IPv4 Address: (%s)", tvb_ip_to_str(tvb, offset+2));
+               proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+2, 4, "IPv4 Address: %s", tvb_ip_to_str(tvb, offset+2));
                proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+6, 1, "Prefix Length: %u", prefix_length);
                proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+7, 1, "Padding: 0x%02x", resvd);
                break;
@@ -565,9 +729,9 @@ dissect_subobj_ipv4(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, int offset, int
                proto_tree_add_uint(pcep_subobj_ipv4, pcep_filter[PCEPF_SUBOBJ_XRO], tvb, offset, 1, (l_and_or_type & 0x7f));
                proto_tree_add_text(pcep_subobj_ipv4, tvb, offset, 1, "Type: %u", (l_and_or_type & 0x7f));
                proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+1, 1, "Length: %u", length);
-               proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+2, 4, "IPv4 Address: (%s)", tvb_ip_to_str(tvb, offset+2));
+               proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+2, 4, "IPv4 Address: %s", tvb_ip_to_str(tvb, offset+2));
                proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+6, 1, "Prefix Length: %u", prefix_length);
-               proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+7, 1,  "%s",val_to_str(resvd, pcep_xro_attribute_obj_vals, "Unknown Attribute (%u). "));
+               proto_tree_add_text(pcep_subobj_ipv4, tvb, offset+7, 1,  "Attribute: %s (%u)",val_to_str(resvd, pcep_xro_attribute_obj_vals, "Unknown"), resvd);
                break;
 
        default:
@@ -586,8 +750,6 @@ dissect_subobj_ipv6(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, int offset, int
        guint8 resv;
        int l;
 
-       prefix_length = tvb_get_guint8(tvb, offset+18);
-       resv = tvb_get_guint8(tvb, offset+19);
        ti = proto_tree_add_item(pcep_subobj_tree, pcep_filter[PCEPF_SUBOBJ_IPv6], tvb, offset, length, FALSE);
        pcep_subobj_ipv6 = proto_item_add_subtree(ti, ett_pcep_obj);
 
@@ -597,6 +759,11 @@ dissect_subobj_ipv6(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, int offset, int
                return;
        }
 
+       prefix_length = tvb_get_guint8(tvb, offset+18);
+       resv = tvb_get_guint8(tvb, offset+19);
+       proto_item_append_text(ti, ": %s/%u", tvb_ip6_to_str(tvb, offset+2),
+                              prefix_length);
+
        switch(obj_class){
        case PCEP_EXPLICIT_ROUTE_OBJ:
                l = (l_and_or_type& Mask_L)>>7;
@@ -634,7 +801,7 @@ dissect_subobj_ipv6(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, int offset, int
                proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+1, 1, "Length: %u", length);
                proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+2, 16, "IPv6 Address: %s", tvb_ip6_to_str(tvb, offset+2));
                proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+18, 1, "Prefix Length: %u", prefix_length);
-               proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+19, 1, "%s", val_to_str(resv, pcep_xro_attribute_obj_vals, "Unknown Attribute (%u). "));
+               proto_tree_add_text(pcep_subobj_ipv6, tvb, offset+19, 1, "Attribute: %s (%u)", val_to_str(resv, pcep_xro_attribute_obj_vals, "Unknown"), resv);
                break;
 
        default:
@@ -655,9 +822,6 @@ dissect_subobj_label_control(proto_tree *pcep_subobj_tree,  tvbuff_t *tvb,  int
        int l;
        int u;
 
-       u_reserved = tvb_get_guint8(tvb, offset+2);
-       c_type = tvb_get_guint8(tvb, offset+3);
-
        ti = proto_tree_add_item(pcep_subobj_tree, pcep_filter[PCEPF_SUBOBJ_LABEL_CONTROL], tvb, offset, length, FALSE);
        pcep_subobj_label_control = proto_item_add_subtree(ti, ett_pcep_obj);
 
@@ -667,6 +831,9 @@ dissect_subobj_label_control(proto_tree *pcep_subobj_tree,  tvbuff_t *tvb,  int
                return;
        }
 
+       u_reserved = tvb_get_guint8(tvb, offset+2);
+       c_type = tvb_get_guint8(tvb, offset+3);
+
        switch(obj_class){
 
        case PCEP_EXPLICIT_ROUTE_OBJ:
@@ -713,10 +880,6 @@ dissect_subobj_unnumb_interfaceID(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, i
        guint16 reserved_flags;
        int l;
 
-       reserved_flags = tvb_get_ntohs(tvb, offset+2);
-       router_ID = tvb_get_ntohl(tvb, offset+4);
-       interface_ID = tvb_get_ntohl(tvb, offset+8);
-
        ti = proto_tree_add_item(pcep_subobj_tree, pcep_filter[PCEPF_SUBOBJ_UNNUM_INTERFACEID], tvb, offset, length, FALSE);
        pcep_subobj_unnumb_interfaceID = proto_item_add_subtree(ti, ett_pcep_obj);
 
@@ -726,6 +889,12 @@ dissect_subobj_unnumb_interfaceID(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, i
                return;
        }
 
+       reserved_flags = tvb_get_ntohs(tvb, offset+2);
+       router_ID = tvb_get_ipv4(tvb, offset+4);
+       interface_ID = tvb_get_ntohl(tvb, offset+8);
+       proto_item_append_text(ti, ": %s:%u", ip_to_str ((guint8 *) &router_ID),
+                              interface_ID);
+
        switch(obj_class){
 
        case PCEP_EXPLICIT_ROUTE_OBJ:
@@ -759,7 +928,7 @@ dissect_subobj_unnumb_interfaceID(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, i
                proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset, 1, "X: %x", (l_and_or_type & 0x01)>>7);
                proto_tree_add_uint(pcep_subobj_unnumb_interfaceID, pcep_filter[PCEPF_SUBOBJ_XRO], tvb, offset, 1, (l_and_or_type & 0x7f));
                proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+2, 1, "Reserved: 0x%02x", (reserved_flags & 0xff00)>>4);
-               proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+3, 1, "%s", val_to_str((reserved_flags & 0x00ff), pcep_xro_attribute_obj_vals, "Unknown Attribute (%u). "));
+               proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+3, 1, "Attribute: %s (%u)", val_to_str(reserved_flags & 0x00ff, pcep_xro_attribute_obj_vals, "Unknown"), reserved_flags & 0x00ff);
                break;
 
        default:
@@ -767,8 +936,8 @@ dissect_subobj_unnumb_interfaceID(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, i
                break;
        }
 
-       proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+4, 4, "Router ID: 0x%08x", router_ID);
-       proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+8, 4, "Interface ID: 0x%08x", interface_ID);
+       proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+4, 4, "Router ID: %s", ip_to_str((guint8 *) &router_ID));
+       proto_tree_add_text(pcep_subobj_unnumb_interfaceID, tvb, offset+8, 4, "Interface ID: %d (0x%08x)", interface_ID, interface_ID);
 }
 
 static void
@@ -803,7 +972,7 @@ dissect_subobj_autonomous_sys_num(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, i
                proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset+1, 1, "Length: %u", length);
 
                proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset+2, 1, "Reserved: 0x%02x", reserved);
-               proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset+3, 1, "%s", val_to_str(attribute, pcep_xro_attribute_obj_vals, "Unknown Object (%u)."));
+               proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset+3, 1, "Attribute: %s (%u)", val_to_str(attribute, pcep_xro_attribute_obj_vals, "Unknown"), attribute);
                proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset+4, 2, "Optional AS Number High Octets: 0x%04x", AS_number);
                proto_tree_add_text(pcep_subobj_autonomous_sys_num, tvb, offset+6, 2, "AS Number: 0x%04x", AS_number);
        } else {
@@ -856,7 +1025,7 @@ dissect_subobj_srlg(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, int offset, gui
 
        proto_tree_add_text(pcep_subobj_srlg, tvb, offset+2, 4, "SRLG ID: 0x%08x", srlg_id);
        proto_tree_add_text(pcep_subobj_srlg, tvb, offset+6, 1, "Reserved: 0x%02x", reserved);
-       proto_tree_add_text(pcep_subobj_srlg, tvb, offset+7, 1, "%s", val_to_str(attribute, pcep_xro_attribute_obj_vals, "Unknown Object (%u)."));
+       proto_tree_add_text(pcep_subobj_srlg, tvb, offset+7, 1, "Attribute: %s (%u)", val_to_str(attribute, pcep_xro_attribute_obj_vals, "Unknown"), attribute);
 }
 
 static void
@@ -934,6 +1103,60 @@ dissect_subobj_exrs(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, int offset, int
        }
 }
 
+static void
+dissect_subobj_pksv4(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, int offset, gint ett_pcep_obj, guint l_and_or_type, guint length)
+{
+       proto_tree *pcep_subobj_pksv4;
+       proto_item *ti;
+       guint16 path_key;
+       int l;
+
+       ti = proto_tree_add_item(pcep_subobj_tree, pcep_filter[PCEPF_SUBOBJ_PKSv4], tvb, offset, length, FALSE);
+       pcep_subobj_pksv4 = proto_item_add_subtree(ti, ett_pcep_obj);
+
+       if (length != 8) {
+               proto_tree_add_text(pcep_subobj_pksv4, tvb, offset, length,
+                   "Bad path key subobject: length %u != 8", length);
+               return;
+       }
+
+       path_key = tvb_get_ntohs(tvb, offset+2);
+       proto_item_append_text(ti, ": %s, Path Key %u", tvb_ip_to_str(tvb, offset+4), path_key);
+       l = (l_and_or_type& Mask_L)>>7;
+       proto_tree_add_text(pcep_subobj_pksv4, tvb, offset, 1, "%s", val_to_str(l, pcep_route_l_obj_vals, "Unknown Object (%u). "));
+       proto_tree_add_uint(pcep_subobj_pksv4, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, (l_and_or_type & 0x7f));
+       proto_tree_add_text(pcep_subobj_pksv4, tvb, offset+1, 1, "Length: %u", length);
+       proto_tree_add_text(pcep_subobj_pksv4, tvb, offset+2, 2, "Path Key: %d (0x%04x)", path_key, path_key);
+       proto_tree_add_text(pcep_subobj_pksv4, tvb, offset+4, 4, "PCE ID: %s", tvb_ip_to_str(tvb, offset+4));
+}
+
+static void
+dissect_subobj_pksv6(proto_tree *pcep_subobj_tree, tvbuff_t *tvb, int offset, gint ett_pcep_obj, guint l_and_or_type, guint length)
+{
+       proto_tree *pcep_subobj_pksv6;
+       proto_item *ti;
+       guint16 path_key;
+       int l;
+
+       ti = proto_tree_add_item(pcep_subobj_tree, pcep_filter[PCEPF_SUBOBJ_PKSv6], tvb, offset, length, FALSE);
+       pcep_subobj_pksv6 = proto_item_add_subtree(ti, ett_pcep_obj);
+
+       if (length != 20) {
+               proto_tree_add_text(pcep_subobj_pksv6, tvb, offset, length,
+                   "Bad path key subobject: length %u != 20", length);
+               return;
+       }
+
+       path_key = tvb_get_ntohs(tvb, offset+2);
+       proto_item_append_text(ti, ": %s, Path Key %u", tvb_ip6_to_str(tvb, offset+4), path_key);
+       l = (l_and_or_type& Mask_L)>>7;
+       proto_tree_add_text(pcep_subobj_pksv6, tvb, offset, 1, "%s", val_to_str(l, pcep_route_l_obj_vals, "Unknown Object (%u). "));
+       proto_tree_add_uint(pcep_subobj_pksv6, pcep_filter[PCEPF_SUBOBJ], tvb, offset, 1, (l_and_or_type & 0x7f));
+       proto_tree_add_text(pcep_subobj_pksv6, tvb, offset+1, 1, "Length: %u", length);
+       proto_tree_add_text(pcep_subobj_pksv6, tvb, offset+2, 2, "Path Key: %d (0x%04x)", path_key, path_key);
+       proto_tree_add_text(pcep_subobj_pksv6, tvb, offset+4, 4, "PCE ID: %s", tvb_ip6_to_str(tvb, offset+4));
+}
+
 /*------------------------------------------------------------------------------
  * OPEN OBJECT
  *------------------------------------------------------------------------------*/
@@ -1008,6 +1231,14 @@ dissect_pcep_rp_obj(proto_tree *pcep_object_tree,
        pcep_rp_obj_flags = proto_item_add_subtree(ti, ett_pcep_obj_request_parameters);
 
        proto_tree_add_boolean(pcep_rp_obj_flags, pcep_rp_flags_reserved, tvb, offset2+1, 3, flags);
+       proto_tree_add_boolean(pcep_rp_obj_flags, pcep_rp_flags_f, tvb, offset2+1, 3, flags);
+       proto_tree_add_boolean(pcep_rp_obj_flags, pcep_rp_flags_n, tvb, offset2+1, 3, flags);
+       proto_tree_add_boolean(pcep_rp_obj_flags, pcep_rp_flags_e, tvb, offset2+1, 3, flags);
+       proto_tree_add_boolean(pcep_rp_obj_flags, pcep_rp_flags_m, tvb, offset2+1, 3, flags);
+       proto_tree_add_boolean(pcep_rp_obj_flags, pcep_rp_flags_d, tvb, offset2+1, 3, flags);
+       proto_tree_add_boolean(pcep_rp_obj_flags, pcep_rp_flags_p, tvb, offset2+1, 3, flags);
+       proto_tree_add_boolean(pcep_rp_obj_flags, pcep_rp_flags_s, tvb, offset2+1, 3, flags);
+       proto_tree_add_boolean(pcep_rp_obj_flags, pcep_rp_flags_v, tvb, offset2+1, 3, flags);
        proto_tree_add_boolean(pcep_rp_obj_flags, pcep_rp_flags_o, tvb, offset2+1, 3, flags);
        proto_tree_add_boolean(pcep_rp_obj_flags, pcep_rp_flags_b, tvb, offset2+1, 3, flags);
        proto_tree_add_boolean(pcep_rp_obj_flags, pcep_rp_flags_r, tvb, offset2+1, 3, flags);
@@ -1081,8 +1312,8 @@ dissect_pcep_end_point_obj(proto_tree *pcep_object_tree,
                        return;
                }
 
-               proto_tree_add_text(pcep_object_tree, tvb, offset2, 4, "Source IPv4 Address: (%s)", tvb_ip_to_str(tvb, offset2));
-               proto_tree_add_text(pcep_object_tree, tvb, offset2+4, 4, "Destination IPv4 Address: (%s)", tvb_ip_to_str(tvb, offset2+4));
+               proto_tree_add_text(pcep_object_tree, tvb, offset2, 4, "Source IPv4 Address: %s", tvb_ip_to_str(tvb, offset2));
+               proto_tree_add_text(pcep_object_tree, tvb, offset2+4, 4, "Destination IPv4 Address: %s", tvb_ip_to_str(tvb, offset2+4));
                break;
 
          case IPv6:
@@ -1115,7 +1346,7 @@ dissect_pcep_end_point_obj(proto_tree *pcep_object_tree,
 static void
 dissect_pcep_bandwidth_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, int obj_length)
 {
-       guint32 bandwidth;
+       gfloat bandwidth;
 
        if (obj_length != OBJ_HDR_LEN+BANDWIDTH_OBJ_LEN) {
                proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
@@ -1124,8 +1355,8 @@ dissect_pcep_bandwidth_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offs
                return;
        }
 
-       bandwidth = tvb_get_ntohl(tvb, offset2);
-       proto_tree_add_text(pcep_object_tree, tvb, offset2, 4, "Bandwidth: 0x%x", bandwidth);
+       bandwidth = tvb_get_ntohieee_float(tvb, offset2);
+       proto_tree_add_text(pcep_object_tree, tvb, offset2, 4, "Bandwidth: %f", bandwidth);
 }
 
 /*------------------------------------------------------------------------------
@@ -1133,7 +1364,7 @@ dissect_pcep_bandwidth_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offs
  *------------------------------------------------------------------------------*/
 #define METRIC_OBJ_LEN 8
 
-static void
+static void 
 dissect_pcep_metric_obj(proto_tree *pcep_object_tree,
                  tvbuff_t *tvb, int offset2, int obj_length)
 {
@@ -1142,7 +1373,7 @@ dissect_pcep_metric_obj(proto_tree *pcep_object_tree,
        guint16 reserved;
        guint8 flags;
        guint8 metric_type;
-       guint32 metric_value;
+       gfloat metric_value;
 
        if (obj_length != OBJ_HDR_LEN+METRIC_OBJ_LEN) {
                proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
@@ -1161,10 +1392,10 @@ dissect_pcep_metric_obj(proto_tree *pcep_object_tree,
        proto_tree_add_boolean(pcep_metric_obj_flags, pcep_metric_flags_b, tvb, offset2+2, 1, flags);
 
        metric_type = tvb_get_guint8(tvb, offset2+3);
-       proto_tree_add_text(pcep_object_tree, tvb, offset2+3, 1, "%s", val_to_str(metric_type, pcep_metric_obj_vals, "Unknown Object (%u). "));
+       proto_tree_add_text(pcep_object_tree, tvb, offset2+3, 1, "Type: %s (T=%u)", val_to_str(metric_type, pcep_metric_obj_vals, "Unknown"), metric_type);
 
-       metric_value = tvb_get_ntohl(tvb, offset2+4);
-       proto_tree_add_text(pcep_object_tree, tvb, offset2+4, 4, "Metric Value: 0x%x", metric_value);
+       metric_value = tvb_get_ntohieee_float(tvb, offset2+4);
+       proto_tree_add_text(pcep_object_tree, tvb, offset2+4, 4, "Metric Value: %f", metric_value);
 }
 
 /*------------------------------------------------------------------------------
@@ -1223,6 +1454,9 @@ dissect_pcep_explicit_route_obj(proto_tree *pcep_object_tree,
                case PCEP_SUB_AUTONOMOUS_SYS_NUM:
                        dissect_subobj_autonomous_sys_num(pcep_object_tree, tvb, offset2, obj_class, ett_pcep_obj_explicit_route, l_type, length);
                        break;
+               case PCEP_SUB_PKSv4:
+                       dissect_subobj_pksv4(pcep_object_tree, tvb, offset2, ett_pcep_obj_explicit_route, l_type, length);
+                       break;
                default:
                        proto_tree_add_text(pcep_object_tree, tvb, offset2, length, "Non defined subobject (%d)", type_exp_route);
                        break;
@@ -1512,12 +1746,12 @@ dissect_pcep_notification_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int o
 static void
 dissect_pcep_error_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, int obj_length)
 {
-       proto_tree *pcep_error_types_obj;
-       proto_item *ti;
        guint8 reserved;
        guint8 flags;
        guint8 error_type;
        guint8 error_value;
+       const gchar *err_str;
+       const gchar *default_str = "Unassigned";
 
        if (obj_length < OBJ_HDR_LEN+ERROR_OBJ_MIN_LEN) {
                proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
@@ -1533,118 +1767,61 @@ dissect_pcep_error_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2,
        proto_tree_add_text(pcep_object_tree, tvb, offset2+1, 1, "Flags: 0x%02x", flags);
 
        error_type = tvb_get_guint8(tvb, offset2+2);
-       ti = proto_tree_add_uint(pcep_object_tree, pcep_filter[PCEPF_ERROR_TYPE], tvb, offset2+2, 1, error_type);
-       pcep_error_types_obj = proto_item_add_subtree(ti, ett_pcep_obj_error);
-
        error_value = tvb_get_guint8(tvb, offset2+3);
-       switch(error_type){
+       proto_tree_add_uint(pcep_object_tree, pcep_filter[PCEPF_ERROR_TYPE], tvb, offset2+2, 1, error_type);
+
+       err_str = default_str;
+       switch (error_type){
        case ESTABLISH_FAILURE:
-               switch(error_value){
-               case RX_MALFORM_PKT:
-                       proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Reception of a Malformed Message ", error_value);
-                       break;
-               case NO_OPEN_MSG:
-                       proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u No Open Message received before the expiration of the OpenWait Timer ", error_value);
-                       break;
-               case UNACEP_NO_NEGO_SSESION:
-                       proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Unacceptable and non Negotiable session characteristics", error_value);
-                       break;
-               case UNACEP_NEG_SESSION:
-                       proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Unacceptable but Negotiable session characteristics", error_value);
-                       break;
-               case TWO_OPEN_MSG_UNACEP:
-                       proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Reception of a second Open Message with still Unacceptable Session characteristics", error_value);
-                       break;
-               case RX_PCEPERR_UNACEP_SESSION:
-                       proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Reception of a PCEPrr message proposing unacceptable session characteristics", error_value);
-                       break;
-               case NO_KEEPALIVE_PCEPERR:
-                       proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u NO Keepalive or PCEPrr message received before the expiration of the Keepwait timer supported", error_value);
-                       break;
-               default:
-                       proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1,
-                               "Error-value: %u Non defined Error-Value", error_value);
-               }
+               err_str = val_to_str(error_value, pcep_error_value_1_vals, "Unknown");
                break;
-
        case CAP_NOT_SUPPORTED:
-               proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-Value: %u ", error_value);
                break;
-
        case UNKNOWN_OBJ:
-               switch(error_value){
-               case UNRECON_OBJ_CLASS:
-                       proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Unrecognized object class", error_value);
-                       break;
-               case UNRECON_OBJ_TYPE:
-                       proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Unrecognized object type", error_value);
-                       break;
-               default:
-                       proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1,
-                               "Error-value: %u Non defined Error-Value", error_value);
-               }
+               err_str = val_to_str(error_value, pcep_error_value_3_vals, "Unknown");
                break;
        case NOT_SUPP_OBJ:
-               switch(error_value){
-               case NO_SUPP_OBJ:
-                       proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Not Supported Object Class", error_value);
-                       break;
-               case NO_SUPP_TYPE:
-                       proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u Not Supported Object Type", error_value);
-                       break;
-               default:
-                       proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1,
-                               "Error-value: %u Non defined Error-Value", error_value);
-               }
+               err_str = val_to_str(error_value, pcep_error_value_4_vals, "Unknown");
                break;
        case POLICY_VIOLATION:
-               switch(error_value){
-               case C_METRIC_SET:
-                       proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u C bit of the METRIC object set (Request Rejected)", error_value);
-                       break;
-               case O_OBJ_SET:
-                       proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u O bit of the RP object set (Request Rejected)", error_value);
-                       break;
-               default:
-                       proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1,
-                               "Error-value: %u Non defined Error-Value", error_value);
-               }
+               err_str = val_to_str(error_value, pcep_error_value_5_vals, "Unknown");
                break;
        case MANDATORY_OBJ_MIS:
-               switch(error_value){
-               case RP_OBJ_MISS:
-                       proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u RP Object missing", error_value);
-                       break;
-               case RRO_OBJ_MISS:
-                       proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u RRO Object missing for a reoptimization request (R bit of the RP Object set) when bandwidth is not equal to 0", error_value);
-                       break;
-               case END_POINT_OBJ_MISS:
-                       proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-value: %u END-POINTS Objects missing", error_value);
-                       break;
-               default:
-                       proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1,
-                               "Error-value: %u Non defined Error-Value", error_value);
-               }
+               err_str = val_to_str(error_value, pcep_error_value_6_vals, "Unknown");
                break;
        case SYNCH_PCREQ_MIS:
-               proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-Value: %u ", error_value);
                break;
        case UNKNOWN_REQ_REF:
-               proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-Value: %u ", error_value);
                break;
        case ATTEMPT_2_SESSION:
-               proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-Value: %u ", error_value);
                break;
-       case UNRECO_IRO_SUBOBJ:
-               proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-Value: %u ", error_value);
+       case INVALID_OBJ:
+               err_str = val_to_str(error_value, pcep_error_value_10_vals, "Unknown");
                break;
        case UNRECO_EXRS_SUBOBJ:
-               proto_tree_add_text(pcep_error_types_obj, tvb, offset2+3, 1, "Error-Value: %u ", error_value);
                break;
-
+       case DIFFSERV_TE_ERROR:
+               err_str = val_to_str(error_value, pcep_error_value_12_vals, "Unknown");
+               break;
+       case BRPC_FAILURE:
+               err_str = val_to_str(error_value, pcep_error_value_13_vals, "Unknown");
+               break;
+       case GCO_ERROR:
+               err_str = val_to_str(error_value, pcep_error_value_15_vals, "Unknown");
+               break;
+       case P2MP_CAPABILITY_ERROR:
+               err_str = val_to_str(error_value, pcep_error_value_16_vals, "Unknown");
+               break;
+       case P2MP_END_POINTS_ERROR:
+               err_str = val_to_str(error_value, pcep_error_value_17_vals, "Unknown");
+               break;
+       case P2MP_FRAGMENT_ERROR:
+               err_str = val_to_str(error_value, pcep_error_value_18_vals, "Unknown");
+               break;
        default:
-               proto_tree_add_text(pcep_error_types_obj, tvb, offset2+2, 1, "Error-Type: %u Non defined Error-Value", error_type);
+               proto_tree_add_text(pcep_object_tree, tvb, offset2+2, 1, "Error-Type: %u Non defined Error-Value", error_type);
        }
+       proto_tree_add_text(pcep_object_tree, tvb, offset2+3, 1, "Error-Value: %s (%u)", err_str, error_value);
 
        /*it's suppose that obj_length is a a valid date. The object can have optional TLV(s)*/
        offset2 += ERROR_OBJ_MIN_LEN;
@@ -1712,7 +1889,7 @@ dissect_pcep_close_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2,
        proto_tree_add_text(pcep_object_tree, tvb, offset2+2, 1, "Flags: 0x%02x", flags);
 
        reason = tvb_get_guint8(tvb, offset2+3);
-       proto_tree_add_text(pcep_object_tree, tvb, offset2+3, 1, "%s", val_to_str(reason, pcep_close_reason_obj_vals, "Unknown Object (%u). "));
+       proto_tree_add_text(pcep_object_tree, tvb, offset2+3, 1, "Reason: %s (%u)", val_to_str(reason, pcep_close_reason_obj_vals, "Unknown"), reason);
 
        /*it's suppose that obj_length is a a valid date. The object can have optional TLV(s)*/
        offset2 += CLOSE_OBJ_MIN_LEN;
@@ -1721,8 +1898,60 @@ dissect_pcep_close_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2,
 }
 
 /*------------------------------------------------------------------------------
- * XRO OBJECT
+ * PATH-KEY OBJECT
  *------------------------------------------------------------------------------*/
+static void 
+dissect_pcep_path_key_obj(proto_tree *pcep_object_tree,
+                 tvbuff_t *tvb, int offset2, int obj_length)
+{
+       guint8 l_type;
+       guint8 length;
+       guint type_exp_route;
+       guint body_obj_len;
+
+       body_obj_len = obj_length - OBJ_HDR_LEN;
+
+       while(body_obj_len){
+               if (body_obj_len < 2) {
+                       proto_tree_add_text(pcep_object_tree, tvb, offset2, 0,
+                           "Bad PATH-KEY object: subobject goes past end of object");
+                       break;
+               }
+
+               l_type = tvb_get_guint8(tvb, offset2);
+               length = tvb_get_guint8(tvb, offset2+1);
+
+               if (length < 2) {
+                       proto_tree_add_text(pcep_object_tree, tvb, offset2, 0,
+                           "Bad PATH-KEY object: subobject length %u < 2",
+                           length);
+                       break;
+               }
+
+               type_exp_route = (l_type & Mask_Type);
+               if (body_obj_len <length) {
+                       proto_tree_add_text(pcep_object_tree, tvb, offset2, length,
+                           "Bad PATH-KEY object: subobject length %u > remaining length %u",
+                               length, body_obj_len);
+                       break;
+               }
+
+               switch(type_exp_route) {
+               case PCEP_SUB_PKSv4:
+                       dissect_subobj_pksv4(pcep_object_tree, tvb, offset2, ett_pcep_obj_explicit_route, l_type, length);
+                       break;
+               default:
+                       proto_tree_add_text(pcep_object_tree, tvb, offset2, length, "Non defined subobject (%d)", type_exp_route);
+                       break;
+               }
+               offset2 += length;
+               body_obj_len -= length;
+       }
+}
+
+/*------------------------------------------------------------------------------
+ * XRO OBJECT 
+ *------------------------------------------------------------------------------*/     
 #define XRO_OBJ_MIN_LEN        4
 
 static void
@@ -1799,6 +2028,12 @@ dissect_pcep_xro_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, i
                case PCEP_SUB_SRLG:
                        dissect_subobj_srlg(pcep_object_tree, tvb, offset2, ett_pcep_obj_xro, x_type, length);
                        break;
+               case PCEP_SUB_PKSv4:
+                       dissect_subobj_pksv4(pcep_object_tree, tvb, offset2, ett_pcep_obj_xro, x_type, length);
+                       break;
+               case PCEP_SUB_PKSv6:
+                       dissect_subobj_pksv6(pcep_object_tree, tvb, offset2, ett_pcep_obj_xro, x_type, length);
+                       break;
                default:
                        proto_tree_add_text(pcep_object_tree, tvb, offset2-4, length, "Non defined subobject (%d)", type_xro);
                        break;
@@ -1808,6 +2043,33 @@ dissect_pcep_xro_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, i
        }
 }
 
+/*------------------------------------------------------------------------------
+ * OF OBJECT
+ *------------------------------------------------------------------------------*/
+#define OF_OBJ_MIN_LEN 4
+
+static void 
+dissect_pcep_of_obj(proto_tree *pcep_object_tree, tvbuff_t *tvb, int offset2, int obj_length)
+{    
+       guint8 of_code;
+
+       if (obj_length < OBJ_HDR_LEN+OF_OBJ_MIN_LEN) {
+               proto_tree_add_text(pcep_object_tree, tvb, offset2, obj_length,
+                   "Bad OF object length %u, should be >= %u", obj_length,
+                   OBJ_HDR_LEN+OF_OBJ_MIN_LEN);
+               return;
+       }
+
+       of_code = tvb_get_ntohs(tvb, offset2);
+       proto_tree_add_text(pcep_object_tree, tvb, offset2, 2, "OF-Code: %s (%u)",
+                       val_to_str(of_code, pcep_of_vals, "Unknown"), of_code);
+
+       /*The object can have optional TLV(s)*/
+       offset2 += OPEN_OBJ_MIN_LEN;
+       obj_length -= OBJ_HDR_LEN+OF_OBJ_MIN_LEN;
+       dissect_pcep_tlvs(pcep_object_tree, tvb, offset2, obj_length, ett_pcep_obj_open);
+}
+
 /*------------------------------------------------------------------------------*/
 /* Dissect in Objects */
 /*------------------------------------------------------------------------------*/
@@ -1902,6 +2164,11 @@ dissect_pcep_obj_tree(proto_tree *pcep_tree, tvbuff_t *tvb, int len, int offset,
                pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_close);
                break;
 
+       case PCEP_PATH_KEY_OBJ:
+               pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_PATH_KEY], tvb, offset, -1, FALSE);
+               pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_path_key);
+               break;
+
        case PCEP_XRO_OBJ:
                pcep_object_item = proto_tree_add_item(pcep_tree, pcep_filter[PCEPF_OBJ_XRO], tvb, offset, -1, FALSE);
                pcep_object_tree = proto_item_add_subtree(pcep_object_item, ett_pcep_obj_xro);
@@ -1995,10 +2262,18 @@ dissect_pcep_obj_tree(proto_tree *pcep_tree, tvbuff_t *tvb, int len, int offset,
            dissect_pcep_close_obj(pcep_object_tree, tvb, offset+4, obj_length);
            break;
 
+       case PCEP_PATH_KEY_OBJ:
+           dissect_pcep_path_key_obj(pcep_object_tree, tvb, offset+4, obj_length);
+           break;
+
        case PCEP_XRO_OBJ:
            dissect_pcep_xro_obj(pcep_object_tree, tvb, offset+4, obj_length, obj_class);
            break;
 
+       case PCEP_OF_OBJ:
+           dissect_pcep_of_obj(pcep_object_tree, tvb, offset+4, obj_length);
+           break;
+
        default:
            proto_tree_add_text(pcep_object_tree, tvb, offset+4, obj_length-OBJ_HDR_LEN, "PCEP Object BODY non defined (%u)", type);
            break;
@@ -2172,16 +2447,40 @@ proto_register_pcep(void){
                 { "Reserved Flags", "pcep.rp.flags.reserved", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_RESERVED,
                NULL, HFILL }},
                {&pcep_rp_flags_pri,
-                { "Priority (PRI)", "pcep.rp.flags.pri", FT_BOOLEAN, 24, TFS(&tfs_on_off), PCEP_RP_PRI,
+                { "(PRI) Priority", "pcep.rp.flags.pri", FT_BOOLEAN, 24, TFS(&tfs_on_off), PCEP_RP_PRI,
                NULL, HFILL }},
                {&pcep_rp_flags_r,
-                { "Reoptimization (R)", "pcep.rp.flags.r", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_R,
+                { "(R) Reoptimization", "pcep.rp.flags.r", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_R,
                NULL, HFILL }},
                {&pcep_rp_flags_b,
-                { "Bi-directional (L)", "pcep.rp.flags.b", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_B,
+                { "(B) Bi-directional", "pcep.rp.flags.b", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_B,
                NULL, HFILL }},
                {&pcep_rp_flags_o,
-                { "Strict/Loose (L)", "pcep.rp.flags.o", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_O,
+                { "(L) Strict/Loose", "pcep.rp.flags.o", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_O,
+               NULL, HFILL }},
+               {&pcep_rp_flags_v,
+                { "(V) VSPT", "pcep.rp.flags.v", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_V,
+               NULL, HFILL }},
+               {&pcep_rp_flags_s,
+                { "(S) Supply OF on response", "pcep.rp.flags.s", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_S,
+               NULL, HFILL }},
+               {&pcep_rp_flags_p,
+                { "(P) Path Key", "pcep.rp.flags.p", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_P,
+               NULL, HFILL }},
+               {&pcep_rp_flags_d,
+                { "(D) Report the request order", "pcep.rp.flags.d", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_D,
+               NULL, HFILL }},
+               {&pcep_rp_flags_m,
+                { "(M) Make-before-break", "pcep.rp.flags.m", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_M,
+               NULL, HFILL }},
+               {&pcep_rp_flags_e,
+                { "(E) ERO-compression", "pcep.rp.flags.e", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_E,
+               NULL, HFILL }},
+               {&pcep_rp_flags_n,
+                { "(N) P2MP", "pcep.rp.flags.n", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_N,
+               NULL, HFILL }},
+               {&pcep_rp_flags_f,
+                { "(F) Fragmentation", "pcep.rp.flags.f", FT_BOOLEAN, 24, TFS(&tfs_set_notset), PCEP_RP_F,
                NULL, HFILL }},
                {&pcep_filter[PCEPF_OBJ_NO_PATH],
                 { "NO-PATH object", "pcep.obj.nopath", FT_NONE, BASE_NONE, NULL, 0x0,
@@ -2199,10 +2498,10 @@ proto_register_pcep(void){
                 { "METRIC object", "pcep.obj.metric", FT_NONE, BASE_NONE, NULL, 0x0,
                        NULL, HFILL }},
                {&pcep_metric_flags_c,
-                { "Cost (C)", "pcep.metric.flags.c", FT_BOOLEAN, 8, TFS(&tfs_set_notset), PCEP_METRIC_C,
+                { "(C) Cost", "pcep.metric.flags.c", FT_BOOLEAN, 8, TFS(&tfs_set_notset), PCEP_METRIC_C,
                NULL, HFILL }},
                {&pcep_metric_flags_b,
-                { "Bound (B)", "pcep.metric.flags.b", FT_BOOLEAN, 8, TFS(&tfs_set_notset), PCEP_METRIC_B,
+                { "(B) Bound", "pcep.metric.flags.b", FT_BOOLEAN, 8, TFS(&tfs_set_notset), PCEP_METRIC_B,
                NULL, HFILL }},
                {&pcep_filter[PCEPF_OBJ_EXPLICIT_ROUTE],
                 { "EXPLICIT ROUTE object (ERO)", "pcep.obj.ero", FT_NONE, BASE_NONE, NULL, 0x0,
@@ -2261,6 +2560,9 @@ proto_register_pcep(void){
                {&pcep_filter[PCEPF_OBJ_CLOSE],
                 { "CLOSE object", "pcep.obj.close", FT_NONE, BASE_NONE, NULL, 0x0,
                        NULL, HFILL }},
+               {&pcep_filter[PCEPF_OBJ_PATH_KEY],
+                { "PATH-KEY object", "pcep.obj.path_key", FT_NONE, BASE_NONE, NULL, 0x0,
+                       NULL, HFILL }},
                {&pcep_filter[PCEPF_OBJ_XRO],
                 { "EXCLUDE ROUTE object (XRO)", "pcep.obj.xro", FT_NONE, BASE_NONE, NULL, 0x0,
                        NULL, HFILL }},
@@ -2291,6 +2593,12 @@ proto_register_pcep(void){
                {&pcep_filter[PCEPF_SUBOBJ_EXRS],
                 { "SUBOBJECT: EXRS", "pcep.subobj.exrs", FT_NONE, BASE_NONE, NULL, 0x0,
                        NULL, HFILL }},
+               {&pcep_filter[PCEPF_SUBOBJ_PKSv4],
+                { "SUBOBJECT: Path Key (IPv4)", "pcep.subobj.path_key.ipv4", FT_NONE, BASE_NONE, NULL, 0x0,
+                       NULL, HFILL }},
+               {&pcep_filter[PCEPF_SUBOBJ_PKSv6],
+                { "SUBOBJECT: Path Key (IPv6)", "pcep.subobj.path_key.ipv6", FT_NONE, BASE_NONE, NULL, 0x0,
+                       NULL, HFILL }},
                {&pcep_filter[PCEPF_SUBOBJ_XRO],
                 { "Type", "pcep.subobj.label", FT_UINT32, BASE_DEC, VALS(pcep_subobj_xro_vals), 0x0,
                        NULL, HFILL }},