summaryrefslogtreecommitdiff
path: root/zebra/zserv.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zserv.c')
-rw-r--r--zebra/zserv.c81
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;
}