This new structure is the basis to get new link parameters for
Traffic Engineering from Zebra/interface layer to OSPFD and ISISD
for the support of Traffic Engineering

* lib/if.[c,h]: link parameters struture and get/set functions
* lib/command.[c,h]: creation of a new link-node
* lib/zclient.[c,h]: modification to the ZBUS message to convey the
link parameters structure
* lib/zebra.h: New ZBUS message

Signed-off-by: Olivier Dugeon <[email protected]>
---
 lib/command.c |   8 ++++
 lib/command.h |   5 +++
 lib/if.c      |  42 ++++++++++++++++++++
 lib/if.h      |  64 +++++++++++++++++++++++++++++++
lib/zclient.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 lib/zclient.h |   4 ++
 lib/zebra.h   |   3 +-
 7 files changed, 244 insertions(+), 3 deletions(-)

diff --git a/lib/command.c b/lib/command.c
index 8089360..645865d 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -2602,8 +2602,12 @@ node_parent ( enum node_type node )
     case KEYCHAIN_KEY_NODE:
       ret = KEYCHAIN_NODE;
       break;
+    case LINK_PARAMS_NODE:
+      ret = INTERFACE_NODE;
+      break;
     default:
       ret = CONFIG_NODE;
+      break;
     }

   return ret;
@@ -2973,6 +2977,9 @@ DEFUN (config_exit,
     case KEYCHAIN_KEY_NODE:
       vty->node = KEYCHAIN_NODE;
       break;
+    case LINK_PARAMS_NODE:
+      vty->node = INTERFACE_NODE;
+      break;
     default:
       break;
     }
@@ -3022,6 +3029,7 @@ DEFUN (config_end,
     case MASC_NODE:
     case PIM_NODE:
     case VTY_NODE:
+    case LINK_PARAMS_NODE:
       vty_config_unlock (vty);
       vty->node = ENABLE_NODE;
       break;
diff --git a/lib/command.h b/lib/command.h
index 6a20e23..9a4d77c 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -108,6 +108,7 @@ enum node_type
   FORWARDING_NODE,        /* IP forwarding node. */
   PROTOCOL_NODE,                /* protocol filtering node */
   VTY_NODE,            /* Vty node. */
+  LINK_PARAMS_NODE,        /* Link-parameters node */
 };

 /* Node which has some commands and prompt string and configuration
@@ -505,6 +506,10 @@ struct cmd_token
 
"(neighbor|interface|area|lsa|zebra|config|dbex|spf|route|lsdb|redistribute|hook|asbr|prefix|abr)"
 #define ISIS_STR "IS-IS information\n"
 #define AREA_TAG_STR "[area tag]\n"
+#define MPLS_TE_STR "MPLS-TE specific commands\n"
+#define LINK_PARAMS_STR "Configure interface link parameters\n"
+#define OSPF_RI_STR "OSPF Router Information specific commands\n"
+#define PCE_STR "PCE Router Information specific commands\n"

 #define CONF_BACKUP_EXT ".sav"

diff --git a/lib/if.c b/lib/if.c
index 44b8586..45c1acc 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -168,6 +168,8 @@ if_delete (struct interface *ifp)

   list_free (ifp->connected);

+  if_link_params_free (ifp);
+
   XFREE (MTYPE_IF, ifp);
 }

@@ -1125,3 +1127,43 @@ if_link_type_str (enum zebra_link_type llt)
     }
   return NULL;
 }
+
+struct if_link_params *
+if_link_params_get (struct interface *ifp)
+{
+  if (ifp->link_params != NULL)
+    return ifp->link_params;
+
+  struct if_link_params *iflp = XCALLOC(MTYPE_IF_LINK_PARAMS,
+                                      sizeof (struct if_link_params));
+  if (iflp == NULL) return NULL;
+
+  /* Set TE metric == standard metric */
+  iflp->te_metric = ifp->metric;
+
+  /* Compute default bandwidth based on interface */
+  int bw = (float)((ifp->bandwidth ? ifp->bandwidth : DEFAULT_BANDWIDTH)
+                   * TE_KILO_BIT / TE_BYTE);
+
+  /* Set Max, Reservable and Unreserved Bandwidth */
+  iflp->max_bw = bw;
+  iflp->max_rsv_bw = bw;
+  for (int i = 0; i < MAX_CLASS_TYPE; i++)
+    iflp->unrsv_bw[i] = bw;
+
+  /* Update Link parameters status */
+  iflp->lp_status = LP_TE | LP_MAX_BW | LP_MAX_RSV_BW | LP_UNRSV_BW;
+
+  /* Finally attach newly created Link Parameters */
+  ifp->link_params = iflp;
+
+  return iflp;
+}
+
+void
+if_link_params_free (struct interface *ifp)
+{
+  if (ifp->link_params == NULL) return;
+  XFREE(MTYPE_IF_LINK_PARAMS, ifp->link_params);
+  ifp->link_params = NULL;
+}
diff --git a/lib/if.h b/lib/if.h
index b3d14ba..9796a4d 100644
--- a/lib/if.h
+++ b/lib/if.h
@@ -131,6 +131,63 @@ struct if_stats
 };
 #endif /* HAVE_PROC_NET_DEV */

+/* Here are "non-official" architectural constants. */
+#define TE_EXT_MASK             0x0FFFFFFF
+#define TE_EXT_ANORMAL          0x80000000
+#define LOSS_PRECISION          0.000003
+#define TE_KILO_BIT             1000
+#define TE_BYTE                 8
+#define DEFAULT_BANDWIDTH       10000
+#define MAX_CLASS_TYPE          8
+#define MAX_PKT_LOSS            50.331642
+
+/* Link Parameters Status: 0: unset, 1: set, */
+#define LP_UNSET                0x0000
+#define LP_TE                   0x0001
+#define LP_MAX_BW               0x0002
+#define LP_MAX_RSV_BW           0x0004
+#define LP_UNRSV_BW             0x0008
+#define LP_ADM_GRP              0x0010
+#define LP_RMT_AS               0x0020
+#define LP_DELAY                0x0040
+#define LP_MM_DELAY             0x0080
+#define LP_DELAY_VAR            0x0100
+#define LP_PKT_LOSS             0x0200
+#define LP_RES_BW               0x0400
+#define LP_AVA_BW               0x0800
+#define LP_USE_BW               0x1000
+
+#define IS_PARAM_UNSET(lp, st) !(lp->lp_status & st)
+#define IS_PARAM_SET(lp, st) (lp->lp_status & st)
+#define IS_LINK_PARAMS_SET(lp) (lp->lp_status != LP_UNSET)
+
+#define SET_PARAM(lp, st) (lp->lp_status) |= (st)
+#define UNSET_PARAM(lp, st) (lp->lp_status) &= ~(st)
+#define RESET_LINK_PARAM(lp) (lp->lp_status = LP_UNSET)
+
+/* Link Parameters for Traffic Engineering */
+struct if_link_params {
+  u_int32_t lp_status;   /* Status of Link Parameters: */
+  u_int32_t te_metric;   /* Traffic Engineering metric */
+  float max_bw;          /* Maximum Bandwidth */
+  float max_rsv_bw;      /* Maximum Reservable Bandwidth */
+ float unrsv_bw[MAX_CLASS_TYPE]; /* Unreserved Bandwidth per Class Type (8) */
+  u_int32_t admin_grp;   /* Administrative group */
+  u_int32_t rmt_as;      /* Remote AS number */
+  struct in_addr rmt_ip; /* Remote IP address */
+  u_int32_t av_delay;    /* Link Average Delay */
+  u_int32_t min_delay;   /* Link Min Delay */
+  u_int32_t max_delay;   /* Link Max Delay */
+  u_int32_t delay_var;   /* Link Delay Variation */
+  float pkt_loss;        /* Link Packet Loss */
+  float res_bw;          /* Residual Bandwidth */
+  float ava_bw;          /* Available Bandwidth */
+  float use_bw;          /* Utilized Bandwidth */
+};
+
+#define INTERFACE_LINK_PARAMS_SIZE   sizeof(struct if_link_params)
+#define HAS_LINK_PARAMS(ifp)  ((ifp)->link_params != NULL)
+
 /* Interface structure */
 struct interface
 {
@@ -172,6 +229,9 @@ struct interface
   /* interface bandwidth, kbits */
   unsigned int bandwidth;

+  /* Link parameters for Traffic Engineering */
+  struct if_link_params *link_params;
+
   /* description of the interface. */
   char *desc;

@@ -389,6 +449,10 @@ extern ifindex_t if_nametoindex (const char *);
 extern char *if_indextoname (ifindex_t, char *);
 #endif

+/* link parameters */
+struct if_link_params *if_link_params_get (struct interface *);
+void if_link_params_free (struct interface *);
+
 /* Exported variables. */
 extern struct list *iflist;
 extern struct cmd_element interface_desc_cmd;
diff --git a/lib/zclient.c b/lib/zclient.c
index 9d50ebc..18ed26c 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -768,7 +768,104 @@ zebra_interface_state_read (struct stream *s, vrf_id_t vrf_id)
   return ifp;
 }

