]> git.proxmox.com Git - mirror_frr.git/commitdiff
lib: Add zapi_route function.
authorDonald Sharp <sharpd@cumulusnetworks.com>
Sun, 4 Jun 2017 23:14:44 +0000 (19:14 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Sun, 4 Jun 2017 23:14:44 +0000 (19:14 -0400)
Allow routing protocols to call one function to add/delete
routes into zebra.  Future commits will start adding
this code to individual routing protocols.

Why are we doing this?  Well the zapi_ipv[4|6]_route functions
are fundamentally broken in their ability to pass down anything
but NEXTHOP_TYPE_IFINDEX or NEXTHOP_TYPE_IPV[4|6] and we need
the ability to pass down a bit more information.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
lib/zclient.c
lib/zclient.h

index a53e8112c82c669095a73fdd21db48be0258492a..801769b9635026ef6571de9fa0e512cd30799b55 100644 (file)
@@ -977,6 +977,98 @@ zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
   return zclient_send_message(zclient);
 }
 
+int
+zapi_route (u_char cmd, struct zclient *zclient, struct prefix *p,
+            struct prefix_ipv6 *src_p, struct zapi_route *api)
+{
+  int i;
+  int psize;
+  struct stream *s;
+
+  /* either we have !SRCPFX && src_p == NULL, or SRCPFX && src_p != NULL */
+  assert (!(api->message & ZAPI_MESSAGE_SRCPFX) == !src_p);
+
+  /* Reset stream. */
+  s = zclient->obuf;
+  stream_reset (s);
+
+  zclient_create_header (s, cmd, api->vrf_id);
+
+  /* Put type and nexthop. */
+  stream_putc (s, api->type);
+  stream_putw (s, api->instance);
+  stream_putl (s, api->flags);
+  stream_putc (s, api->message);
+  stream_putw (s, api->safi);
+  
+  /* Put prefix information. */
+  psize = PSIZE (p->prefixlen);
+  stream_putc (s, p->prefixlen);
+  stream_write (s, (u_char *)&p->u.prefix, psize);
+
+  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_SRCPFX))
+    {
+      psize = PSIZE (src_p->prefixlen);
+      stream_putc (s, src_p->prefixlen);
+      stream_write (s, (u_char *)&src_p->prefix, psize);
+    }
+
+  /* Nexthop, ifindex, distance and metric information. */
+  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
+    {
+      stream_putc (s, api->nexthop_num);
+
+      for (i = 0; i < api->nexthop_num; i++)
+        {
+          stream_putc (s, api->nexthop[i]->type);
+          switch (api->nexthop[i]->type)
+            {
+            case NEXTHOP_TYPE_BLACKHOLE:
+              break;
+            case NEXTHOP_TYPE_IPV4:
+              stream_put_in_addr (s, &api->nexthop[i]->gate.ipv4);
+
+              /* For labeled-unicast, each nexthop is followed by label. */
+              if (CHECK_FLAG (api->message, ZAPI_MESSAGE_LABEL))
+                stream_putl (s, api->nexthop[i]->nh_label->label[0]);
+              break;
+            case NEXTHOP_TYPE_IPV4_IFINDEX:
+              stream_put_in_addr (s, &api->nexthop[i]->gate.ipv4);
+              stream_putl (s, api->nexthop[i]->ifindex);
+              break;
+            case NEXTHOP_TYPE_IFINDEX:
+              stream_putl (s, api->nexthop[i]->ifindex);
+              break;
+            case NEXTHOP_TYPE_IPV6:
+              stream_write (s, (u_char *)&api->nexthop[i]->gate.ipv6, 16);
+
+              /* For labeled-unicast, each nexthop is followed by label. */
+              if (CHECK_FLAG (api->message, ZAPI_MESSAGE_LABEL))
+                stream_putl (s, api->nexthop[i]->nh_label->label[0]);
+              break;
+            case NEXTHOP_TYPE_IPV6_IFINDEX:
+              stream_write (s, (u_char *)&api->nexthop[i]->gate.ipv6, 16);
+              stream_putl (s, api->nexthop[i]->ifindex);
+              break;
+            }
+        }
+    }
+
+  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
+    stream_putc (s, api->distance);
+  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
+    stream_putl (s, api->metric);
+  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_TAG))
+    stream_putl (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));
+
+  return zclient_send_message(zclient);
+}
+
 /* 
  * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
  * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
index 847ac3b671ec314216857cd1282d57ff5d562231..59412fdd4c5487da5b5868f7a5fd1e91598505cf 100644 (file)
@@ -192,6 +192,31 @@ struct zserv_header
   uint16_t command;
 };
 
+struct zapi_route
+{
+  u_char type;
+  u_short instance;
+
+  u_int32_t flags;
+
+  u_char message;
+
+  safi_t safi;
+
+  u_char nexthop_num;
+  struct nexthop **nexthop;
+
+  u_char distance;
+
+  u_int32_t metric;
+
+  route_tag_t tag;
+
+  u_int32_t mtu;
+
+  vrf_id_t vrf_id;
+};
+
 /* Zebra IPv4 route message API. */
 struct zapi_ipv4
 {
@@ -323,5 +348,8 @@ extern int zapi_ipv6_route (u_char cmd, struct zclient *zclient,
                      struct zapi_ipv6 *api);
 extern int zapi_ipv4_route_ipv6_nexthop (u_char, struct zclient *,
                                          struct prefix_ipv4 *, struct zapi_ipv6 *);
+extern int zapi_route (u_char cmd, struct zclient *zclient,
+                       struct prefix *p, struct prefix_ipv6 *src_p,
+                       struct zapi_route *api);
 
 #endif /* _ZEBRA_ZCLIENT_H */