summaryrefslogtreecommitdiff
path: root/zebra/zserv.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zserv.c')
-rw-r--r--zebra/zserv.c174
1 files changed, 120 insertions, 54 deletions
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 8618e5c371..064489acd9 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -54,6 +54,7 @@
#include "zebra/rtadv.h"
#include "zebra/zebra_mpls.h"
#include "zebra/zebra_fpm.h"
+#include "zebra/zebra_mroute.h"
/* Event list of zebra. */
enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
@@ -91,6 +92,7 @@ zserv_flush_data(struct thread *thread)
zlog_warn("%s: buffer_flush_available failed on zserv client fd %d, "
"closing", __func__, client->sock);
zebra_client_close(client);
+ client = NULL;
break;
case BUFFER_PENDING:
client->t_write = thread_add_write(zebrad.master, zserv_flush_data,
@@ -100,7 +102,8 @@ zserv_flush_data(struct thread *thread)
break;
}
- client->last_write_time = quagga_monotime();
+ if (client)
+ client->last_write_time = monotime(NULL);
return 0;
}
@@ -134,7 +137,7 @@ zebra_server_send_message(struct zserv *client)
break;
}
- client->last_write_time = quagga_monotime();
+ client->last_write_time = monotime(NULL);
return 0;
}
@@ -600,7 +603,7 @@ zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp)
*/
int
zsend_redistribute_route (int add, struct zserv *client, struct prefix *p,
- struct rib *rib)
+ struct prefix *src_p, struct rib *rib)
{
afi_t afi;
int cmd;
@@ -666,6 +669,14 @@ zsend_redistribute_route (int add, struct zserv *client, struct prefix *p,
stream_putc (s, p->prefixlen);
stream_write (s, (u_char *) & p->u.prefix, psize);
+ if (src_p)
+ {
+ SET_FLAG (zapi_flags, ZAPI_MESSAGE_SRCPFX);
+ psize = PSIZE (src_p->prefixlen);
+ stream_putc (s, src_p->prefixlen);
+ stream_write (s, (u_char *) & src_p->u.prefix, psize);
+ }
+
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
{
/* We don't send any nexthops when there's a multipath */
@@ -742,7 +753,7 @@ zsend_redistribute_route (int add, struct zserv *client, struct prefix *p,
/* ldpd needs all nexthops */
if (client->proto != ZEBRA_ROUTE_LDP)
- break;
+ break;
}
}
@@ -785,8 +796,6 @@ zsend_write_nexthop (struct stream *s, struct nexthop *nexthop)
switch (nexthop->type)
{
case NEXTHOP_TYPE_IPV4:
- stream_put_in_addr (s, &nexthop->gate.ipv4);
- break;
case NEXTHOP_TYPE_IPV4_IFINDEX:
stream_put_in_addr (s, &nexthop->gate.ipv4);
stream_putl (s, nexthop->ifindex);
@@ -826,7 +835,7 @@ zserv_rnh_register (struct zserv *client, int sock, u_short length,
s = client->ibuf;
- client->nh_reg_time = quagga_monotime();
+ client->nh_reg_time = monotime(NULL);
while (l < length)
{
@@ -914,7 +923,7 @@ zserv_rnh_unregister (struct zserv *client, int sock, u_short length,
rnh = zebra_lookup_rnh(&p, zvrf_id (zvrf), type);
if (rnh)
{
- client->nh_dereg_time = quagga_monotime();
+ client->nh_dereg_time = monotime(NULL);
zebra_remove_rnh_client(rnh, client, type);
}
}
@@ -1041,12 +1050,12 @@ zread_interface_delete (struct zserv *client, u_short length, struct zebra_vrf *
void
zserv_nexthop_num_warn (const char *caller, const struct prefix *p, const unsigned int nexthop_num)
{
- if (nexthop_num > MULTIPATH_NUM)
+ if (nexthop_num > multipath_num)
{
char buff[PREFIX2STR_BUFFER];
prefix2str(p, buff, sizeof (buff));
zlog_warn("%s: Prefix %s has %d nexthops, but we can only use the first %d",
- caller, buff, nexthop_num, MULTIPATH_NUM);
+ caller, buff, nexthop_num, multipath_num);
}
}
@@ -1150,7 +1159,7 @@ zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
/* Table */
rib->table = zvrf->table_id;
- ret = rib_add_multipath (AFI_IP, safi, &p, rib);
+ ret = rib_add_multipath (AFI_IP, safi, &p, NULL, rib);
/* Stats */
if (ret > 0)
@@ -1244,7 +1253,7 @@ zread_ipv4_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
table_id = zvrf->table_id;
rib_delete (AFI_IP, api.safi, zvrf_id (zvrf), api.type, api.instance,
- api.flags, &p, nexthop_p, ifindex, table_id);
+ api.flags, &p, NULL, nexthop_p, ifindex, table_id);
client->v4_route_del_cnt++;
return 0;
}
@@ -1265,7 +1274,7 @@ zread_ipv4_nexthop_lookup_mrib (struct zserv *client, u_short length, struct zeb
static int
zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
{
- int i;
+ unsigned int i;
struct stream *s;
struct in6_addr nexthop;
struct rib *rib;
@@ -1309,9 +1318,9 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct
* next-hop-addr/next-hop-ifindices. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
{
- int nh_count = 0;
- int if_count = 0;
- int max_nh_if = 0;
+ unsigned int nh_count = 0;
+ unsigned int if_count = 0;
+ unsigned int max_nh_if = 0;
nexthop_num = stream_getc (s);
zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num);
@@ -1323,12 +1332,12 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct
{
case NEXTHOP_TYPE_IPV6:
stream_get (&nexthop, s, 16);
- if (nh_count < MULTIPATH_NUM) {
+ if (nh_count < multipath_num) {
nexthops[nh_count++] = nexthop;
}
break;
case NEXTHOP_TYPE_IFINDEX:
- if (if_count < MULTIPATH_NUM) {
+ if (if_count < multipath_num) {
ifindices[if_count++] = stream_getl (s);
}
break;
@@ -1379,7 +1388,7 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct
/* Table */
rib->table = zvrf->table_id;
- ret = rib_add_multipath (AFI_IP6, safi, &p, rib);
+ ret = rib_add_multipath (AFI_IP6, safi, &p, NULL, rib);
/* Stats */
if (ret > 0)
client->v4_route_add_cnt++;
@@ -1392,7 +1401,7 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct
static int
zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
{
- int i;
+ unsigned int i;
struct stream *s;
struct in6_addr nexthop;
struct rib *rib;
@@ -1400,6 +1409,7 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
u_char nexthop_num;
u_char nexthop_type;
struct prefix p;
+ struct prefix_ipv6 src_p, *src_pp;
safi_t safi;
static struct in6_addr nexthops[MULTIPATH_NUM];
static unsigned int ifindices[MULTIPATH_NUM];
@@ -1427,15 +1437,26 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
p.prefixlen = stream_getc (s);
stream_get (&p.u.prefix6, s, PSIZE (p.prefixlen));
+ if (CHECK_FLAG (message, ZAPI_MESSAGE_SRCPFX))
+ {
+ memset (&src_p, 0, sizeof (struct prefix_ipv6));
+ src_p.family = AF_INET6;
+ src_p.prefixlen = stream_getc (s);
+ stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen));
+ src_pp = &src_p;
+ }
+ else
+ src_pp = NULL;
+
/* We need to give nh-addr, nh-ifindex with the same next-hop object
* to the rib to ensure that IPv6 multipathing works; need to coalesce
* these. Clients should send the same number of paired set of
* next-hop-addr/next-hop-ifindices. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
{
- int nh_count = 0;
- int if_count = 0;
- int max_nh_if = 0;
+ unsigned int nh_count = 0;
+ unsigned int if_count = 0;
+ unsigned int max_nh_if = 0;
nexthop_num = stream_getc (s);
zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num);
@@ -1447,12 +1468,12 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
{
case NEXTHOP_TYPE_IPV6:
stream_get (&nexthop, s, 16);
- if (nh_count < MULTIPATH_NUM) {
+ if (nh_count < multipath_num) {
nexthops[nh_count++] = nexthop;
}
break;
case NEXTHOP_TYPE_IFINDEX:
- if (if_count < MULTIPATH_NUM) {
+ if (if_count < multipath_num) {
ifindices[if_count++] = stream_getl (s);
}
break;
@@ -1501,7 +1522,7 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
rib->vrf_id = zvrf_id (zvrf);
rib->table = zvrf->table_id;
- ret = rib_add_multipath (AFI_IP6, safi, &p, rib);
+ ret = rib_add_multipath (AFI_IP6, safi, &p, src_pp, rib);
/* Stats */
if (ret > 0)
client->v6_route_add_cnt++;
@@ -1519,9 +1540,10 @@ zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
struct stream *s;
struct zapi_ipv6 api;
struct in6_addr nexthop;
- union g_addr *pnexthop;
+ union g_addr *pnexthop = NULL;
unsigned long ifindex;
struct prefix p;
+ struct prefix_ipv6 src_p, *src_pp;
s = client->ibuf;
ifindex = 0;
@@ -1540,6 +1562,17 @@ zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
p.prefixlen = stream_getc (s);
stream_get (&p.u.prefix6, s, PSIZE (p.prefixlen));
+ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_SRCPFX))
+ {
+ memset (&src_p, 0, sizeof (struct prefix_ipv6));
+ src_p.family = AF_INET6;
+ src_p.prefixlen = stream_getc (s);
+ stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen));
+ src_pp = &src_p;
+ }
+ else
+ src_pp = NULL;
+
/* Nexthop, ifindex, distance, metric. */
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
{
@@ -1583,10 +1616,10 @@ zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance,
- api.flags, &p, NULL, ifindex, client->rtm_table);
+ api.flags, &p, src_pp, NULL, ifindex, client->rtm_table);
else
rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance,
- api.flags, &p, pnexthop, ifindex, client->rtm_table);
+ api.flags, &p, src_pp, pnexthop, ifindex, client->rtm_table);
client->v6_route_del_cnt++;
return 0;
@@ -1665,6 +1698,7 @@ zread_mpls_labels (int command, struct zserv *client, u_short length,
struct prefix prefix;
enum nexthop_types_t gtype;
union g_addr gate;
+ ifindex_t ifindex;
mpls_label_t in_label, out_label;
u_int8_t distance;
struct zebra_vrf *zvrf;
@@ -1684,37 +1718,56 @@ zread_mpls_labels (int command, struct zserv *client, u_short length,
case AF_INET:
prefix.u.prefix4.s_addr = stream_get_ipv4 (s);
prefix.prefixlen = stream_getc (s);
- gtype = NEXTHOP_TYPE_IPV4;
gate.ipv4.s_addr = stream_get_ipv4 (s);
break;
case AF_INET6:
stream_get (&prefix.u.prefix6, s, 16);
prefix.prefixlen = stream_getc (s);
- gtype = NEXTHOP_TYPE_IPV6;
stream_get (&gate.ipv6, s, 16);
break;
default:
return;
}
+ ifindex = stream_getl (s);
distance = stream_getc (s);
in_label = stream_getl (s);
out_label = stream_getl (s);
+ switch (prefix.family)
+ {
+ case AF_INET:
+ if (ifindex)
+ gtype = NEXTHOP_TYPE_IPV4_IFINDEX;
+ else
+ gtype = NEXTHOP_TYPE_IPV4;
+ break;
+ case AF_INET6:
+ if (ifindex)
+ gtype = NEXTHOP_TYPE_IPV6_IFINDEX;
+ else
+ gtype = NEXTHOP_TYPE_IPV6;
+ break;
+ default:
+ return;
+ }
+
if (! mpls_enabled)
return;
if (command == ZEBRA_MPLS_LABELS_ADD)
{
mpls_lsp_install (zvrf, type, in_label, out_label, gtype, &gate,
- NULL, 0);
+ NULL, ifindex);
if (out_label != MPLS_IMP_NULL_LABEL)
- mpls_ftn_update (1, zvrf, type, &prefix, &gate, distance, out_label);
+ mpls_ftn_update (1, zvrf, type, &prefix, gtype, &gate, ifindex,
+ distance, out_label);
}
else if (command == ZEBRA_MPLS_LABELS_DELETE)
{
- mpls_lsp_uninstall (zvrf, type, in_label, gtype, &gate, NULL, 0);
+ mpls_lsp_uninstall (zvrf, type, in_label, gtype, &gate, NULL, ifindex);
if (out_label != MPLS_IMP_NULL_LABEL)
- mpls_ftn_update (0, zvrf, type, &prefix, &gate, distance, out_label);
+ mpls_ftn_update (0, zvrf, type, &prefix, gtype, &gate, ifindex,
+ distance, out_label);
}
}
@@ -1806,7 +1859,7 @@ zebra_client_create (int sock)
/* Set table number. */
client->rtm_table = zebrad.rtm_table_default;
- client->connect_time = quagga_monotime();
+ client->connect_time = monotime(NULL);
/* Initialize flags */
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
@@ -1932,7 +1985,7 @@ zebra_client_read (struct thread *thread)
zlog_debug ("zebra message received [%s] %d in VRF %u",
zserv_command_string (command), length, vrf_id);
- client->last_read_time = quagga_monotime();
+ client->last_read_time = monotime(NULL);
client->last_read_cmd = command;
zvrf = zebra_vrf_lookup_by_id (vrf_id);
@@ -2031,6 +2084,9 @@ zebra_client_read (struct thread *thread)
case ZEBRA_MPLS_LABELS_DELETE:
zread_mpls_labels (command, client, length, vrf_id);
break;
+ case ZEBRA_IPMR_ROUTE_STATS:
+ zebra_ipmr_route_stats (client, sock, length, zvrf);
+ break;
default:
zlog_info ("Zebra received unknown command %d", command);
break;
@@ -2113,7 +2169,7 @@ zebra_serv ()
sockopt_reuseport (accept_sock);
if ( zserv_privs.change(ZPRIVS_RAISE) )
- zlog (NULL, LOG_ERR, "Can't raise privileges");
+ zlog_err("Can't raise privileges");
ret = bind (accept_sock, (struct sockaddr *)&addr,
sizeof (struct sockaddr_in));
@@ -2127,7 +2183,7 @@ zebra_serv ()
}
if ( zserv_privs.change(ZPRIVS_LOWER) )
- zlog (NULL, LOG_ERR, "Can't lower privileges");
+ zlog_err("Can't lower privileges");
ret = listen (accept_sock, 1);
if (ret < 0)
@@ -2243,7 +2299,7 @@ zserv_time_buf(time_t *time1, char *buf, int buflen)
return (buf);
}
- now = quagga_monotime();
+ now = monotime(NULL);
now -= *time1;
tm = gmtime(&now);
@@ -2351,7 +2407,22 @@ zebra_show_client_brief (struct vty *vty, struct zserv *client)
}
+struct zserv *
+zebra_find_client (u_char proto)
+{
+ struct listnode *node, *nnode;
+ struct zserv *client;
+
+ for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
+ {
+ if (client->proto == proto)
+ return client;
+ }
+
+ return NULL;
+}
+#ifdef HAVE_NETLINK
/* Display default rtm_table for all clients. */
DEFUN (show_table,
show_table_cmd,
@@ -2364,19 +2435,19 @@ DEFUN (show_table,
return CMD_SUCCESS;
}
-DEFUN (config_table,
+DEFUN (config_table,
config_table_cmd,
"table TABLENO",
"Configure target kernel routing table\n"
"TABLE integer\n")
{
- zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10);
+ zebrad.rtm_table_default = strtol (argv[1]->arg, (char**)0, 10);
return CMD_SUCCESS;
}
DEFUN (no_config_table,
no_config_table_cmd,
- "no table TABLENO",
+ "no table [TABLENO]",
NO_STR
"Configure target kernel routing table\n"
"TABLE integer\n")
@@ -2384,6 +2455,7 @@ DEFUN (no_config_table,
zebrad.rtm_table_default = 0;
return CMD_SUCCESS;
}
+#endif
DEFUN (ip_forwarding,
ip_forwarding_cmd,
@@ -2433,8 +2505,8 @@ DEFUN (show_zebra_client,
show_zebra_client_cmd,
"show zebra client",
SHOW_STR
- "Zebra information"
- "Client information")
+ "Zebra information\n"
+ "Client information\n")
{
struct listnode *node;
struct zserv *client;
@@ -2450,8 +2522,9 @@ DEFUN (show_zebra_client_summary,
show_zebra_client_summary_cmd,
"show zebra client summary",
SHOW_STR
- "Zebra information brief"
- "Client information brief")
+ "Zebra information brief\n"
+ "Client information brief\n"
+ "Brief Summary\n")
{
struct listnode *node;
struct zserv *client;
@@ -2505,7 +2578,6 @@ DEFUN (show_ip_forwarding,
return CMD_SUCCESS;
}
-#ifdef HAVE_IPV6
/* Only display ipv6 forwarding is enabled or not. */
DEFUN (show_ipv6_forwarding,
show_ipv6_forwarding_cmd,
@@ -2579,8 +2651,6 @@ DEFUN (no_ipv6_forwarding,
return CMD_SUCCESS;
}
-#endif /* HAVE_IPV6 */
-
/* IPForwarding configuration write function. */
static int
config_write_forwarding (struct vty *vty)
@@ -2590,10 +2660,8 @@ config_write_forwarding (struct vty *vty)
if (!ipforward ())
vty_out (vty, "no ip forwarding%s", VTY_NEWLINE);
-#ifdef HAVE_IPV6
if (!ipforward_ipv6 ())
vty_out (vty, "no ipv6 forwarding%s", VTY_NEWLINE);
-#endif /* HAVE_IPV6 */
vty_out (vty, "!%s", VTY_NEWLINE);
return 0;
}
@@ -2651,11 +2719,9 @@ zebra_init (void)
install_element (CONFIG_NODE, &no_config_table_cmd);
#endif /* HAVE_NETLINK */
-#ifdef HAVE_IPV6
install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
install_element (CONFIG_NODE, &ipv6_forwarding_cmd);
install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
-#endif /* HAVE_IPV6 */
/* Route-map */
zebra_route_map_init ();