📄 zserv.c
字号:
intzsend_ipv6_add_multipath (struct zserv *client, struct prefix *p, struct rib *rib){ int psize; struct stream *s; struct nexthop *nexthop; struct in6_addr empty; memset (&empty, 0, sizeof (struct in6_addr)); s = client->obuf; stream_reset (s); /* Place holder for size. */ stream_putw (s, 0); /* Put command, type and nexthop. */ stream_putc (s, ZEBRA_IPV6_ROUTE_ADD); stream_putc (s, rib->type); stream_putc (s, rib->flags); stream_putc (s, ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_IFINDEX | ZAPI_MESSAGE_METRIC); /* Prefix. */ psize = PSIZE (p->prefixlen); stream_putc (s, p->prefixlen); stream_write (s, (u_char *) &p->u.prefix, psize); /* Nexthop */ for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) { if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) { stream_putc (s, 1); if (nexthop->type == NEXTHOP_TYPE_IPV6) stream_write (s, (u_char *) &nexthop->gate.ipv6, 16); else stream_write (s, (u_char *) &empty, 16); /* Interface index. */ stream_putc (s, 1); stream_putl (s, nexthop->ifindex); break; } } /* Metric */ stream_putl (s, rib->metric); /* Write packet size. */ stream_putw_at (s, 0, stream_get_endp (s)); zebra_server_send_message (client->sock, s->data, stream_get_endp (s)); return 0;}intzsend_ipv6_delete (struct zserv *client, int type, int flags, struct prefix_ipv6 *p, struct in6_addr *nexthop, unsigned int ifindex){ int psize; struct stream *s; s = client->obuf; stream_reset (s); /* Place holder for size. */ stream_putw (s, 0); /* Put command, type and nexthop. */ stream_putc (s, ZEBRA_IPV6_ROUTE_DELETE); stream_putc (s, type); stream_putc (s, flags); stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX); /* Prefix. */ psize = PSIZE (p->prefixlen); stream_putc (s, p->prefixlen); stream_write (s, (u_char *)&p->prefix, psize); /* Nexthop */ stream_putc (s, 1); stream_write (s, (u_char *)nexthop, 16); /* Interface index. */ stream_putc (s, 1); stream_putl (s, ifindex); /* Write packet size. */ stream_putw_at (s, 0, stream_get_endp (s)); zebra_server_send_message (client->sock, s->data, stream_get_endp (s)); return 0;}intzsend_ipv6_delete_multipath (struct zserv *client, struct prefix *p, struct rib *rib){ int psize; struct stream *s; struct nexthop *nexthop; struct in6_addr empty; memset (&empty, 0, sizeof (struct in6_addr)); s = client->obuf; stream_reset (s); /* Place holder for size. */ stream_putw (s, 0); /* Put command, type and nexthop. */ stream_putc (s, ZEBRA_IPV6_ROUTE_DELETE); stream_putc (s, rib->type); stream_putc (s, rib->flags); stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX); /* Prefix. */ psize = PSIZE (p->prefixlen); stream_putc (s, p->prefixlen); stream_write (s, (u_char *)&p->u.prefix, psize); /* Nexthop */ for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) { if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) { stream_putc (s, 1); if (nexthop->type == NEXTHOP_TYPE_IPV6) stream_write (s, (u_char *) &nexthop->gate.ipv6, 16); else stream_write (s, (u_char *) &empty, 16); /* Interface index. */ stream_putc (s, 1); stream_putl (s, nexthop->ifindex); break; } } /* Write packet size. */ stream_putw_at (s, 0, stream_get_endp (s)); zebra_server_send_message (client->sock, s->data, stream_get_endp (s)); return 0;}intzsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr){ struct stream *s; struct rib *rib; unsigned long nump; u_char num; struct nexthop *nexthop; /* Lookup nexthop. */ rib = rib_match_ipv6 (addr); /* Get output stream. */ s = client->obuf; stream_reset (s); /* Fill in result. */ stream_putw (s, 0); stream_putc (s, ZEBRA_IPV6_NEXTHOP_LOOKUP); stream_put (s, &addr, 16); if (rib) { stream_putl (s, rib->metric); num = 0; nump = s->putp; stream_putc (s, 0); for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) { stream_putc (s, nexthop->type); switch (nexthop->type) { case ZEBRA_NEXTHOP_IPV6: stream_put (s, &nexthop->gate.ipv6, 16); break; case ZEBRA_NEXTHOP_IPV6_IFINDEX: case ZEBRA_NEXTHOP_IPV6_IFNAME: stream_put (s, &nexthop->gate.ipv6, 16); stream_putl (s, nexthop->ifindex); break; case ZEBRA_NEXTHOP_IFINDEX: case ZEBRA_NEXTHOP_IFNAME: stream_putl (s, nexthop->ifindex); break; } num++; } stream_putc_at (s, nump, num); } else { stream_putl (s, 0); stream_putc (s, 0); } stream_putw_at (s, 0, stream_get_endp (s)); zebra_server_send_message (client->sock, s->data, stream_get_endp (s)); return 0;}#endif /* HAVE_IPV6 */intzsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr){ struct stream *s; struct rib *rib; unsigned long nump; u_char num; struct nexthop *nexthop; /* Lookup nexthop. */ rib = rib_match_ipv4 (addr); /* Get output stream. */ s = client->obuf; stream_reset (s); /* Fill in result. */ stream_putw (s, 0); stream_putc (s, ZEBRA_IPV4_NEXTHOP_LOOKUP); stream_put_in_addr (s, &addr); if (rib) { stream_putl (s, rib->metric); num = 0; nump = s->putp; stream_putc (s, 0); for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) { stream_putc (s, nexthop->type); switch (nexthop->type) { case ZEBRA_NEXTHOP_IPV4: stream_put_in_addr (s, &nexthop->gate.ipv4); break; case ZEBRA_NEXTHOP_IFINDEX: case ZEBRA_NEXTHOP_IFNAME: stream_putl (s, nexthop->ifindex); break; } num++; } stream_putc_at (s, nump, num); } else { stream_putl (s, 0); stream_putc (s, 0); } stream_putw_at (s, 0, stream_get_endp (s)); zebra_server_send_message (client->sock, s->data, stream_get_endp (s)); return 0;}intzsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p){ struct stream *s; struct rib *rib; unsigned long nump; u_char num; struct nexthop *nexthop; /* Lookup nexthop. */ rib = rib_lookup_ipv4 (p); /* Get output stream. */ s = client->obuf; stream_reset (s); /* Fill in result. */ stream_putw (s, 0); stream_putc (s, ZEBRA_IPV4_IMPORT_LOOKUP); stream_put_in_addr (s, &p->prefix); if (rib) { stream_putl (s, rib->metric); num = 0; nump = s->putp; stream_putc (s, 0); for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) { stream_putc (s, nexthop->type); switch (nexthop->type) { case ZEBRA_NEXTHOP_IPV4: stream_put_in_addr (s, &nexthop->gate.ipv4); break; case ZEBRA_NEXTHOP_IFINDEX: case ZEBRA_NEXTHOP_IFNAME: stream_putl (s, nexthop->ifindex); break; } num++; } stream_putc_at (s, nump, num); } else { stream_putl (s, 0); stream_putc (s, 0); } stream_putw_at (s, 0, stream_get_endp (s)); zebra_server_send_message (client->sock, s->data, stream_get_endp (s)); return 0;}/* Register zebra server interface information. Send current all interface and address information. */voidzread_interface_add (struct zserv *client, u_short length){ listnode ifnode; listnode cnode; struct interface *ifp; struct connected *c; /* Interface information is needed. */ client->ifinfo = 1; for (ifnode = listhead (iflist); ifnode; ifnode = nextnode (ifnode)) { ifp = getdata (ifnode); /* Skip pseudo interface. */ if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)) continue; zsend_interface_add (client, ifp); for (cnode = listhead (ifp->connected); cnode; nextnode (cnode)) { c = getdata (cnode); if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL)) zsend_interface_address_add (client, ifp, c); } }}/* Unregister zebra server interface information. */voidzread_interface_delete (struct zserv *client, u_short length){ client->ifinfo = 0;}/* This function support multiple nexthop. */voidzread_ipv4_add (struct zserv *client, u_short length){ int i; struct rib *rib; struct prefix_ipv4 p; u_char message; struct in_addr nexthop; u_char nexthop_num; u_char nexthop_type; struct stream *s; unsigned int ifindex; u_char ifname_len; /* Get input stream. */ s = client->ibuf; /* Allocate new rib. */ rib = XMALLOC (MTYPE_RIB, sizeof (struct rib)); memset (rib, 0, sizeof (struct rib)); /* Type, flags, message. */ rib->type = stream_getc (s); rib->flags = stream_getc (s); message = stream_getc (s); rib->uptime = time (NULL); /* IPv4 prefix. */ memset (&p, 0, sizeof (struct prefix_ipv4)); p.family = AF_INET; p.prefixlen = stream_getc (s); stream_get (&p.prefix, s, PSIZE (p.prefixlen)); /* Nexthop parse. */ if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP)) { nexthop_num = stream_getc (s); for (i = 0; i < nexthop_num; i++) { nexthop_type = stream_getc (s); switch (nexthop_type) { case ZEBRA_NEXTHOP_IFINDEX: ifindex = stream_getl (s); nexthop_ifindex_add (rib, ifindex); break; case ZEBRA_NEXTHOP_IFNAME: ifname_len = stream_getc (s); stream_forward (s, ifname_len); break; case ZEBRA_NEXTHOP_IPV4: nexthop.s_addr = stream_get_ipv4 (s); nexthop_ipv4_add (rib, &nexthop); break; case ZEBRA_NEXTHOP_IPV6: stream_forward (s, IPV6_MAX_BYTELEN); break; case ZEBRA_NEXTHOP_BLACKHOLE: nexthop_blackhole_add (rib); break; } } } /* Distance. */ if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE)) rib->distance = stream_getc (s); /* Metric. */ if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC)) rib->metric = stream_getl (s); rib_add_ipv4_multipath (&p, rib);}/* Zebra server IPv4 prefix delete function. */voidzread_ipv4_delete (struct zserv *client, u_short length){ int i; struct stream *s; struct zapi_ipv4 api; struct in_addr nexthop; unsigned long ifindex; struct prefix_ipv4 p; u_char nexthop_num; u_char nexthop_type; u_char ifname_len; s = client->ibuf; ifindex = 0; nexthop.s_addr = 0; /* Type, flags, message. */ api.type = stream_getc (s); api.flags = stream_getc (s); api.message = stream_getc (s); /* IPv4 prefix. */ memset (&p, 0, sizeof (struct prefix_ipv4)); p.family = AF_INET; p.prefixlen = stream_getc (s); stream_get (&p.prefix, s, PSIZE (p.prefixlen)); /* Nexthop, ifindex, distance, metric. */ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) { nexthop_num = stream_getc (s); for (i = 0; i < nexthop_num; i++) { nexthop_type = stream_getc (s); switch (nexthop_type) { case ZEBRA_NEXTHOP_IFINDEX: ifindex = stream_getl (s); break; case ZEBRA_NEXTHOP_IFNAME: ifname_len = stream_getc (s); stream_forward (s, ifname_len); break; case ZEBRA_NEXTHOP_IPV4: nexthop.s_addr = stream_get_ipv4 (s); break; case ZEBRA_NEXTHOP_IPV6: stream_forward (s, IPV6_MAX_BYTELEN); break; } } } /* Distance. */ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) api.distance = stream_getc (s); else api.distance = 0; /* Metric. */ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) api.metric = stream_getl (s); else api.metric = 0; rib_delete_ipv4 (api.type, api.flags, &p, &nexthop, ifindex, client->rtm_table);}/* Nexthop lookup for IPv4. */voidzread_ipv4_nexthop_lookup (struct zserv *client, u_short length){ struct in_addr addr; addr.s_addr = stream_get_ipv4 (client->ibuf); zsend_ipv4_nexthop_lookup (client, addr);}/* Nexthop lookup for IPv4. */voidzread_ipv4_import_lookup (struct zserv *client, u_short length){ struct prefix_ipv4 p; p.family = AF_INET; p.prefixlen = stream_getc (client->ibuf); p.prefix.s_addr = stream_get_ipv4 (client->ibuf); zsend_ipv4_import_lookup (client, &p);}#ifdef HAVE_IPV6/* Zebra server IPv6 prefix add function. */voidzread_ipv6_add (struct zserv *client, u_short length){ int i; struct stream *s; struct zapi_ipv6 api; struct in6_addr nexthop; unsigned long ifindex; struct prefix_ipv6 p; s = client->ibuf; ifindex = 0; memset (&nexthop, 0, sizeof (struct in6_addr)); /* Type, flags, message. */ api.type = stream_getc (s); api.flags = stream_getc (s); api.message = stream_getc (s); /* IPv4 prefix. */ memset (&p, 0, sizeof (struct prefix_ipv6)); p.family = AF_INET6; p.prefixlen = stream_getc (s); stream_get (&p.prefix, s, PSIZE (p.prefixlen)); /* Nexthop, ifindex, distance, metric. */ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) { u_char nexthop_type; api.nexthop_num = stream_getc (s); for (i = 0; i < api.nexthop_num; i++) { nexthop_type = stream_getc (s); switch (nexthop_type) { case ZEBRA_NEXTHOP_IPV6: stream_get (&nexthop, s, 16); break; case ZEBRA_NEXTHOP_IFINDEX: ifindex = stream_getl (s); break; } } } if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) api.distance = stream_getc (s); else api.distance = 0; if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) api.metric = stream_getl (s); else api.metric = 0; if (IN6_IS_ADDR_UNSPECIFIED (&nexthop)) rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0); else rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0);}/* Zebra server IPv6 prefix delete function. */voidzread_ipv6_delete (struct zserv *client, u_short length){ int i; struct stream *s; struct zapi_ipv6 api; struct in6_addr nexthop; unsigned long ifindex; struct prefix_ipv6 p; s = client->ibuf; ifindex = 0; memset (&nexthop, 0, sizeof (struct in6_addr)); /* Type, flags, message. */ api.type = stream_getc (s); api.flags = stream_getc (s); api.message = stream_getc (s); /* IPv4 prefix. */ memset (&p, 0, sizeof (struct prefix_ipv6)); p.family = AF_INET6; p.prefixlen = stream_getc (s); stream_get (&p.prefix, s, PSIZE (p.prefixlen)); /* Nexthop, ifindex, distance, metric. */ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) { u_char nexthop_type; api.nexthop_num = stream_getc (s); for (i = 0; i < api.nexthop_num; i++) { nexthop_type = stream_getc (s); switch (nexthop_type)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -