summaryrefslogtreecommitdiff
path: root/lib/zclient.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/zclient.c')
-rw-r--r--lib/zclient.c218
1 files changed, 173 insertions, 45 deletions
diff --git a/lib/zclient.c b/lib/zclient.c
index ef9516c912..753954fd84 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -32,6 +32,7 @@
#include "zclient.h"
#include "memory.h"
#include "table.h"
+#include "nexthop.h"
/* Zebra client events. */
enum event {ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT};
@@ -709,6 +710,8 @@ zclient_connect (struct thread *t)
*
* If ZAPI_MESSAGE_TAG is set, the tag value is written as a 2 byte value
*
+ * If ZAPI_MESSAGE_MTU is set, the mtu value is written as a 4 byte value
+ *
* XXX: No attention paid to alignment.
*/
int
@@ -744,7 +747,7 @@ zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
{
stream_putc (s, 1);
- stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE);
+ stream_putc (s, NEXTHOP_TYPE_BLACKHOLE);
/* XXX assert(api->nexthop_num == 0); */
/* XXX assert(api->ifindex_num == 0); */
}
@@ -753,12 +756,12 @@ zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
for (i = 0; i < api->nexthop_num; i++)
{
- stream_putc (s, ZEBRA_NEXTHOP_IPV4);
+ stream_putc (s, NEXTHOP_TYPE_IPV4);
stream_put_in_addr (s, api->nexthop[i]);
}
for (i = 0; i < api->ifindex_num; i++)
{
- stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
+ stream_putc (s, NEXTHOP_TYPE_IFINDEX);
stream_putl (s, api->ifindex[i]);
}
}
@@ -769,6 +772,8 @@ zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
stream_putl (s, api->metric);
if (CHECK_FLAG (api->message, ZAPI_MESSAGE_TAG))
stream_putw (s, api->tag);
+ if (CHECK_FLAG (api->message, ZAPI_MESSAGE_MTU))
+ stream_putl (s, api->mtu);
/* Put length at the first point of the stream. */
stream_putw_at (s, 0, stream_get_endp (s));
@@ -809,7 +814,7 @@ zapi_ipv4_route_ipv6_nexthop (u_char cmd, struct zclient *zclient,
if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
{
stream_putc (s, 1);
- stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE);
+ stream_putc (s, NEXTHOP_TYPE_BLACKHOLE);
/* XXX assert(api->nexthop_num == 0); */
/* XXX assert(api->ifindex_num == 0); */
}
@@ -818,12 +823,12 @@ zapi_ipv4_route_ipv6_nexthop (u_char cmd, struct zclient *zclient,
for (i = 0; i < api->nexthop_num; i++)
{
- stream_putc (s, ZEBRA_NEXTHOP_IPV6);
+ stream_putc (s, NEXTHOP_TYPE_IPV6);
stream_write (s, (u_char *)api->nexthop[i], 16);
}
for (i = 0; i < api->ifindex_num; i++)
{
- stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
+ stream_putc (s, NEXTHOP_TYPE_IFINDEX);
stream_putl (s, api->ifindex[i]);
}
}
@@ -834,6 +839,8 @@ zapi_ipv4_route_ipv6_nexthop (u_char cmd, struct zclient *zclient,
stream_putl (s, api->metric);
if (CHECK_FLAG (api->message, ZAPI_MESSAGE_TAG))
stream_putw (s, api->tag);
+ if (CHECK_FLAG (api->message, ZAPI_MESSAGE_MTU))
+ stream_putl (s, api->mtu);
/* Put length at the first point of the stream. */
stream_putw_at (s, 0, stream_get_endp (s));
@@ -873,7 +880,7 @@ zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
{
stream_putc (s, 1);
- stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE);
+ stream_putc (s, NEXTHOP_TYPE_BLACKHOLE);
/* XXX assert(api->nexthop_num == 0); */
/* XXX assert(api->ifindex_num == 0); */
}
@@ -882,12 +889,12 @@ zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
for (i = 0; i < api->nexthop_num; i++)
{
- stream_putc (s, ZEBRA_NEXTHOP_IPV6);
+ stream_putc (s, NEXTHOP_TYPE_IPV6);
stream_write (s, (u_char *)api->nexthop[i], 16);
}
for (i = 0; i < api->ifindex_num; i++)
{
- stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
+ stream_putc (s, NEXTHOP_TYPE_IFINDEX);
stream_putl (s, api->ifindex[i]);
}
}
@@ -898,6 +905,8 @@ zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
stream_putl (s, api->metric);
if (CHECK_FLAG (api->message, ZAPI_MESSAGE_TAG))
stream_putw (s, api->tag);
+ if (CHECK_FLAG (api->message, ZAPI_MESSAGE_MTU))
+ stream_putl (s, api->mtu);
/* Put length at the first point of the stream. */
stream_putw_at (s, 0, stream_get_endp (s));
@@ -951,8 +960,6 @@ zebra_router_id_update_read (struct stream *s, struct prefix *rid)
* ZEBRA_INTERFACE_DELETE from zebra to the client is:
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+
- * | type |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ifname |
* | |
@@ -960,20 +967,32 @@ zebra_router_id_update_read (struct stream *s, struct prefix *rid)
* | |
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | ifindex |
+ * | ifindex |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | status |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | if_flags |
+ * | if_flags |
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | metric |
+ * | metric |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | ifmtu |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | ifmtu6 |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | bandwidth |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | ifmtu |
+ * | Link Layer Type |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | ifmtu6 |
+ * | Harware Address Length |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | bandwidth |
+ * | Hardware Address if HW lenght different from 0 |
+ * | ... max INTERFACE_HWADDR_MAX |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | sockaddr_dl |
+ * | Link_params? | Whether a link-params follows: 1 or 0.
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Link_params 0 or 1 INTERFACE_LINK_PARAMS_SIZE sized |
+ * | .... (struct if_link_params). |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
@@ -1062,7 +1081,138 @@ 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;
+}
+
+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);
+
+ /* Read interface's value. */
+ ifp->flags = stream_getq (s);
+ ifp->ptm_enable = stream_getc (s);
+ ifp->ptm_status = stream_getc (s);
+ ifp->metric = stream_getl (s);
+ ifp->mtu = stream_getl (s);
+ ifp->mtu6 = stream_getl (s);
+ ifp->bandwidth = stream_getl (s);
+ ifp->ll_type = stream_getl (s);
+ 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);
+ }
+}
+
+size_t
+zebra_interface_link_params_write (struct stream *s, struct interface *ifp)
+{
+ size_t w;
+ struct if_link_params *iflp;
+ int i;
+
+ 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 (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
@@ -1091,33 +1241,8 @@ zebra_interface_state_read (struct stream *s, vrf_id_t vrf_id)
* : :
* | |
* +-+-+-+-+-+-+-+-+
- *
*/
-void
-zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
-{
- /* Read interface's index. */
- ifp->ifindex = stream_getl (s);
- ifp->status = stream_getc (s);
-
- /* Read interface's value. */
- ifp->flags = stream_getq (s);
- ifp->ptm_enable = stream_getc (s);
- ifp->ptm_status = stream_getc (s);
- ifp->metric = stream_getl (s);
- ifp->mtu = stream_getl (s);
- ifp->mtu6 = stream_getl (s);
- ifp->bandwidth = stream_getl (s);
-#ifdef HAVE_STRUCT_SOCKADDR_DL
- stream_get (&ifp->sdl, s, sizeof (ifp->sdl_storage));
-#else
- 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));
-#endif /* HAVE_STRUCT_SOCKADDR_DL */
-}
-
static int
memconstant(const void *s, int c, size_t n)
{
@@ -1133,7 +1258,7 @@ memconstant(const void *s, int c, size_t n)
struct connected *
zebra_interface_address_read (int type, struct stream *s, vrf_id_t vrf_id)
{
- unsigned int ifindex;
+ ifindex_t ifindex;
struct interface *ifp;
struct connected *ifc;
struct prefix p, d;
@@ -1503,6 +1628,9 @@ zclient_read (struct thread *thread)
case ZEBRA_REDISTRIBUTE_IPV6_DEL:
if (zclient->redistribute_route_ipv6_del)
(*zclient->redistribute_route_ipv6_del) (command, zclient, length, vrf_id);
+ case ZEBRA_INTERFACE_LINK_PARAMS:
+ if (zclient->interface_link_params)
+ (*zclient->interface_link_params) (command, zclient, length);
break;
default:
break;