-/*
+static void link_params_set_value(struct stream *s, struct if_link_params *iflp)
+{
+
+  if (iflp == NULL)
+    return;
+
+  iflp->lp_status = stream_getl (s);
+  iflp->te_metric = stream_getl (s);
+  iflp->max_bw = stream_getf (s);
+  iflp->max_rsv_bw = stream_getf (s);
+  uint32_t bwclassnum = stream_getl (s);
+  {
+    unsigned int i;
+    for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++)
+      iflp->unrsv_bw[i] = stream_getf (s);
+    if (i < bwclassnum)
+      zlog_err ("%s: received %d > %d (MAX_CLASS_TYPE) bw entries"
+                " - outdated library?",
+                __func__, bwclassnum, MAX_CLASS_TYPE);
+  }
+  iflp->admin_grp = stream_getl (s);
+  iflp->rmt_as = stream_getl (s);
+  iflp->rmt_ip.s_addr = stream_get_ipv4 (s);
+
+  iflp->av_delay = stream_getl (s);
+  iflp->min_delay = stream_getl (s);
+  iflp->max_delay = stream_getl (s);
+  iflp->delay_var = stream_getl (s);
+
+  iflp->pkt_loss = stream_getf (s);
+  iflp->res_bw = stream_getf (s);
+  iflp->ava_bw = stream_getf (s);
+  iflp->use_bw = stream_getf (s);
+}
+
+struct interface *
+zebra_interface_link_params_read (struct stream *s)
+{
+  struct if_link_params *iflp;
+  uint32_t ifindex = stream_getl (s);
+
+  struct interface *ifp = if_lookup_by_index (ifindex);
+
+  if (ifp == NULL || s == NULL)
+    {
+      zlog_err ("%s: unknown ifindex %u, shouldn't happen",
+                __func__, ifindex);
+      return NULL;
+    }
+
+  if ((iflp = if_link_params_get (ifp)) == NULL)
+    return NULL;
+
+  link_params_set_value(s, iflp);
+
+  return ifp;
+}
+
+size_t
+zebra_interface_link_params_write (struct stream *s, struct interface *ifp)
+{
+  size_t w;
+  struct if_link_params *iflp;
+
+  if (s == NULL || ifp == NULL || ifp->link_params == NULL)
+    return 0;
+
+  iflp = ifp->link_params;
+  w = 0;
+
+  w += stream_putl (s, iflp->lp_status);
+
+  w += stream_putl (s, iflp->te_metric);
+  w += stream_putf (s, iflp->max_bw);
+  w += stream_putf (s, iflp->max_rsv_bw);
+
+  w += stream_putl (s, MAX_CLASS_TYPE);
+  for (int i = 0; i < MAX_CLASS_TYPE; i++)
+    w += stream_putf (s, iflp->unrsv_bw[i]);
+
+  w += stream_putl (s, iflp->admin_grp);
+  w += stream_putl (s, iflp->rmt_as);
+  w += stream_put_in_addr (s, &iflp->rmt_ip);
+
+  w += stream_putl (s, iflp->av_delay);
+  w += stream_putl (s, iflp->min_delay);
+  w += stream_putl (s, iflp->max_delay);
+  w += stream_putl (s, iflp->delay_var);
+
+  w += stream_putf (s, iflp->pkt_loss);
+  w += stream_putf (s, iflp->res_bw);
+  w += stream_putf (s, iflp->ava_bw);
+  w += stream_putf (s, iflp->use_bw);
+
+  return w;
+}
+
+/*
  * format of message for address additon is:
  *    0
  *  0 1 2 3 4 5 6 7
@@ -797,12 +894,18 @@ zebra_interface_state_read (struct stream *s, vrf_id_t vrf_id)
  * :               :
  * |               |
  * +-+-+-+-+-+-+-+-+
- *
+ * | Link_params?  |  Whether a link-params follows: 1 or 0.
+ * +-+-+-+-+-+-+-+-+
+ * |  Link_params  | 0 or 1 INTERFACE_LINK_PARAMS_SIZE sized
+ * |   ....        | (struct if_link_params).
+ * +-+-+-+-+-+-+-+-+
  */

 void
 zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
 {
+  u_char link_params_status = 0;
+
   /* Read interface's index. */
   ifp->ifindex = stream_getl (s);
   ifp->status = stream_getc (s);
@@ -817,6 +920,16 @@ zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
   ifp->hw_addr_len = stream_getl (s);
   if (ifp->hw_addr_len)
stream_get (ifp->hw_addr, s, MIN(ifp->hw_addr_len, INTERFACE_HWADDR_MAX));
+
+  /* Read Traffic Engineering status */
+  link_params_status = stream_getc (s);
+  /* Then, Traffic Engineering parameters if any */
+  if (link_params_status)
+    {
+      struct if_link_params *iflp = if_link_params_get (ifp);
+      link_params_set_value(s, iflp);
+    }
+
 }

 static int
