diff options
Diffstat (limited to 'zebra/zserv.c')
| -rw-r--r-- | zebra/zserv.c | 174 |
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 (); |
