summaryrefslogtreecommitdiff
path: root/lib/zclient.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/zclient.c')
-rw-r--r--lib/zclient.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/lib/zclient.c b/lib/zclient.c
index d23f62dcd7..e1ce40ce70 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -36,6 +36,7 @@
#include "nexthop.h"
#include "mpls.h"
#include "sockopt.h"
+#include "pbr.h"
DEFINE_MTYPE_STATIC(LIB, ZCLIENT, "Zclient")
DEFINE_MTYPE_STATIC(LIB, REDIST_INST, "Redistribution instance IDs")
@@ -1229,6 +1230,55 @@ stream_failure:
return 0;
}
+static void zapi_encode_prefix(struct stream *s,
+ struct prefix *p,
+ uint8_t family)
+{
+ struct prefix any;
+
+ if (!p) {
+ memset(&any, 0, sizeof(any));
+ any.family = family;
+ p = &any;
+ }
+
+ stream_putc(s, p->family);
+ stream_putc(s, p->prefixlen);
+ stream_put(s, &p->u.prefix, prefix_blen(p));
+}
+
+int zapi_pbr_rule_encode(uint8_t cmd, struct stream *s,
+ struct pbr_rule *zrule)
+{
+ stream_reset(s);
+ zclient_create_header(s, cmd, zrule->vrf_id);
+
+ /*
+ * We are sending one item at a time at the moment
+ */
+ stream_putl(s, 1);
+
+ stream_putl(s, zrule->seq);
+ stream_putl(s, zrule->priority);
+ stream_putl(s, zrule->unique);
+
+ zapi_encode_prefix(s, &(zrule->filter.src_ip),
+ zrule->filter.src_ip.family);
+ stream_putw(s, zrule->filter.src_port); /* src port */
+ zapi_encode_prefix(s, &(zrule->filter.dst_ip),
+ zrule->filter.src_ip.family);
+ stream_putw(s, zrule->filter.dst_port); /* dst port */
+ stream_putw(s, zrule->filter.fwmark); /* fwmark */
+
+ stream_putl(s, zrule->action.table);
+ stream_putl(s, zrule->ifindex);
+
+ /* Put length at the first point of the stream. */
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ return 0;
+}
+
bool zapi_route_notify_decode(struct stream *s, struct prefix *p,
uint32_t *tableid,
enum zapi_route_notify_owner *note)
@@ -1279,6 +1329,50 @@ stream_failure:
return false;
}
+bool zapi_ipset_notify_decode(struct stream *s,
+ uint32_t *unique,
+ enum zapi_ipset_notify_owner *note)
+{
+ uint32_t uni;
+
+ STREAM_GET(note, s, sizeof(*note));
+
+ STREAM_GETL(s, uni);
+
+ if (zclient_debug)
+ zlog_debug("%s: %u", __PRETTY_FUNCTION__, uni);
+ *unique = uni;
+
+ return true;
+
+stream_failure:
+ return false;
+}
+
+bool zapi_ipset_entry_notify_decode(struct stream *s,
+ uint32_t *unique,
+ char *ipset_name,
+ enum zapi_ipset_entry_notify_owner *note)
+{
+ uint32_t uni;
+
+ STREAM_GET(note, s, sizeof(*note));
+
+ STREAM_GETL(s, uni);
+
+ STREAM_GET(ipset_name, s,
+ ZEBRA_IPSET_NAME_SIZE);
+
+ if (zclient_debug)
+ zlog_debug("%s: %u", __PRETTY_FUNCTION__, uni);
+ *unique = uni;
+
+ return true;
+
+stream_failure:
+ return false;
+}
+
struct nexthop *nexthop_from_zapi_nexthop(struct zapi_nexthop *znh)
{
struct nexthop *n = nexthop_new();
@@ -1991,6 +2085,40 @@ int lm_label_manager_connect(struct zclient *zclient)
return (int)result;
}
+/*
+ * Asynchronous label chunk request
+ *
+ * @param zclient Zclient used to connect to label manager (zebra)
+ * @param keep Avoid garbage collection
+ * @param chunk_size Amount of labels requested
+ * @result 0 on success, -1 otherwise
+ */
+int zclient_send_get_label_chunk(
+ struct zclient *zclient,
+ uint8_t keep,
+ uint32_t chunk_size)
+{
+ struct stream *s;
+
+ if (zclient_debug)
+ zlog_debug("Getting Label Chunk");
+
+ if (zclient->sock < 0)
+ return -1;
+
+ s = zclient->obuf;
+ stream_reset(s);
+
+ zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
+ stream_putc(s, keep);
+ stream_putl(s, chunk_size);
+
+ /* Put length at the first point of the stream. */
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ return zclient_send_message(zclient);
+}
+
/**
* Function to request a label chunk in a syncronous way
*
@@ -2604,6 +2732,12 @@ static int zclient_read(struct thread *thread)
if (zclient->rule_notify_owner)
(*zclient->rule_notify_owner)(command, zclient, length,
vrf_id);
+ break;
+ case ZEBRA_GET_LABEL_CHUNK:
+ if (zclient->label_chunk)
+ (*zclient->label_chunk)(command, zclient, length,
+ vrf_id);
+ break;
default:
break;
}