@@ -1045,6 +1158,10 @@ zclient_read (struct thread *thread)
       if (zclient->ipv6_route_delete)
     (*zclient->ipv6_route_delete) (command, zclient, length, vrf_id);
       break;
+    case ZEBRA_INTERFACE_LINK_PARAMS:
+      if (zclient->interface_link_params)
+        (*zclient->interface_link_params) (command, zclient, length);
+      break;
     default:
       break;
     }
diff --git a/lib/zclient.h b/lib/zclient.h
index d069eb2..1513492 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -85,6 +85,7 @@ struct zclient
   int (*interface_down) (int, struct zclient *, uint16_t, vrf_id_t);
int (*interface_address_add) (int, struct zclient *, uint16_t, vrf_id_t); int (*interface_address_delete) (int, struct zclient *, uint16_t, vrf_id_t);
+  int (*interface_link_params) (int, struct zclient *, uint16_t);
   int (*ipv4_route_add) (int, struct zclient *, uint16_t, vrf_id_t);
   int (*ipv4_route_delete) (int, struct zclient *, uint16_t, vrf_id_t);
   int (*ipv6_route_add) (int, struct zclient *, uint16_t, vrf_id_t);
@@ -184,6 +185,9 @@ extern void zebra_router_id_update_read (struct stream *s, struct prefix *rid); extern int zapi_ipv4_route (u_char, struct zclient *, struct prefix_ipv4 *,
                             struct zapi_ipv4 *);

+extern struct interface *zebra_interface_link_params_read (struct stream *);
+extern size_t zebra_interface_link_params_write (struct stream *,
+                                                 struct interface *);
 #ifdef HAVE_IPV6
 /* IPv6 prefix add and delete function prototype. */

diff --git a/lib/zebra.h b/lib/zebra.h
index d980283..95cee33 100644
--- a/lib/zebra.h
+++ b/lib/zebra.h
@@ -415,7 +415,8 @@ struct in_pktinfo
 #define ZEBRA_HELLO                       23
 #define ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB    24
 #define ZEBRA_VRF_UNREGISTER              25
-#define ZEBRA_MESSAGE_MAX                 26
+#define ZEBRA_INTERFACE_LINK_PARAMS       26
+#define ZEBRA_MESSAGE_MAX                 27

 /* Marker value used in new Zserv, in the byte location corresponding
  * the command value in the old zserv header. To allow old and new
--
1.9.1


_______________________________________________
Quagga-dev mailing list
[email protected]
https://lists.quagga.net/mailman/listinfo/quagga-dev

Reply via email to