summaryrefslogtreecommitdiff
path: root/zebra/zserv.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zserv.c')
-rw-r--r--zebra/zserv.c93
1 files changed, 91 insertions, 2 deletions
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 9d9a7cd783..b6d70084c0 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -988,6 +988,43 @@ static int zsend_ipv4_nexthop_lookup_mrib(struct zserv *client,
return zebra_server_send_message(client);
}
+int zsend_route_notify_owner(u_char proto, u_short instance,
+ vrf_id_t vrf_id, struct prefix *p,
+ enum zapi_route_notify_owner note)
+{
+ struct zserv *client;
+ struct stream *s;
+ uint8_t blen;
+
+ client = zebra_find_client(proto, instance);
+ if (!client || !client->notify_owner) {
+ if (IS_ZEBRA_DEBUG_PACKET) {
+ char buff[PREFIX_STRLEN];
+
+ zlog_debug("Not Notifying Owner: %u about prefix %s",
+ proto, prefix2str(p, buff, sizeof(buff)));
+ }
+ return 0;
+ }
+
+ s = client->obuf;
+ stream_reset(s);
+
+ zserv_create_header(s, ZEBRA_ROUTE_NOTIFY_OWNER, vrf_id);
+
+ stream_put(s, &note, sizeof(note));
+
+ stream_putc(s, p->family);
+
+ blen = prefix_blen(p);
+ stream_putc(s, p->prefixlen);
+ stream_put(s, &p->u.prefix, blen);
+
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ return zebra_server_send_message(client);
+}
+
/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
int zsend_router_id_update(struct zserv *client, struct prefix *p,
vrf_id_t vrf_id)
@@ -1884,9 +1921,13 @@ static void zread_hello(struct zserv *client)
/* type of protocol (lib/zebra.h) */
u_char proto;
u_short instance;
+ u_char notify;
STREAM_GETC(client->ibuf, proto);
STREAM_GETW(client->ibuf, instance);
+ STREAM_GETC(client->ibuf, notify);
+ if (notify)
+ client->notify_owner = true;
/* accept only dynamic routing protocols */
if ((proto < ZEBRA_ROUTE_MAX) && (proto > ZEBRA_ROUTE_STATIC)) {
@@ -2562,6 +2603,26 @@ static inline void zserv_handle_commands(struct zserv *client,
}
}
+#if defined(HANDLE_ZAPI_FUZZING)
+static void zserv_write_incoming(struct stream *orig, uint16_t command)
+{
+ char fname[MAXPATHLEN];
+ struct stream *copy;
+ int fd = -1;
+
+ copy = stream_dup(orig);
+ stream_set_getp(copy, 0);
+
+ zserv_privs.change(ZPRIVS_RAISE);
+ snprintf(fname, MAXPATHLEN, "%s/%u", DAEMON_VTY_DIR, command);
+ fd = open(fname, O_CREAT | O_WRONLY | O_EXCL, 0644);
+ stream_flush(copy, fd);
+ close(fd);
+ zserv_privs.change(ZPRIVS_LOWER);
+ stream_free(copy);
+}
+#endif
+
/* Handler of zebra service request. */
static int zebra_client_read(struct thread *thread)
{
@@ -2572,7 +2633,11 @@ static int zebra_client_read(struct thread *thread)
uint8_t marker, version;
vrf_id_t vrf_id;
struct zebra_vrf *zvrf;
+#if defined(HANDLE_ZAPI_FUZZING)
+ int packets = 1;
+#else
int packets = zebrad.packets_to_process;
+#endif
/* Get thread data. Reset reading thread because I'm running. */
sock = THREAD_FD(thread);
@@ -2662,6 +2727,9 @@ static int zebra_client_read(struct thread *thread)
}
}
+#if defined(HANDLE_ZAPI_FUZZING)
+ zserv_write_incoming(client->ibuf, command);
+#endif
length -= ZEBRA_HEADER_SIZE;
/* Debug packet information. */
@@ -2935,13 +3003,14 @@ static void zebra_show_client_brief(struct vty *vty, struct zserv *client)
client->v6_route_del_cnt);
}
-struct zserv *zebra_find_client(u_char proto)
+struct zserv *zebra_find_client(u_char proto, u_short instance)
{
struct listnode *node, *nnode;
struct zserv *client;
for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
- if (client->proto == proto)
+ if (client->proto == proto &&
+ client->instance == instance)
return client;
}
@@ -3209,6 +3278,26 @@ static struct cmd_node forwarding_node = {FORWARDING_NODE,
"", /* This node has no interface. */
1};
+#if defined(HANDLE_ZAPI_FUZZING)
+void zserv_read_file(char *input)
+{
+ int fd;
+ struct zserv *client = NULL;
+ struct thread t;
+
+ zebra_client_create(-1);
+ client = zebrad.client_list->head->data;
+ t.arg = client;
+
+ fd = open(input, O_RDONLY|O_NONBLOCK);
+ t.u.fd = fd;
+
+ zebra_client_read(&t);
+
+ close(fd);
+}
+#endif
+
/* Initialisation of zebra and installation of commands. */
void zebra_init(void)
{