Browse Source

ospfd: Update Traffic Engineering support

These patches update original code to RFC3630 (OSPF-TE) and add support of
RFC5392 (Inter-AS v2) & RFC7471 (TE metric extensions) and partial support
of RFC6827 (ASON - GMPLS).

* ospfd/ospf_dump.[c,h]: Add new dump functions for Traffic Engineering
* ospfd/ospf_opaque.[c,h]: Add new TLV code points for RFC5392
* ospfd/ospf_packet.c: Update checking of OSPF_OPTION
* ospfd/ospf_vty.[c,h]: Update ospf_str2area_id
* ospfd/ospf_zebra.c: Add new function ospf_interface_link_params() to get
  Link Parameters information from the interface to populate Traffic
  Engineering metrics
* ospfd/ospfd.[c,h]: Update OSPF_OPTION flags (T -> MT and new DN)
* ospfd/ospf_te.[c,h]: Major modifications to update the code to new
  link parameters structure and new RFCs

Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
Olivier Dugeon 3 years ago
parent
commit
29a1401706
12 changed files with 1693 additions and 609 deletions
  1. 35 3
      ospfd/ospf_dump.c
  2. 4 0
      ospfd/ospf_dump.h
  3. 15 3
      ospfd/ospf_opaque.c
  4. 5 1
      ospfd/ospf_opaque.h
  5. 2 2
      ospfd/ospf_packet.c
  6. 1310 574
      ospfd/ospf_te.c
  7. 296 23
      ospfd/ospf_te.h
  8. 1 1
      ospfd/ospf_vty.c
  9. 1 0
      ospfd/ospf_vty.h
  10. 21 0
      ospfd/ospf_zebra.c
  11. 1 1
      ospfd/ospfd.c
  12. 2 1
      ospfd/ospfd.h

+ 35 - 3
ospfd/ospf_dump.c

@@ -133,6 +133,7 @@ unsigned long conf_debug_ospf_nsm = 0;
 unsigned long conf_debug_ospf_lsa = 0;
 unsigned long conf_debug_ospf_zebra = 0;
 unsigned long conf_debug_ospf_nssa = 0;
+unsigned long conf_debug_ospf_te = 0;
 
 /* Enable debug option variables -- valid only session. */
 unsigned long term_debug_ospf_packet[5] = {0, 0, 0, 0, 0};
@@ -142,7 +143,7 @@ unsigned long term_debug_ospf_nsm = 0;
 unsigned long term_debug_ospf_lsa = 0;
 unsigned long term_debug_ospf_zebra = 0;
 unsigned long term_debug_ospf_nssa = 0;
-
+unsigned long term_debug_ospf_te = 0;
 
 
 const char *
@@ -328,13 +329,14 @@ ospf_options_dump (u_char options)
 {
   static char buf[OSPF_OPTION_STR_MAXLEN];
 
-  snprintf (buf, OSPF_OPTION_STR_MAXLEN, "*|%s|%s|%s|%s|%s|%s|*",
+  snprintf (buf, OSPF_OPTION_STR_MAXLEN, "*|%s|%s|%s|%s|%s|%s|%s",
 	    (options & OSPF_OPTION_O) ? "O" : "-",
 	    (options & OSPF_OPTION_DC) ? "DC" : "-",
 	    (options & OSPF_OPTION_EA) ? "EA" : "-",
 	    (options & OSPF_OPTION_NP) ? "N/P" : "-",
 	    (options & OSPF_OPTION_MC) ? "MC" : "-",
-	    (options & OSPF_OPTION_E) ? "E" : "-");
+           (options & OSPF_OPTION_E) ? "E" : "-",
+           (options & OSPF_OPTION_MT) ? "M/T" : "-");
 
   return buf;
 }
@@ -1426,6 +1428,32 @@ DEFUN (no_debug_ospf_nssa,
   return CMD_SUCCESS;
 }
 
