📄 zclient.c
字号:
} } if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE)) stream_putc (s, api->distance); if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC)) stream_putl (s, api->metric); /* Put length at the first point of the stream. */ stream_putw_at (s, 0, stream_get_endp (s)); return writen (zclient->sock, s->data, stream_get_endp (s));}intzapi_ipv6_delete (struct zclient *zclient, struct prefix_ipv6 *p, struct zapi_ipv6 *api){ int i; int psize; struct stream *s; /* Reset stream. */ s = zclient->obuf; stream_reset (s); /* Length place holder. */ stream_putw (s, 0); /* Put command, type and nexthop. */ stream_putc (s, ZEBRA_IPV6_ROUTE_DELETE); stream_putc (s, api->type); stream_putc (s, api->flags); stream_putc (s, api->message); /* Put prefix information. */ psize = PSIZE (p->prefixlen); stream_putc (s, p->prefixlen); stream_write (s, (u_char *)&p->prefix, psize); /* Nexthop, ifindex, distance and metric information. */ if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP)) { stream_putc (s, api->nexthop_num + api->ifindex_num); for (i = 0; i < api->nexthop_num; i++) { stream_putc (s, ZEBRA_NEXTHOP_IPV6); stream_write (s, (u_char *)api->nexthop[i], 16); } for (i = 0; i < api->ifindex_num; i++) { stream_putc (s, ZEBRA_NEXTHOP_IFINDEX); stream_putl (s, api->ifindex[i]); } } if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE)) stream_putc (s, api->distance); if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC)) stream_putl (s, api->metric); /* Put length at the first point of the stream. */ stream_putw_at (s, 0, stream_get_endp (s)); return writen (zclient->sock, s->data, stream_get_endp (s));}#endif /* HAVE_IPV6 */intzebra_redistribute_send (int command, int sock, int type){ int ret; struct stream *s; s = stream_new (ZEBRA_MAX_PACKET_SIZ); /* Total length of the messages. */ stream_putw (s, 4); stream_putc (s, command); stream_putc (s, type); ret = writen (sock, s->data, 4); stream_free (s); return ret;}/* Interface addition from zebra daemon. */struct interface *zebra_interface_add_read (struct stream *s){ struct interface *ifp; u_char ifname_tmp[INTERFACE_NAMSIZ]; /* Read interface name. */ stream_get (ifname_tmp, s, INTERFACE_NAMSIZ); /* Lookup this by interface name. */ ifp = if_lookup_by_name (ifname_tmp); /* If such interface does not exist, make new one. */ if (! ifp) { ifp = if_create (); strncpy (ifp->name, ifname_tmp, IFNAMSIZ); } /* Read interface's index. */ ifp->ifindex = stream_getl (s); /* Read interface's value. */ ifp->flags = stream_getl (s); ifp->metric = stream_getl (s); ifp->mtu = stream_getl (s); ifp->bandwidth = stream_getl (s);#ifdef HAVE_SOCKADDR_DL stream_get (&ifp->sdl, s, sizeof (ifp->sdl));#else ifp->hw_addr_len = stream_getl (s); if (ifp->hw_addr_len) stream_get (ifp->hw_addr, s, ifp->hw_addr_len);#endif /* HAVE_SOCKADDR_DL */ return ifp;}/* Read interface up/down msg from zebra daemon. */struct interface *zebra_interface_state_read (struct stream *s){ struct interface *ifp; u_char ifname_tmp[INTERFACE_NAMSIZ]; /* Read interface name. */ stream_get (ifname_tmp, s, INTERFACE_NAMSIZ); /* Lookup this by interface index. */ ifp = if_lookup_by_name (ifname_tmp); /* If such interface does not exist, indicate an error */ if (! ifp) return NULL; /* Read interface's index. */ ifp->ifindex = stream_getl (s); /* Read interface's value. */ ifp->flags = stream_getl (s); ifp->metric = stream_getl (s); ifp->mtu = stream_getl (s); ifp->bandwidth = stream_getl (s); return ifp;}struct connected *zebra_interface_address_add_read (struct stream *s){ unsigned int ifindex; struct interface *ifp; struct connected *ifc; struct prefix *p; int family; int plen; /* Get interface index. */ ifindex = stream_getl (s); /* Lookup index. */ ifp = if_lookup_by_index (ifindex); if (ifp == NULL) { zlog_warn ("zebra_interface_address_add_read: Can't find interface by ifindex: %d ", ifindex); return NULL; } /* Allocate new connected address. */ ifc = connected_new (); ifc->ifp = ifp; /* Fetch flag. */ ifc->flags = stream_getc (s); /* Fetch interface address. */ p = prefix_new (); family = p->family = stream_getc (s); plen = prefix_blen (p); stream_get (&p->u.prefix, s, plen); p->prefixlen = stream_getc (s); ifc->address = p; /* Fetch destination address. */ p = prefix_new (); stream_get (&p->u.prefix, s, plen); p->family = family; ifc->destination = p; p = ifc->address; /* Add connected address to the interface. */ listnode_add (ifp->connected, ifc); return ifc;}struct connected *zebra_interface_address_delete_read (struct stream *s){ unsigned int ifindex; struct interface *ifp; struct connected *ifc; struct prefix p; struct prefix d; int family; int len; u_char flags; /* Get interface index. */ ifindex = stream_getl (s); /* Lookup index. */ ifp = if_lookup_by_index (ifindex); if (ifp == NULL) { zlog_warn ("zebra_interface_address_delete_read: Can't find interface by ifindex: %d ", ifindex); return NULL; } /* Fetch flag. */ flags = stream_getc (s); /* Fetch interface address. */ family = p.family = stream_getc (s); len = prefix_blen (&p); stream_get (&p.u.prefix, s, len); p.prefixlen = stream_getc (s); /* Fetch destination address. */ stream_get (&d.u.prefix, s, len); d.family = family; ifc = connected_delete_by_prefix (ifp, &p); return ifc;}/* Zebra client message read function. */intzclient_read (struct thread *thread){ int ret; int nbytes; int sock; zebra_size_t length; zebra_command_t command; struct zclient *zclient; /* Get socket to zebra. */ sock = THREAD_FD (thread); zclient = THREAD_ARG (thread); zclient->t_read = NULL; /* Clear input buffer. */ stream_reset (zclient->ibuf); /* Read zebra header. */ nbytes = stream_read (zclient->ibuf, sock, ZEBRA_HEADER_SIZE); /* zebra socket is closed. */ if (nbytes == 0) { if (zclient_debug) zlog_info ("zclient connection closed socket [%d].", sock); zclient->fail++; zclient_stop (zclient); zclient_event (ZCLIENT_CONNECT, zclient); return -1; } /* zebra read error. */ if (nbytes < 0 || nbytes != ZEBRA_HEADER_SIZE) { if (zclient_debug) zlog_info ("Can't read all packet (length %d).", nbytes); zclient->fail++; zclient_stop (zclient); zclient_event (ZCLIENT_CONNECT, zclient); return -1; } /* Fetch length and command. */ length = stream_getw (zclient->ibuf); command = stream_getc (zclient->ibuf); /* Length check. */ if (length >= zclient->ibuf->size) { stream_free (zclient->ibuf); zclient->ibuf = stream_new (length + 1); } length -= ZEBRA_HEADER_SIZE; /* Read rest of zebra packet. */ nbytes = stream_read (zclient->ibuf, sock, length); if (nbytes != length) { if (zclient_debug) zlog_info ("zclient connection closed socket [%d].", sock); zclient->fail++; zclient_stop (zclient); zclient_event (ZCLIENT_CONNECT, zclient); return -1; } switch (command) { case ZEBRA_INTERFACE_ADD: if (zclient->interface_add) ret = (*zclient->interface_add) (command, zclient, length); break; case ZEBRA_INTERFACE_DELETE: if (zclient->interface_delete) ret = (*zclient->interface_delete) (command, zclient, length); break; case ZEBRA_INTERFACE_ADDRESS_ADD: if (zclient->interface_address_add) ret = (*zclient->interface_address_add) (command, zclient, length); break; case ZEBRA_INTERFACE_ADDRESS_DELETE: if (zclient->interface_address_delete) ret = (*zclient->interface_address_delete) (command, zclient, length); break; case ZEBRA_INTERFACE_UP: if (zclient->interface_up) ret = (*zclient->interface_up) (command, zclient, length); break; case ZEBRA_INTERFACE_DOWN: if (zclient->interface_down) ret = (*zclient->interface_down) (command, zclient, length); break; case ZEBRA_IPV4_ROUTE_ADD: if (zclient->ipv4_route_add) ret = (*zclient->ipv4_route_add) (command, zclient, length); break; case ZEBRA_IPV4_ROUTE_DELETE: if (zclient->ipv4_route_delete) ret = (*zclient->ipv4_route_delete) (command, zclient, length); break; case ZEBRA_IPV6_ROUTE_ADD: if (zclient->ipv6_route_add) ret = (*zclient->ipv6_route_add) (command, zclient, length); break; case ZEBRA_IPV6_ROUTE_DELETE: if (zclient->ipv6_route_delete) ret = (*zclient->ipv6_route_delete) (command, zclient, length); break; default: break; } /* Register read thread. */ zclient_event (ZCLIENT_READ, zclient); return 0;}voidzclient_redistribute_set (struct zclient *zclient, int type){ if (zclient->redist[type]) return; zclient->redist[type] = 1; if (zclient->sock > 0) zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient->sock, type);}voidzclient_redistribute_unset (struct zclient *zclient, int type){ if (! zclient->redist[type]) return; zclient->redist[type] = 0; if (zclient->sock > 0) zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient->sock, type);}voidzclient_redistribute_default_set (struct zclient *zclient){ if (zclient->default_information) return; zclient->default_information = 1; if (zclient->sock > 0) zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD);}voidzclient_redistribute_default_unset (struct zclient *zclient){ if (! zclient->default_information) return; zclient->default_information = 0; if (zclient->sock > 0) zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_DELETE);}extern struct thread_master *master;static voidzclient_event (enum event event, struct zclient *zclient){ switch (event) { case ZCLIENT_SCHEDULE: if (! zclient->t_connect) zclient->t_connect = thread_add_event (master, zclient_connect, zclient, 0); break; case ZCLIENT_CONNECT: if (zclient->fail >= 10) return; if (zclient_debug) zlog_info ("zclient connect schedule interval is %d", zclient->fail < 3 ? 10 : 60); if (! zclient->t_connect) zclient->t_connect = thread_add_timer (master, zclient_connect, zclient, zclient->fail < 3 ? 10 : 60); break; case ZCLIENT_READ: zclient->t_read = thread_add_read (master, zclient_read, zclient, zclient->sock); break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -