diff options
Diffstat (limited to 'zebra/zserv.c')
| -rw-r--r-- | zebra/zserv.c | 93 |
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, ¬e, 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) { |
