diff options
Diffstat (limited to 'zebra/zserv.c')
| -rw-r--r-- | zebra/zserv.c | 81 |
1 files changed, 77 insertions, 4 deletions
diff --git a/zebra/zserv.c b/zebra/zserv.c index b245b7f7bc..ecb3bd05dd 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -36,12 +36,14 @@ #include "privs.h" #include "network.h" #include "buffer.h" +#include "nexthop.h" #include "zebra/zserv.h" #include "zebra/router-id.h" #include "zebra/redistribute.h" #include "zebra/debug.h" #include "zebra/ipforward.h" +#include "zebra/zebra_rnh.h" /* Event list of zebra. */ enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE }; @@ -101,7 +103,7 @@ zserv_flush_data(struct thread *thread) return 0; } -static int +int zebra_server_send_message(struct zserv *client) { if (client->t_suicide) @@ -130,7 +132,7 @@ zebra_server_send_message(struct zserv *client) return 0; } -static void +void zserv_create_header (struct stream *s, uint16_t cmd) { /* length placeholder, caller can update */ @@ -599,6 +601,65 @@ zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr) return zebra_server_send_message(client); } +/* Nexthop register */ +static int +zserv_nexthop_register (struct zserv *client, int sock, u_short length) +{ + struct rnh *rnh; + struct stream *s; + struct prefix p; + u_short l = 0; + + if (IS_ZEBRA_DEBUG_NHT) + zlog_debug("nexthop_register msg from client %s: length=%d\n", + zebra_route_string(client->proto), length); + + s = client->ibuf; + + while (l < length) + { + p.family = stream_getw(s); + p.prefixlen = stream_getc(s); + l += 3; + stream_get(&p.u.prefix, s, PSIZE(p.prefixlen)); + l += PSIZE(p.prefixlen); + rnh = zebra_add_rnh(&p, 0); + zebra_add_rnh_client(rnh, client); + } + zebra_evaluate_rnh_table(0, AF_INET); + zebra_evaluate_rnh_table(0, AF_INET6); + return 0; +} + +/* Nexthop register */ +static int +zserv_nexthop_unregister (struct zserv *client, int sock, u_short length) +{ + struct rnh *rnh; + struct stream *s; + struct prefix p; + u_short l = 0; + + if (IS_ZEBRA_DEBUG_NHT) + zlog_debug("nexthop_unregister msg from client %s: length=%d\n", + zebra_route_string(client->proto), length); + + s = client->ibuf; + + while (l < length) + { + p.family = stream_getw(s); + p.prefixlen = stream_getc(s); + l += 3; + stream_get(&p.u.prefix, s, PSIZE(p.prefixlen)); + l += PSIZE(p.prefixlen); + rnh = zebra_lookup_rnh(&p, 0); + if (rnh) + zebra_remove_rnh_client(rnh, client); + } + return 0; +} + static int zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p) { @@ -1171,6 +1232,7 @@ zread_hello (struct zserv *client) client->sock); route_type_oaths[proto] = client->sock; + client->proto = proto; } } @@ -1196,6 +1258,9 @@ zebra_score_rib (int client_sock) static void zebra_client_close (struct zserv *client) { + zebra_cleanup_rnh_client(0, AF_INET, client); + zebra_cleanup_rnh_client(0, AF_INET6, client); + /* Close file descriptor. */ if (client->sock) { @@ -1408,6 +1473,12 @@ zebra_client_read (struct thread *thread) case ZEBRA_HELLO: zread_hello (client); break; + case ZEBRA_NEXTHOP_REGISTER: + zserv_nexthop_register(client, sock, length); + break; + case ZEBRA_NEXTHOP_UNREGISTER: + zserv_nexthop_unregister(client, sock, length); + break; default: zlog_info ("Zebra received unknown command %d", command); break; @@ -1681,8 +1752,10 @@ DEFUN (show_zebra_client, struct zserv *client; for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client)) - vty_out (vty, "Client fd %d%s", client->sock, VTY_NEWLINE); - + vty_out (vty, "Client %s fd %d%s", + zebra_route_string(client->proto), client->sock, + VTY_NEWLINE); + return CMD_SUCCESS; } |