+DEFUN (debug_ospf_te,
+       debug_ospf_te_cmd,
+       "debug ospf te",
+       DEBUG_STR
+       OSPF_STR
+       "OSPF-TE information\n")
+{
+  if (vty->node == CONFIG_NODE)
+    CONF_DEBUG_ON (te, TE);
+  TERM_DEBUG_ON (te, TE);
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_debug_ospf_te,
+       no_debug_ospf_te_cmd,
+       "no debug ospf te",
+       NO_STR
+       DEBUG_STR
+       OSPF_STR
+       "OSPF-TE information\n")
+{
+  if (vty->node == CONFIG_NODE)
+    CONF_DEBUG_OFF (te, TE);
+  TERM_DEBUG_OFF (te, TE);
+  return CMD_SUCCESS;
+}
 
 DEFUN (show_debugging_ospf,
        show_debugging_ospf_cmd,
@@ -1673,6 +1701,7 @@ debug_init ()
   install_element (ENABLE_NODE, &debug_ospf_zebra_cmd);
   install_element (ENABLE_NODE, &debug_ospf_event_cmd);
   install_element (ENABLE_NODE, &debug_ospf_nssa_cmd);
+  install_element (ENABLE_NODE, &debug_ospf_te_cmd);
   install_element (ENABLE_NODE, &no_debug_ospf_packet_send_recv_detail_cmd);
   install_element (ENABLE_NODE, &no_debug_ospf_packet_send_recv_cmd);
   install_element (ENABLE_NODE, &no_debug_ospf_packet_all_cmd);
@@ -1686,6 +1715,7 @@ debug_init ()
   install_element (ENABLE_NODE, &no_debug_ospf_zebra_cmd);
   install_element (ENABLE_NODE, &no_debug_ospf_event_cmd);
   install_element (ENABLE_NODE, &no_debug_ospf_nssa_cmd);
+  install_element (ENABLE_NODE, &no_debug_ospf_te_cmd);
 
   install_element (CONFIG_NODE, &debug_ospf_packet_send_recv_detail_cmd);
   install_element (CONFIG_NODE, &debug_ospf_packet_send_recv_cmd);
@@ -1700,6 +1730,7 @@ debug_init ()
   install_element (CONFIG_NODE, &debug_ospf_zebra_cmd);
   install_element (CONFIG_NODE, &debug_ospf_event_cmd);
   install_element (CONFIG_NODE, &debug_ospf_nssa_cmd);
+  install_element (CONFIG_NODE, &debug_ospf_te_cmd);
   install_element (CONFIG_NODE, &no_debug_ospf_packet_send_recv_detail_cmd);
   install_element (CONFIG_NODE, &no_debug_ospf_packet_send_recv_cmd);
   install_element (CONFIG_NODE, &no_debug_ospf_packet_all_cmd);
@@ -1713,4 +1744,5 @@ debug_init ()
   install_element (CONFIG_NODE, &no_debug_ospf_zebra_cmd);
   install_element (CONFIG_NODE, &no_debug_ospf_event_cmd);
   install_element (CONFIG_NODE, &no_debug_ospf_nssa_cmd);
+  install_element (CONFIG_NODE, &no_debug_ospf_te_cmd);
 }

+ 4 - 0
ospfd/ospf_dump.h

@@ -57,6 +57,7 @@
 
 #define OSPF_DEBUG_EVENT        0x01
 #define OSPF_DEBUG_NSSA		0x02
+#define OSPF_DEBUG_TE          0x04
 
 /* Macro for setting debug option. */
 #define CONF_DEBUG_PACKET_ON(a, b)	    conf_debug_ospf_packet[a] |= (b)
@@ -98,6 +99,8 @@
 
 #define IS_DEBUG_OSPF_NSSA  IS_DEBUG_OSPF(nssa,NSSA)
 
+#define IS_DEBUG_OSPF_TE  IS_DEBUG_OSPF(te,TE)
+
 #define IS_CONF_DEBUG_OSPF_PACKET(a, b) \
 	(conf_debug_ospf_packet[a] & OSPF_DEBUG_ ## b)
 #define IS_CONF_DEBUG_OSPF(a, b) \
@@ -119,6 +122,7 @@ extern unsigned long term_debug_ospf_nsm;
 extern unsigned long term_debug_ospf_lsa;
 extern unsigned long term_debug_ospf_zebra;
 extern unsigned long term_debug_ospf_nssa;
+extern unsigned long term_debug_ospf_te;
 
 /* Message Strings. */
 extern char *ospf_lsa_type_str[];

+ 15 - 3
ospfd/ospf_opaque.c

@@ -213,6 +213,9 @@ ospf_opaque_type_name (u_char opaque_type)
     case OPAQUE_TYPE_GRACE_LSA:
       name = "Grace-LSA";
       break;
+    case OPAQUE_TYPE_INTER_AS_LSA:
+      name = "Inter-AS TE-v2 LSA";
+      break;
     default:
       if (OPAQUE_TYPE_RANGE_UNASSIGNED (opaque_type))
         name = "Unassigned";
@@ -1973,6 +1976,7 @@ ospf_opaque_lsa_refresh_schedule (struct ospf_lsa *lsa0)
   struct opaque_info_per_type *oipt;
   struct opaque_info_per_id *oipi;
   struct ospf_lsa *lsa;
+  struct ospf *top;
   int delay;
 
   if ((oipt = lookup_opaque_info_by_type (lsa0)) == NULL
@@ -2004,7 +2008,10 @@ ospf_opaque_lsa_refresh_schedule (struct ospf_lsa *lsa0)
       ospf_ls_retransmit_delete_nbr_area (lsa->area, lsa);
       break;
     case OSPF_OPAQUE_AS_LSA:
-      ospf_ls_retransmit_delete_nbr_as (lsa0->area->ospf, lsa);
+      top = ospf_lookup ();
+      if ((lsa0->area != NULL) && (lsa0->area->ospf != NULL))
+        top = lsa0->area->ospf;
+      ospf_ls_retransmit_delete_nbr_as (top, lsa);
       break;
     default:
       zlog_warn ("ospf_opaque_lsa_refresh_schedule: Unexpected LSA-type(%u)", lsa->data->type);
@@ -2049,6 +2056,9 @@ ospf_opaque_lsa_flush_schedule (struct ospf_lsa *lsa0)
   struct opaque_info_per_type *oipt;
   struct opaque_info_per_id *oipi;
   struct ospf_lsa *lsa;
+  struct ospf *top;
+
+  top = ospf_lookup ();
 
   if ((oipt = lookup_opaque_info_by_type (lsa0)) == NULL
   ||  (oipi = lookup_opaque_info_by_id (oipt, lsa0)) == NULL)
@@ -2072,7 +2082,9 @@ ospf_opaque_lsa_flush_schedule (struct ospf_lsa *lsa0)
       ospf_ls_retransmit_delete_nbr_area (lsa->area, lsa);
       break;
     case OSPF_OPAQUE_AS_LSA:
-      ospf_ls_retransmit_delete_nbr_as (lsa0->area->ospf, lsa);
+      if ((lsa0->area != NULL) && (lsa0->area->ospf != NULL))
+        top = lsa0->area->ospf;
+      ospf_ls_retransmit_delete_nbr_as (top, lsa);
       break;
     default:
       zlog_warn ("ospf_opaque_lsa_flush_schedule: Unexpected LSA-type(%u)", lsa->data->type);
@@ -2096,7 +2108,7 @@ ospf_opaque_lsa_flush_schedule (struct ospf_lsa *lsa0)
     zlog_debug ("Schedule Type-%u Opaque-LSA to FLUSH: [opaque-type=%u, opaque-id=%x]", lsa->data->type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)));
 
   /* This lsa will be flushed and removed eventually. */
-  ospf_lsa_flush (lsa0->area->ospf, lsa);
+  ospf_lsa_flush (top, lsa);
 
 out:
   return;

+ 5 - 1
ospfd/ospf_opaque.h

@@ -60,6 +60,10 @@
 #define OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA		1
 #define OPAQUE_TYPE_SYCAMORE_OPTICAL_TOPOLOGY_DESC	2
 #define OPAQUE_TYPE_GRACE_LSA				3
+#define OPAQUE_TYPE_L1VPN_LSA                          5
+#define OPAQUE_TYPE_ROUTER_INFORMATION_LSA             4
+#define OPAQUE_TYPE_INTER_AS_LSA                       6
+#define OPAQUE_TYPE_MAX                                6
 
 /* Followings types are proposed in internet-draft documents. */
 #define OPAQUE_TYPE_8021_QOSPF				129
@@ -70,7 +74,7 @@
 #define OPAQUE_TYPE_WILDCARD				0
 
 #define OPAQUE_TYPE_RANGE_UNASSIGNED(type) \
-	(  4 <= (type) && (type) <= 127)
+	( OPAQUE_TYPE_MAX  <= (type) && (type) <= 127)
 
 #define OPAQUE_TYPE_RANGE_RESERVED(type) \
 	(127 <  (type) && (type) <= 255)

+ 2 - 2
ospfd/ospf_packet.c

@@ -882,7 +882,7 @@ ospf_hello (struct ip *iph, struct ospf_header *ospfh,
   /* Compare options. */
 #define REJECT_IF_TBIT_ON	1 /* XXX */
 #ifdef REJECT_IF_TBIT_ON
-  if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
+  if (CHECK_FLAG (hello->options, OSPF_OPTION_MT))
     {
       /*
        * This router does not support non-zero TOS.
@@ -1231,7 +1231,7 @@ ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
     }
 
 #ifdef REJECT_IF_TBIT_ON
-  if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
+  if (CHECK_FLAG (dd->options, OSPF_OPTION_MT))
     {
       /*
        * In Hello protocol, optional capability must have checked

File diff suppressed because it is too large
+ 1310 - 574
ospfd/ospf_te.c


+ 296 - 23
ospfd/ospf_te.h

@@ -1,8 +1,11 @@
 /*
- * This is an implementation of draft-katz-yeung-ospf-traffic-06.txt
+ * This is an implementation of RFC3630, RFC5392 & RFC6827
  * Copyright (C) 2001 KDD R&D Laboratories, Inc.
  * http://www.kddlabs.co.jp/
  *
+ * Copyright (C) 2012 Orange Labs
+ * http://www.orange.com
+ *
  * This file is part of GNU Zebra.
  *
  * GNU Zebra is free software; you can redistribute it and/or modify it
@@ -21,6 +24,10 @@
  * 02111-1307, USA.
  */
 
+/* Add support of RFC7471 */
+/* Add support of RFC5392 */
+/* Add support of RFC6827 (partial) */
+
 #ifndef _ZEBRA_OSPF_MPLS_TE_H
 #define _ZEBRA_OSPF_MPLS_TE_H
 
@@ -42,6 +49,7 @@
  */
 
 #define	MAX_LEGAL_TE_INSTANCE_NUM (0xffff)
+#define LEGAL_TE_INSTANCE_RANGE(i)  (0 <= (i) && (i) <= 0xffff)
 
 /*
  *        24       16        8        0
@@ -62,6 +70,31 @@
  * +--------+--------+--------+--------+ ---
  */
 
+/* Following define the type of TE link regarding the various RFC */
+#define STD_TE  	0x01
+#define GMPLS   	0x02
+#define INTER_AS	0x04
+#define PSEUDO_TE	0x08
+#define FLOOD_AREA	0x10
+#define FLOOD_AS	0x20
+#define EMULATED	0x80
+
+#define IS_STD_TE(x)	        (x & STD_TE)
+#define IS_PSEUDO_TE(x)		(x & PSEUDO_TE)
+#define IS_INTER_AS(x) 		(x & INTER_AS)
+#define IS_EMULATED(x)		(x & EMULATED)
+#define IS_FLOOD_AREA(x)	(x & FLOOD_AREA)
+#define IS_FLOOD_AS(x)		(x & FLOOD_AS)
+#define IS_INTER_AS_EMU(x) 	(x & INTER_AS & EMULATED)
+#define IS_INTER_AS_AS(x)	(x & INTER_AS & FLOOD_AS)
+
+/* Flags to manage TE Link LSA */
+#define LPFLG_LSA_INACTIVE		0x0
+#define LPFLG_LSA_ACTIVE		0x1
+#define LPFLG_LSA_ENGAGED		0x2
+#define LPFLG_LOOKUP_DONE		0x4
+#define LPFLG_LSA_FORCED_REFRESH	0x8
+
 /*
  * Following section defines TLV (tag, length, value) structures,
  * used for Traffic Engineering.
@@ -87,10 +120,18 @@ struct te_tlv_header
 #define TLV_HDR_NEXT(tlvh) \
 	(struct te_tlv_header *)((char *)(tlvh) + TLV_SIZE(tlvh))
 
+#define TLV_HDR_SUBTLV(tlvh) \
+	(struct te_tlv_header *)((char *)(tlvh) + TLV_HDR_SIZE)
+
+#define TLV_TYPE(tlvh)     tlvh.header.type
+#define TLV_LEN(tlvh)      tlvh.header.length
+#define TLV_HDR(tlvh)      tlvh.header
+
+
 /*
  * Following section defines TLV body parts.
  */
-/* Router Address TLV *//* Mandatory */
+/* Router Address TLV */ /* Mandatory */
 #define	TE_TLV_ROUTER_ADDR		1
 struct te_tlv_router_addr
 {
@@ -106,12 +147,16 @@ struct te_tlv_link
   /* A set of link-sub-TLVs will follow. */
 };
 
-/* Link Type Sub-TLV *//* Mandatory */
-#define	TE_LINK_SUBTLV_LINK_TYPE		1
+#define TE_LINK_SUBTLV_DEF_SIZE		4
+
+/* Link Type Sub-TLV */ /* Mandatory */
+#define	TE_LINK_SUBTLV_LINK_TYPE	1
+#define TE_LINK_SUBTLV_TYPE_SIZE	1
 struct te_link_subtlv_link_type
 {
   struct te_tlv_header	header;		/* Value length is 1 octet. */
-  struct {
+  struct
+  {
 #define	LINK_TYPE_SUBTLV_VALUE_PTP	1
 #define	LINK_TYPE_SUBTLV_VALUE_MA	2
       u_char	value;
@@ -119,75 +164,303 @@ struct te_link_subtlv_link_type
   } link_type;
 };
 
-/* Link Sub-TLV: Link ID *//* Mandatory */
-#define	TE_LINK_SUBTLV_LINK_ID			2
+/* Link Sub-TLV: Link ID */ /* Mandatory */
+#define	TE_LINK_SUBTLV_LINK_ID		2
 struct te_link_subtlv_link_id
 {
   struct te_tlv_header	header;		/* Value length is 4 octets. */
   struct in_addr	value;		/* Same as router-lsa's link-id. */
 };
 
-/* Link Sub-TLV: Local Interface IP Address *//* Optional */
-#define	TE_LINK_SUBTLV_LCLIF_IPADDR		3
+/* Link Sub-TLV: Local Interface IP Address */ /* Optional */
+#define	TE_LINK_SUBTLV_LCLIF_IPADDR	3
 struct te_link_subtlv_lclif_ipaddr
 {
   struct te_tlv_header	header;		/* Value length is 4 x N octets. */
   struct in_addr	value[1];	/* Local IP address(es). */
 };
 
-/* Link Sub-TLV: Remote Interface IP Address *//* Optional */
-#define	TE_LINK_SUBTLV_RMTIF_IPADDR		4
+/* Link Sub-TLV: Remote Interface IP Address */ /* Optional */
+#define	TE_LINK_SUBTLV_RMTIF_IPADDR	4
 struct te_link_subtlv_rmtif_ipaddr
 {
   struct te_tlv_header	header;		/* Value length is 4 x N octets. */
   struct in_addr	value[1];	/* Neighbor's IP address(es). */
 };
 
-/* Link Sub-TLV: Traffic Engineering Metric *//* Optional */
-#define	TE_LINK_SUBTLV_TE_METRIC		5
+/* Link Sub-TLV: Traffic Engineering Metric */ /* Optional */
+#define	TE_LINK_SUBTLV_TE_METRIC	5
 struct te_link_subtlv_te_metric
 {
   struct te_tlv_header	header;		/* Value length is 4 octets. */
   u_int32_t		value;		/* Link metric for TE purpose. */
 };
 
-/* Link Sub-TLV: Maximum Bandwidth *//* Optional */
-#define	TE_LINK_SUBTLV_MAX_BW			6
+/* Link Sub-TLV: Maximum Bandwidth */ /* Optional */
+#define	TE_LINK_SUBTLV_MAX_BW		6
 struct te_link_subtlv_max_bw
 {
   struct te_tlv_header	header;		/* Value length is 4 octets. */
   float			value;		/* bytes/sec */
 };
 
-/* Link Sub-TLV: Maximum Reservable Bandwidth *//* Optional */
-#define	TE_LINK_SUBTLV_MAX_RSV_BW		7
+/* Link Sub-TLV: Maximum Reservable Bandwidth */ /* Optional */
+#define	TE_LINK_SUBTLV_MAX_RSV_BW	7
 struct te_link_subtlv_max_rsv_bw
 {
   struct te_tlv_header	header;		/* Value length is 4 octets. */
   float			value;		/* bytes/sec */
 };
 
-/* Link Sub-TLV: Unreserved Bandwidth *//* Optional */
-#define	TE_LINK_SUBTLV_UNRSV_BW			8
+/* Link Sub-TLV: Unreserved Bandwidth */ /* Optional */
+#define	TE_LINK_SUBTLV_UNRSV_BW		8
+#define TE_LINK_SUBTLV_UNRSV_SIZE	32
 struct te_link_subtlv_unrsv_bw
 {
   struct te_tlv_header	header;		/* Value length is 32 octets. */
-  float			value[8];	/* One for each priority level. */
+  float			value[MAX_CLASS_TYPE];	/* One for each priority level. */
 };
 
-/* Link Sub-TLV: Resource Class/Color *//* Optional */
-#define	TE_LINK_SUBTLV_RSC_CLSCLR		9
+/* Link Sub-TLV: Resource Class/Color */ /* Optional */
+#define	TE_LINK_SUBTLV_RSC_CLSCLR	9
 struct te_link_subtlv_rsc_clsclr
 {
   struct te_tlv_header	header;		/* Value length is 4 octets. */
   u_int32_t		value;		/* Admin. group membership. */
 };
 
-/* Here are "non-official" architechtual constants. */
+/* For RFC6827 */
+/* Local and Remote TE Router ID */
+#define TE_LINK_SUBTLV_LRRID		10
+#define TE_LINK_SUBTLV_LRRID_SIZE	8
+struct te_link_subtlv_lrrid
+{
+  struct te_tlv_header header;  /* Value length is 8 octets. */
+  struct in_addr local;         /* Local TE Router Identifier */
+  struct in_addr remote;        /* Remote TE Router Identifier */
+};
+
+/* RFC4203: Link Local/Remote Identifiers */
+#define TE_LINK_SUBTLV_LLRI		11
+#define TE_LINK_SUBTLV_LLRI_SIZE	8
+struct te_link_subtlv_llri
+{
+  struct te_tlv_header header;  /* Value length is 8 octets. */
+  u_int32_t local;              /* Link Local Identifier */
+  u_int32_t remote;             /* Link Remote Identifier */
+};
+
+/* Inter-RA Export Upward sub-TLV (12) and Inter-RA Export Downward sub-TLV (13) (RFC6827bis) are not yet supported */
+/* SUBTLV 14-16 (RFC4203) are not yet supported */
+/* Bandwidth Constraints sub-TLV (17) (RFC4124) is not yet supported */
+/* SUBLV 18-20 are for OSPFv6 TE (RFC5329). see ospf6d */
+
+/* For RFC 5392 */
+/* Remote AS Number sub-TLV */
+#define TE_LINK_SUBTLV_RAS		21
+struct te_link_subtlv_ras
+{
+  struct te_tlv_header header;  /* Value length is 4 octets. */
+  u_int32_t value;              /* Remote AS number */
+};
+
+/* IPv4 Remote ASBR ID Sub-TLV */
+#define TE_LINK_SUBTLV_RIP		22
+struct te_link_subtlv_rip
+{
+  struct te_tlv_header header;  /* Value length is 4 octets. */
+  struct in_addr value;         /* Remote ASBR IP address */
+};
+
+/* SUBTLV 24 is IPv6 Remote ASBR ID (RFC5392). see ospf6d */
+
+/* SUBTLV 23 (RFC5330) and 25 (RFC6001) are not yet supported */
+
+/* SUBTLV 26 (RFC7308) is not yet supported */
+
+/* RFC7471 */
+/* Link Sub-TLV: Average Link Delay */ /* Optional */
+#define TE_LINK_SUBTLV_AV_DELAY		27
+struct te_link_subtlv_av_delay
+{
+  struct te_tlv_header header;  /* Value length is 4 bytes. */
+  u_int32_t            value;   /* delay in micro-seconds only 24 bits => 0 ... 16777215
+                                   with Anomalous Bit as Upper most bit */
+};
+
+/* Link Sub-TLV: Low/High Link Delay */
+#define TE_LINK_SUBTLV_MM_DELAY         28
+#define TE_LINK_SUBTLV_MM_DELAY_SIZE    8
+struct te_link_subtlv_mm_delay
+{
+  struct te_tlv_header header;  /* Value length is 8 bytes. */
+  u_int32_t            low;     /* low delay in micro-seconds only 24 bits => 0 ... 16777215
+                                   with Anomalous Bit (A) as Upper most bit */
+  u_int32_t            high;    /* high delay in micro-seconds only 24 bits => 0 ... 16777215 */
+};
+
+/* Link Sub-TLV: Link Delay Variation i.e. Jitter */
+#define TE_LINK_SUBTLV_DELAY_VAR	29
+struct te_link_subtlv_delay_var
+{
+  struct te_tlv_header header;  /* Value length is 4 bytes. */
+  u_int32_t            value;   /* interval in micro-seconds only 24 bits => 0 ... 16777215 */
+};
+
+/* Link Sub-TLV: Routine Unidirectional Link Packet Loss */
+#define TE_LINK_SUBTLV_PKT_LOSS		30
+struct te_link_subtlv_pkt_loss
+{
+  struct te_tlv_header header;  /* Value length is 4 bytes. */
+  u_int32_t            value;   /* in percentage of total traffic only 24 bits (2^24 - 2)
+                                   with Anomalous Bit as Upper most bit */
+};
+
+/* Link Sub-TLV: Unidirectional Residual Bandwidth */ /* Optional */
+#define TE_LINK_SUBTLV_RES_BW		31
+struct te_link_subtlv_res_bw
+{
+  struct te_tlv_header header;  /* Value length is 4 bytes. */
+  float                value;   /* bandwidth in IEEE floating point format with units in bytes per second */
+};
+
+/* Link Sub-TLV: Unidirectional Available Bandwidth */ /* Optional */
+#define TE_LINK_SUBTLV_AVA_BW		32
+struct te_link_subtlv_ava_bw
+{
+  struct te_tlv_header header;  /* Value length is 4 octets. */
+  float                value;   /* bandwidth in IEEE floating point format with units in bytes per second */
+};
+
+/* Link Sub-TLV: Unidirectional Utilized Bandwidth */ /* Optional */
+#define TE_LINK_SUBTLV_USE_BW           33
+struct te_link_subtlv_use_bw
+{
+  struct te_tlv_header header;  /* Value length is 4 octets. */
+  float                value;   /* bandwidth in IEEE floating point format with units in bytes per second */
+};
+
+#define TE_LINK_SUBTLV_MAX		34      /* Last SUBTLV + 1 */
+
+/* Here are "non-official" architectural constants. */
 #define MPLS_TE_MINIMUM_BANDWIDTH	1.0	/* Reasonable? *//* XXX */
 
+/* Following declaration concerns the MPLS-TE and LINk-TE management */
+typedef enum _opcode_t
+{ REORIGINATE_THIS_LSA, REFRESH_THIS_LSA, FLUSH_THIS_LSA } opcode_t;
+
+typedef enum _status_t
+{ disabled, enabled } status_t;
+
+/* Mode for Inter-AS Opaque-LSA */
+enum inter_as_mode { Disable, AS, Area };
+
+struct te_link_subtlv
+{
+  struct te_tlv_header header;
+  union
+  {
+    u_int32_t link_type;
+    struct in_addr link_id;
+    struct in_addr lclif;
+    struct in_addr rmtif;
+    u_int32_t te_metric;
+    float max_bw;
+    float max_rsv_bw;
+    float unrsv[8];
+    u_int32_t rsc_clsclr;
+    u_int32_t llri[2];
+    u_int32_t ras;
+    struct in_addr rip;
+    struct in_addr lrrid[2];
+    u_int32_t av_delay;
+    u_int32_t mm_delay;
+    u_int32_t delay_var;
+    u_int32_t pkt_loss;
+    float res_bw;
+    float ava_bw;
+    float use_bw;
+  } value;
+};
+
+/* Following structure are internal use only. */
+struct ospf_mpls_te
+{
+  /* Status of MPLS-TE: enable or disbale */
+  status_t status;
+
+  /* RFC5392 */
+  enum inter_as_mode inter_as;
+  struct in_addr interas_areaid;
+
+  /* List elements are zebra-interfaces (ifp), not ospf-interfaces (oi). */
+  struct list *iflist;
+
+  /* Store Router-TLV in network byte order. */
+  struct te_tlv_router_addr router_addr;
+};
+
+struct mpls_te_link
+{
+  /*
+   * According to MPLS-TE (draft) specification, 24-bit Opaque-ID field
+   * is subdivided into 8-bit "unused" field and 16-bit "instance" field.
+   * In this implementation, each Link-TLV has its own instance.
+   */
+  u_int32_t instance;
+
+  /* Reference pointer to a Zebra-interface. */
+  struct interface *ifp;
+
+  /* Area info in which this MPLS-TE link belongs to. */
+  struct ospf_area *area;
+
+  /* Flags to manage this link parameters. */
+  u_int32_t flags;
+
+  /* Type of MPLS-TE link: RFC3630, RFC5392, RFC5392 emulated, RFC6827 */
+  u_int8_t type;
+
+  /* Store Link-TLV in network byte order. */
+  /* RFC3630 & RFC6827 / RFC 6827 */
+  struct te_tlv_link link_header;
+  struct te_link_subtlv_link_type link_type;
+  struct te_link_subtlv_link_id link_id;
+  struct te_link_subtlv_lclif_ipaddr lclif_ipaddr;
+  struct te_link_subtlv_rmtif_ipaddr rmtif_ipaddr;
+  struct te_link_subtlv_te_metric te_metric;
+  struct te_link_subtlv_max_bw max_bw;
+  struct te_link_subtlv_max_rsv_bw max_rsv_bw;
+  struct te_link_subtlv_unrsv_bw unrsv_bw;
+  struct te_link_subtlv_rsc_clsclr rsc_clsclr;
+  /* RFC4203 */
+  struct te_link_subtlv_llri llri;
+  /* RFC5392 */
+  struct te_link_subtlv_ras ras;
+  struct te_link_subtlv_rip rip;
+  /* RFC6827 */
+  struct te_link_subtlv_lrrid lrrid;
+  /* RFC7471 */
+  struct te_link_subtlv_av_delay av_delay;
+  struct te_link_subtlv_mm_delay mm_delay;
+  struct te_link_subtlv_delay_var delay_var;
+  struct te_link_subtlv_pkt_loss pkt_loss;
+  struct te_link_subtlv_res_bw res_bw;
+  struct te_link_subtlv_ava_bw ava_bw;
+  struct te_link_subtlv_use_bw use_bw;
+
+  struct in_addr adv_router;
+  struct in_addr id;
+};
+
 /* Prototypes. */
 extern int ospf_mpls_te_init (void);
 extern void ospf_mpls_te_term (void);
+extern struct ospf_mpls_te *get_ospf_mpls_te (void);
+extern void ospf_mpls_te_update_if (struct interface *);
+extern void ospf_mpls_te_lsa_schedule (struct mpls_te_link *, opcode_t);
+extern u_int32_t get_mpls_te_instance_value (void);
+extern void set_linkparams_llri (struct mpls_te_link *, u_int32_t, u_int32_t);
+extern void set_linkparams_lrrid (struct mpls_te_link *, struct in_addr, struct in_addr);
 
 #endif /* _ZEBRA_OSPF_MPLS_TE_H */

+ 1 - 1
ospfd/ospf_vty.c

@@ -63,7 +63,7 @@ static const char *ospf_network_type_str[] =
 
 
 /* Utility functions. */
-static int
+int
 ospf_str2area_id (const char *str, struct in_addr *area_id, int *format)
 {
   char *endptr = NULL;

+ 1 - 0
ospfd/ospf_vty.h

@@ -53,5 +53,6 @@
 /* Prototypes. */
 extern void ospf_vty_init (void);
 extern void ospf_vty_show_init (void);
+extern int ospf_str2area_id (const char *, struct in_addr *, int *);
 
 #endif /* _QUAGGA_OSPF_VTY_H */

+ 21 - 0
ospfd/ospf_zebra.c

@@ -48,6 +48,7 @@
 #ifdef HAVE_SNMP
 #include "ospfd/ospf_snmp.h"
 #endif /* HAVE_SNMP */
+#include "ospfd/ospf_te.h"
 
 /* Zebra structure to hold current status. */
 struct zclient *zclient = NULL;
@@ -326,6 +327,24 @@ ospf_interface_address_delete (int command, struct zclient *zclient,
   return 0;
 }
 
+static int
+ospf_interface_link_params (int command, struct zclient *zclient,
+                        zebra_size_t length)
+{
+  struct interface *ifp;
+
+  ifp = zebra_interface_link_params_read (zclient->ibuf);
+
+  if (ifp == NULL)
+    return 0;
+
+  /* Update TE TLV */
+  ospf_mpls_te_update_if (ifp);
+
+  return 0;
+}
+
+
 void
 ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)
 {
@@ -1319,6 +1338,8 @@ ospf_zebra_init (struct thread_master *master)
   zclient->interface_down = ospf_interface_state_down;
   zclient->interface_address_add = ospf_interface_address_add;
   zclient->interface_address_delete = ospf_interface_address_delete;
+  zclient->interface_link_params = ospf_interface_link_params;
+
   zclient->ipv4_route_add = ospf_zebra_read_ipv4;
   zclient->ipv4_route_delete = ospf_zebra_read_ipv4;
 

+ 1 - 1
ospfd/ospfd.c

@@ -255,7 +255,7 @@ ospf_lookup ()
   if (listcount (om->ospf) == 0)
     return NULL;
 
-  return listgetdata (listhead (om->ospf));
+  return listgetdata ((struct listnode *)listhead (om->ospf));
 }
 
 static int

+ 2 - 1
ospfd/ospfd.h

@@ -59,13 +59,14 @@
 #define OSPF_AUTH_CMD_NOTSEEN              -2
 
 /* OSPF options. */
-#define OSPF_OPTION_T                    0x01  /* TOS. */
+#define OSPF_OPTION_MT                   0x01  /* M/T */
 #define OSPF_OPTION_E                    0x02
 #define OSPF_OPTION_MC                   0x04
 #define OSPF_OPTION_NP                   0x08
 #define OSPF_OPTION_EA                   0x10
 #define OSPF_OPTION_DC                   0x20
 #define OSPF_OPTION_O                    0x40
+#define OSPF_OPTION_DN                   0x80
 
 /* OSPF Database Description flags. */
 #define OSPF_DD_FLAG_MS                  0x01