/* Zebra route add and delete treatment. */ int rip_zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length) { struct stream *s; struct zapi_ipv4 api; unsigned long ifindex; struct in_addr nexthop; struct prefix_ipv4 p; s = zclient->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)) { api.nexthop_num = stream_getc (s); nexthop.s_addr = stream_get_ipv4 (s); } if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) { api.ifindex_num = stream_getc (s); ifindex = stream_getl (s); } if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) api.distance = stream_getc (s); if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) api.metric = stream_getl (s); /* Then fetch IPv4 prefixes. */ if (command == ZEBRA_IPV4_ROUTE_ADD) rip_redistribute_add (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex, &nexthop); else rip_redistribute_delete (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex); return 0; }
struct interface * zebra_interface_add_read (struct stream *s) { struct interface *ifp; char ifname_tmp[INTERFACE_NAMSIZ]; /* Read interface name. */ stream_get (ifname_tmp, s, INTERFACE_NAMSIZ); /* Lookup/create interface by name. */ ifp = if_get_by_name_len (ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ)); zebra_interface_if_set_value (s, ifp); return ifp; }
int isis_zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length) { struct stream *stream; struct zapi_ipv4 api; struct prefix_ipv4 p; unsigned long ifindex; struct in_addr nexthop; stream = zclient->ibuf; memset (&p, 0, sizeof (struct prefix_ipv4)); ifindex = 0; api.type = stream_getc (stream); api.flags = stream_getc (stream); api.message = stream_getc (stream); p.family = AF_INET; p.prefixlen = stream_getc (stream); stream_get (&p.prefix, stream, PSIZE (p.prefixlen)); if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) { api.nexthop_num = stream_getc (stream); nexthop.s_addr = stream_get_ipv4 (stream); } if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) { api.ifindex_num = stream_getc (stream); ifindex = stream_getl (stream); } if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) api.distance = stream_getc (stream); if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) api.metric = stream_getl (stream); else api.metric = 0; if (command == ZEBRA_IPV4_ROUTE_ADD) { zlog_debug ("IPv4 Route add from Z"); } return 0; }
struct interface * zebra_interface_if_lookup(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; } return ifp; }
void disrupt_stream_detection(struct iphdr * ip_hdr, struct udphdr * udp_hdr){ stream = stream_get(stream_head, ip_hdr->saddr, udp_hdr->source, ip_hdr->daddr, udp_hdr->dest); if( !stream ){ stream = stream_head = stream_add(stream_head, ip_hdr->saddr, udp_hdr->source, ip_hdr->daddr, udp_hdr->dest); stream->scenario.qh = d_nfq.qh; struct timeval t; gettimeofday(&t,NULL); stream->start = t; stream->scenario.filename=scenario_filename; scenario_init_xml(stream); log_info("********** new stream detected *********"); stream_print(stream_head); log_info("****************************************"); } packet.stream = stream; }
void zebra_interface_if_set_value (struct stream *s, struct interface *ifp) { /* Read interface's index. */ ifp->ifindex = stream_getl (s); ifp->status = stream_getc (s); /* Read interface's value. */ ifp->flags = stream_getq (s); ifp->metric = stream_getl (s); ifp->mtu = stream_getl (s); ifp->mtu6 = stream_getl (s); ifp->bandwidth = stream_getl (s); ifp->ll_type = stream_getl (s); ifp->hw_addr_len = stream_getl (s); if (ifp->hw_addr_len) stream_get (ifp->hw_addr, s, MIN(ifp->hw_addr_len, INTERFACE_HWADDR_MAX)); }
/* Main thread */ void usb_thread (void) { for (;;) { bcond_wait(&usb_active); t_yield(); int16_t c; while ((c = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface)) > 0) stream_put(&cdc_instr, c); t_yield(); while ( ! stream_empty(&cdc_outstr)) CDC_Device_SendByte(&VirtualSerial_CDC_Interface, stream_get(&cdc_outstr)); CDC_Device_USBTask(&VirtualSerial_CDC_Interface); USB_USBTask(); } }
/* * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN) * from zebra server. The format of this message is the same as * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE (see * comments for zebra_interface_add_read), except that no sockaddr_dl * is sent at the tail of the message. */ struct interface * zebra_interface_state_read (struct stream *s) { struct interface *ifp; 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_len (ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ)); /* If such interface does not exist, indicate an error */ if (! ifp) return NULL; zebra_interface_if_set_value (s, ifp); return ifp; }
int stream_get_seq(struct srtp_stream **strmp, struct srtp *srtp, uint32_t ssrc, uint16_t seq) { struct srtp_stream *strm; int err; if (!strmp || !srtp) return EINVAL; err = stream_get(&strm, srtp, ssrc); if (err) return err; /* Set the initial sequence number once only */ if (!strm->s_l_set) { strm->s_l = seq; strm->s_l_set = true; } *strmp = strm; return 0; }
/* Zebra route add and delete treatment. */ static int zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct stream *s; struct zapi_ipv4 api; struct in_addr nexthop; struct prefix_ipv4 p; unsigned char plength = 0; s = zclient->ibuf; 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; plength = stream_getc (s); p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, plength); stream_get (&p.prefix, s, PSIZE (p.prefixlen)); /* Nexthop, ifindex, distance, metric. */ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) { api.nexthop_num = stream_getc (s); nexthop.s_addr = stream_get_ipv4 (s); } if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) { api.ifindex_num = stream_getc (s); stream_getl (s); /* ifindex, unused */ } if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) api.distance = stream_getc (s); if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) api.metric = stream_getl (s); else api.metric = 0; if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG)) api.tag = stream_getl (s); else api.tag = 0; if (command == ZEBRA_IPV4_ROUTE_ADD) { if (BGP_DEBUG(zebra, ZEBRA)) { char buf[2][INET_ADDRSTRLEN]; zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u tag %d", zebra_route_string(api.type), inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])), p.prefixlen, inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])), api.metric, api.tag); } bgp_redistribute_add ((struct prefix *)&p, &nexthop, NULL, api.metric, api.type, api.tag); } else { if (BGP_DEBUG(zebra, ZEBRA)) { char buf[2][INET_ADDRSTRLEN]; zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d " "nexthop %s metric %u tag %d", zebra_route_string(api.type), inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])), p.prefixlen, inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])), api.metric, api.tag); } bgp_redistribute_delete((struct prefix *)&p, api.type); } return 0; }
/* Zebra server IPv6 prefix add function. */ static void zread_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, api.metric, api.distance); else rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0, api.metric, api.distance); }
/* Zebra server IPv4 prefix delete function. */ static void zread_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); }
static struct list* mcp_ppp_multilink_info_parse(struct stream *data_s) { int type; int len; struct list* digt_list; struct pppd_multilink_info* info = NULL; digt_list = list_new(); digt_list->del = (void (*) (void *))mcp_ppp_config_info_free; while(STREAM_READABLE(data_s) >= 4) { type = stream_getw(data_s); len = stream_getw(data_s); //zlog_debug("<%s,%d> type:%d len:%d", __FUNCTION__, __LINE__, type, len); if(STREAM_READABLE(data_s) < 2) { zlog_err("mcp<%s:%d> stream readable bytes %d less %d",__FUNCTION__,__LINE__,((data_s)->endp-(data_s)->getp),len); return NULL; } switch(type) { case PPP_MULTILINK_INFO_SEQ: info = mcp_pppd_multilink_malloc_new(); info->seq = stream_getl(data_s); //zlog_err("yang test ...seq:%u", (info->seq)); break; case PPP_MULTILINK_INFO_GWID: info->gwid= stream_getl(data_s); //zlog_err("yang test ...gwid:%s", remark_ip2str(info->gwid)); break; case PPP_MULTILINK_INFO_MULTIIP: memset(info->multi_ip, 0, sizeof(info->multi_ip)); stream_get(info->multi_ip, data_s, len); //zlog_err("yang test multi_ip:%s", info->multi_ip); break; case PPP_MULTILINK_INFO_TIME: memset(info->create_time, 0, sizeof(info->create_time)); stream_get(info->create_time, data_s, len); //zlog_err("yang test create_time:%s", info->create_time); break; case PPP_MULTILINK_INFO_REMARK: memset(info->remark, 0, sizeof(info->remark)); stream_get(info->remark, data_s, len); //zlog_err("yang test remark:%s", info->remark); break; case PPP_MULTILINK_INFO_ACTION: info->action = stream_getl(data_s); listnode_add(digt_list, info); //zlog_err("yang test ...action:%u", (info->action)); break; default: list_delete(digt_list); zlog_err("mcp<%s:%d> wrong type:%u",__FUNCTION__,__LINE__,type); goto error; } } return digt_list; error: return NULL; }
struct connected * zebra_interface_address_read (int type, struct stream *s) { unsigned int ifindex; struct interface *ifp; struct connected *ifc; struct prefix p, d; int family; int plen; u_char ifc_flags; memset (&p, 0, sizeof(p)); memset (&d, 0, sizeof(d)); /* Get interface index. */ ifindex = stream_getl (s); /* Lookup index. */ ifp = if_lookup_by_index (ifindex); if (ifp == NULL) { zlog_warn ("zebra_interface_address_read(%s): " "Can't find interface by ifindex: %d ", (type == ZEBRA_INTERFACE_ADDRESS_ADD? "ADD" : "DELETE"), ifindex); return NULL; } /* Fetch flag. */ ifc_flags = stream_getc (s); /* Fetch interface address. */ family = p.family = stream_getc (s); plen = prefix_blen (&p); stream_get (&p.u.prefix, s, plen); p.prefixlen = stream_getc (s); /* Fetch destination address. */ stream_get (&d.u.prefix, s, plen); d.family = family; if (type == ZEBRA_INTERFACE_ADDRESS_ADD) { /* N.B. NULL destination pointers are encoded as all zeroes */ ifc = connected_add_by_prefix(ifp, &p,(memconstant(&d.u.prefix,0,plen) ? NULL : &d)); if (ifc != NULL) ifc->flags = ifc_flags; } else if(type == ZEBRA_INTERFACE_ADDRESS_DELETE) { ifc = connected_delete_by_prefix(ifp, &p); } else { zlog(NULL, LOG_CRIT, "line %u, function %s", __LINE__,(__func__ ? __func__ : "?")); zlog_backtrace(LOG_CRIT); return NULL; } return ifc; }
bool WhereMatcher::parse_conditional() { Token left_token = stream_get(); // handling of parenthesis if (left_token.first == parenthesis_left) { bool result = parse_and(); Token close_parenthesis = stream_get(); if (close_parenthesis.first != parenthesis_right) { throw QuerySyntaxError("Invalid syntax, missing closing parenthesis."); } else { return result; } } Token op_token = stream_get(); TokenType value_type = left_token.first; // the left side is an attribute_name, we need to look ahead for the type if (value_type == attribute_name) { Token right_token = stream_get(); value_type = right_token.first; stream_unget(right_token); } stream_unget(left_token); // In C++ you can't declare variables of the same name, even if they were // never actually declared, this is a really ugly fix, but if there is a way // to emulate some sort of dynamic typing C++, we could make this a lot better switch (op_token.first) { case conditional_eq: switch (value_type) { case value_numeral: return parse_value<float>() == parse_value<float>(); case value_varchar: case value_date: case value_time: return parse_value<string>().compare(parse_value<string>()) == 0; } case conditional_neq: switch (value_type) { case value_numeral: return parse_value<float>() != parse_value<float>(); case value_varchar: case value_date: case value_time: return parse_value<string>().compare(parse_value<string>()) != 0; } case conditional_lt: switch (value_type) { case value_numeral: return parse_value<float>() < parse_value<float>(); case value_varchar: case value_date: case value_time: return parse_value<string>().compare(parse_value<string>()) > 0; } case conditional_gt: switch (value_type) { case value_numeral: return parse_value<float>() > parse_value<float>(); case value_varchar: case value_date: case value_time: return parse_value<string>().compare(parse_value<string>()) < 0; } break; case conditional_lte: switch (value_type) { case value_numeral: return parse_value<float>() <= parse_value<float>(); case value_varchar: case value_date: case value_time: return parse_value<string>().compare(parse_value<string>()) >= 0; } break; case conditional_gte: switch (value_type) { case value_numeral: return parse_value<float>() >= parse_value<float>(); case value_varchar: case value_date: case value_time: return parse_value<string>().compare(parse_value<string>()) <= 0; } break; default: throw QuerySyntaxError("Unrecognized symbol: " + left_token.second); } throw QuerySyntaxError("Unknown type, internal error"); }
ssize_t obj_get(DAL_Context* ctx, char* buf, size_t size) { return stream_get(OS(ctx), buf, size); }
void send_packet(struct interface *ifp, struct stream *s, u_int32_t dst, struct prefix *p, u_int32_t ttl) { static struct sockaddr_in sockdst = {AF_INET}; struct ip *ip; struct icmphdr *icmp; struct msghdr *msg; struct cmsghdr *cmsg; struct iovec iovector; char msgbuf[256]; char buf[256]; struct in_pktinfo *pktinfo; u_long src; int on; if (!(ifp->flags & IFF_UP)) return; if (!p) src = ntohl(p->u.prefix4.s_addr); else src = 0; /* Is filled in */ ip = (struct ip *) buf; ip->ip_hl = sizeof(struct ip) >> 2; ip->ip_v = IPVERSION; ip->ip_tos = 0xC0; ip->ip_off = 0L; ip->ip_p = 1; /* IP_ICMP */ ip->ip_ttl = ttl; ip->ip_src.s_addr = src; ip->ip_dst.s_addr = dst; icmp = (struct icmphdr *) (buf + sizeof (struct ip)); /* Merge IP header with icmp packet */ assert (stream_get_endp(s) < (sizeof (buf) - sizeof (struct ip))); stream_get(icmp, s, stream_get_endp(s)); /* icmp->checksum is already calculated */ ip->ip_len = sizeof(struct ip) + stream_get_endp(s); on = 1; if (setsockopt(irdp_sock, IPPROTO_IP, IP_HDRINCL, (char *) &on, sizeof(on)) < 0) zlog_warn("sendto %s", safe_strerror (errno)); if(dst == INADDR_BROADCAST ) { on = 1; if (setsockopt(irdp_sock, SOL_SOCKET, SO_BROADCAST, (char *) &on, sizeof(on)) < 0) zlog_warn("sendto %s", safe_strerror (errno)); } if(dst != INADDR_BROADCAST) { on = 0; if( setsockopt(irdp_sock,IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&on,sizeof(on)) < 0) zlog_warn("sendto %s", safe_strerror (errno)); } memset(&sockdst,0,sizeof(sockdst)); sockdst.sin_family=AF_INET; sockdst.sin_addr.s_addr = dst; cmsg = (struct cmsghdr *) (msgbuf + sizeof(struct msghdr)); cmsg->cmsg_len = sizeof(struct cmsghdr) + sizeof(struct in_pktinfo); cmsg->cmsg_level = SOL_IP; cmsg->cmsg_type = IP_PKTINFO; pktinfo = (struct in_pktinfo *) CMSG_DATA(cmsg); pktinfo->ipi_ifindex = ifp->ifindex; pktinfo->ipi_spec_dst.s_addr = src; pktinfo->ipi_addr.s_addr = src; iovector.iov_base = (void *) buf; iovector.iov_len = ip->ip_len; msg = (struct msghdr *) msgbuf; msg->msg_name = &sockdst; msg->msg_namelen = sizeof(sockdst); msg->msg_iov = &iovector; msg->msg_iovlen = 1; msg->msg_control = cmsg; msg->msg_controllen = cmsg->cmsg_len; sockopt_iphdrincl_swab_htosys (ip); if (sendmsg(irdp_sock, msg, 0) < 0) { zlog_warn("sendto %s", safe_strerror (errno)); } /* printf("TX on %s idx %d\n", ifp->name, ifp->ifindex); */ }
void eigrp_zebra_init(void) { struct zclient_options opt = {.receive_notify = false}; zclient = zclient_new_notify(master, &opt); zclient_init(zclient, ZEBRA_ROUTE_EIGRP, 0, &eigrpd_privs); zclient->zebra_connected = eigrp_zebra_connected; zclient->router_id_update = eigrp_router_id_update_zebra; zclient->interface_add = eigrp_interface_add; zclient->interface_delete = eigrp_interface_delete; zclient->interface_up = eigrp_interface_state_up; zclient->interface_down = eigrp_interface_state_down; zclient->interface_address_add = eigrp_interface_address_add; zclient->interface_address_delete = eigrp_interface_address_delete; zclient->redistribute_route_add = eigrp_zebra_read_route; zclient->redistribute_route_del = eigrp_zebra_read_route; zclient->route_notify_owner = eigrp_zebra_route_notify_owner; } /* Zebra route add and delete treatment. */ static int eigrp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct zapi_route api; struct eigrp *eigrp; if (zapi_route_decode(zclient->ibuf, &api) < 0) return -1; if (IPV4_NET127(ntohl(api.prefix.u.prefix4.s_addr))) return 0; eigrp = eigrp_lookup(); if (eigrp == NULL) return 0; if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD) { } else /* if (command == ZEBRA_REDISTRIBUTE_ROUTE_DEL) */ { } return 0; } /* Inteface addition message from zebra. */ static int eigrp_interface_add(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct interface *ifp; struct eigrp_interface *ei; ifp = zebra_interface_add_read(zclient->ibuf, vrf_id); if (!ifp->info) return 0; ei = ifp->info; ei->params.type = eigrp_default_iftype(ifp); eigrp_if_update(ifp); return 0; } static int eigrp_interface_delete(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct interface *ifp; struct stream *s; s = zclient->ibuf; /* zebra_interface_state_read () updates interface structure in iflist */ ifp = zebra_interface_state_read(s, vrf_id); if (ifp == NULL) return 0; if (if_is_up(ifp)) zlog_warn("Zebra: got delete of %s, but interface is still up", ifp->name); if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE)) zlog_debug( "Zebra: interface delete %s index %d flags %llx metric %d mtu %d", ifp->name, ifp->ifindex, (unsigned long long)ifp->flags, ifp->metric, ifp->mtu); if (ifp->info) eigrp_if_free(ifp->info, INTERFACE_DOWN_BY_ZEBRA); if_set_index(ifp, IFINDEX_INTERNAL); return 0; } static int eigrp_interface_address_add(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct connected *c; c = zebra_interface_address_read(command, zclient->ibuf, vrf_id); if (c == NULL) return 0; if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE)) { char buf[128]; prefix2str(c->address, buf, sizeof(buf)); zlog_debug("Zebra: interface %s address add %s", c->ifp->name, buf); } eigrp_if_update(c->ifp); return 0; } static int eigrp_interface_address_delete(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct connected *c; struct interface *ifp; struct eigrp_interface *ei; c = zebra_interface_address_read(command, zclient->ibuf, vrf_id); if (c == NULL) return 0; if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE)) { char buf[128]; prefix2str(c->address, buf, sizeof(buf)); zlog_debug("Zebra: interface %s address delete %s", c->ifp->name, buf); } ifp = c->ifp; ei = ifp->info; if (!ei) return 0; /* Call interface hook functions to clean up */ eigrp_if_free(ei, INTERFACE_DOWN_BY_ZEBRA); connected_free(c); return 0; } static int eigrp_interface_state_up(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct interface *ifp; ifp = zebra_interface_if_lookup(zclient->ibuf); if (ifp == NULL) return 0; /* Interface is already up. */ if (if_is_operative(ifp)) { /* Temporarily keep ifp values. */ struct interface if_tmp; memcpy(&if_tmp, ifp, sizeof(struct interface)); zebra_interface_if_set_value(zclient->ibuf, ifp); if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE)) zlog_debug("Zebra: Interface[%s] state update.", ifp->name); if (if_tmp.bandwidth != ifp->bandwidth) { if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE)) zlog_debug( "Zebra: Interface[%s] bandwidth change %d -> %d.", ifp->name, if_tmp.bandwidth, ifp->bandwidth); // eigrp_if_recalculate_output_cost (ifp); } if (if_tmp.mtu != ifp->mtu) { if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE)) zlog_debug( "Zebra: Interface[%s] MTU change %u -> %u.", ifp->name, if_tmp.mtu, ifp->mtu); /* Must reset the interface (simulate down/up) when MTU * changes. */ eigrp_if_reset(ifp); } return 0; } zebra_interface_if_set_value(zclient->ibuf, ifp); if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE)) zlog_debug("Zebra: Interface[%s] state change to up.", ifp->name); if (ifp->info) eigrp_if_up(ifp->info); return 0; } static int eigrp_interface_state_down(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct interface *ifp; ifp = zebra_interface_state_read(zclient->ibuf, vrf_id); if (ifp == NULL) return 0; if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE)) zlog_debug("Zebra: Interface[%s] state change to down.", ifp->name); if (ifp->info) eigrp_if_down(ifp->info); return 0; } static struct interface *zebra_interface_if_lookup(struct stream *s) { char ifname_tmp[INTERFACE_NAMSIZ]; /* Read interface name. */ stream_get(ifname_tmp, s, INTERFACE_NAMSIZ); /* And look it up. */ return if_lookup_by_name(ifname_tmp, VRF_DEFAULT); }
// wait for the S3 GET/PUT to complete int stream_sync(ObjectStream* os) { /// // TBD: this should be a per-repo config-option /// static const time_t timeout_sec = 5; void* retval; // fuse may call fuse-flush multiple times (one for every open stream). // but will not call flush after calling close(). if (! (os->flags & OSF_OPEN)) { LOG(LOG_ERR, "%s isn't open\n", os->url); errno = EINVAL; /* ?? */ return -1; } // See NOTE, above, regarding the difference between reads and writes. if (! pthread_tryjoin_np(os->op, &retval)) { LOG(LOG_INFO, "op-thread joined\n"); os->flags |= OSF_JOINED; } else { // If a stream_get/put timed-out waiting for their // writefunc/readfunc, then the locks are likely in an inconsistent // state. [Either (a) the readfunc never posted iob_empty for // stream__put(), or (b) the writefunc never posted iob_full for // stream_get().] In either case, the operation started by // stream_open() is declared a failure, and we shouldn't do any of // the normal cleanup stuff, like trying to write recovery-info, etc. // But we do need to the thread to stop before we return, because if // the writefunc/readfunc gets another callback, it will access parts // of the ObjectStream that are about to be deallocated. if (os->flags & OSF_TIMEOUT) { LOG(LOG_INFO, "cancelling timed-out thread\n"); int rc = pthread_cancel(os->op); if (rc) { LOG(LOG_ERR, "cancellation failed (%s), killing thread\n", strerror(errno)); pthread_kill(os->op, SIGKILL); LOG(LOG_INFO, "killed thread\n"); } LOG(LOG_INFO, "waiting for terminated op-thread\n"); if (stream_wait(os)) { LOG(LOG_ERR, "err joining op-thread ('%s')\n", strerror(errno)); return -1; } } // In this case, the get/put timed-out, but it did so inside SAFE_WAIT_KILL(), // rather than SAFE_WAIT(), so the thread has already been cancelled // and joined. else if (os->flags & OSF_TIMEOUT_K) { LOG(LOG_INFO, "timed-out thread already killed\n"); LOG(LOG_INFO, "op-thread returned %d\n", os->op_rc); errno = (os->op_rc ? EIO : 0); return os->op_rc; } #if (LIBCURL_VERSION_MAJOR > 7) || ((LIBCURL_VERSION_MAJOR == 7) && (LIBCURL_VERSION_MINOR >= 45)) // Our installed version of libcurl is 7.19.7. We are experimenting // with a custom-built libcurl based on 7.45.0. We notice that the // latter does not call streaming_readfunc() again, if stream_open() // provided a content-length (i.e. the request had a content-length // header, rather than being chunked-transfer-encoded), and the full // number of chars matching the content-length header has been sent. // In such a case, stream_sync() shouldn't use "stream_put(..0)" to // get the readfunc to quit, because the readfunc isn't running. // // NOTE: This behavior may actually be present in earlier versions of // libcurl, in which case, the VERSION_MINOR here should be // adjusted downwards, toward 19. else if ((os->flags & OSF_WRITING) && os->content_len && (os->content_len == os->written)) { LOG(LOG_INFO, "(wr) wrote content-len, no action needed (flags=0x%04x)\n", os->flags); } #endif // signal EOF to readfunc else if (os->flags & OSF_WRITING) { LOG(LOG_INFO, "(wr) sending empty buffer (flags=0x%04x)\n", os->flags); if (stream_put(os, NULL, 0)) { LOG(LOG_ERR, "stream_put(0) failed\n"); pthread_kill(os->op, SIGKILL); LOG(LOG_INFO, "killed thread\n"); } } // signal QUIT to writefunc else { LOG(LOG_INFO, "(rd) sending empty buffer (flags=0x%04x)\n", os->flags); if (stream_get(os, NULL, 0)) { LOG(LOG_ERR, "stream_get(0) failed\n"); pthread_kill(os->op, SIGKILL); LOG(LOG_INFO, "killed thread\n"); } } // check whether thread has returned. Could mean a curl // error, an S3 protocol error, or server flaking out. LOG(LOG_INFO, "waiting for op-thread\n"); if (stream_wait(os)) { LOG(LOG_ERR, "err joining op-thread ('%s')\n", strerror(errno)); return -1; } } // thread has completed os->flags |= OSF_JOINED; if (( os->flags & OSF_READING) && (os->op_rc == CURLE_WRITE_ERROR)) { // when we signalled writefunc to quit, it provoked this LOG(LOG_INFO, "op-thread returned CURLE_WRITE_ERROR as expected\n"); return 0; } else { LOG(LOG_INFO, "op-thread returned %d\n", os->op_rc); errno = (os->op_rc ? EIO : 0); return os->op_rc; } }
/* Zebra route add and delete treatment. */ static int zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length) { struct stream *s; struct zapi_ipv6 api; struct in6_addr nexthop; struct prefix_ipv6 p; s = zclient->ibuf; 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); /* IPv6 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)) { api.nexthop_num = stream_getc (s); stream_get (&nexthop, s, 16); } if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) { api.ifindex_num = stream_getc (s); stream_getl (s); /* ifindex, unused */ } 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; /* Simply ignore link-local address. */ if (IN6_IS_ADDR_LINKLOCAL (&p.prefix)) return 0; if (command == ZEBRA_IPV6_ROUTE_ADD) { if (BGP_DEBUG(zebra, ZEBRA)) { char buf[2][INET6_ADDRSTRLEN]; zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d nexthop %s metric %u", zebra_route_string(api.type), inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])), p.prefixlen, inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])), api.metric); } bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop, api.metric, api.type); } else { if (BGP_DEBUG(zebra, ZEBRA)) { char buf[2][INET6_ADDRSTRLEN]; zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d " "nexthop %s metric %u", zebra_route_string(api.type), inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])), p.prefixlen, inet_ntop(AF_INET6, &nexthop, buf[1], sizeof(buf[1])), api.metric); } bgp_redistribute_delete ((struct prefix *) &p, api.type); } return 0; }
static int redist_read_ipv4_route(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct stream *s; struct zapi_ipv4 api; unsigned long ifindex; struct in_addr nexthop; struct prefix_ipv4 p; int min_len = 4; if (length < min_len) { zlog_warn("%s %s: short buffer: length=%d min=%d", __FILE__, __PRETTY_FUNCTION__, length, min_len); return -1; } s = zclient->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 length. */ memset(&p, 0, sizeof(struct prefix_ipv4)); p.family = AF_INET; p.prefixlen = stream_getc(s); min_len += PSIZE(p.prefixlen) + CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP) ? 5 : 0 + CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX) ? 5 : 0 + CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? 1 : 0 + CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? 4 : 0; if (PIM_DEBUG_ZEBRA) { zlog_debug("%s %s: length=%d min_len=%d flags=%s%s%s%s", __FILE__, __PRETTY_FUNCTION__, length, min_len, CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP) ? "nh" : "", CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX) ? " ifi" : "", CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? " dist" : "", CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? " metr" : ""); } if (length < min_len) { zlog_warn("%s %s: short buffer: length=%d min_len=%d flags=%s%s%s%s", __FILE__, __PRETTY_FUNCTION__, length, min_len, CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP) ? "nh" : "", CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX) ? " ifi" : "", CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? " dist" : "", CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? " metr" : ""); return -1; } /* IPv4 prefix. */ stream_get(&p.prefix, s, PSIZE(p.prefixlen)); /* Nexthop, ifindex, distance, metric. */ if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { api.nexthop_num = stream_getc(s); nexthop.s_addr = stream_get_ipv4(s); } if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { api.ifindex_num = stream_getc(s); ifindex = stream_getl(s); } api.distance = CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? stream_getc(s) : 0; api.metric = CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? stream_getl(s) : 0; switch (command) { case ZEBRA_IPV4_ROUTE_ADD: if (PIM_DEBUG_ZEBRA) { char buf[2][INET_ADDRSTRLEN]; zlog_debug("%s: add %s %s/%d " "nexthop %s ifindex %ld metric%s %u distance%s %u", __PRETTY_FUNCTION__, zebra_route_string(api.type), inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])), p.prefixlen, inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])), ifindex, CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? "-recv" : "-miss", api.metric, CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? "-recv" : "-miss", api.distance); } break; case ZEBRA_IPV4_ROUTE_DELETE: if (PIM_DEBUG_ZEBRA) { char buf[2][INET_ADDRSTRLEN]; zlog_debug("%s: delete %s %s/%d " "nexthop %s ifindex %ld metric%s %u distance%s %u", __PRETTY_FUNCTION__, zebra_route_string(api.type), inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])), p.prefixlen, inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])), ifindex, CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? "-recv" : "-miss", api.metric, CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? "-recv" : "-miss", api.distance); } break; default: zlog_warn("%s: unknown command=%d", __PRETTY_FUNCTION__, command); return -1; } sched_rpf_cache_refresh(); return 0; }
static struct list* mcp_pppd_interface_parse(struct stream *data_s) { int type; int len; struct list* digt_list; struct pppd_interface_info* info = NULL; digt_list = list_new(); digt_list->del = (void (*) (void *))mcp_ppp_config_info_free; while(STREAM_READABLE(data_s) >= 4) { type = stream_getw(data_s); len = stream_getw(data_s); //zlog_debug("<%s,%d> type:%d len:%d", __FUNCTION__, __LINE__, type, len); if(STREAM_READABLE(data_s) < 2) { zlog_err("mcp<%s:%d> stream readable bytes %d less %d",__FUNCTION__,__LINE__,((data_s)->endp-(data_s)->getp),len); return NULL; } switch(type) { case PPP_INTERFACE_SEQ: info = mcp_pppd_interface_new(); info->seq = stream_getl(data_s); //zlog_err("yang test ...seq:%u", (info->seq)); break; case PPP_INTERFACE_GWID: info->gwid= stream_getl(data_s); //zlog_err("yang test ...gwid:%s", remark_ip2str(info->gwid)); break; case PPP_INTERFACE_SEVTYPE: info->dev_type = stream_getl(data_s); //zlog_err("yang test ...dev_type:%u", (info->dev_type)); break; case PPP_INTERFACE_INTERFACEID: info->interfaceid = stream_getl(data_s); //zlog_err("yang test ...dev_type:%u", (info->dev_type)); break; case PPP_INTERFACE_MULTIFLAGE: info->multi_group = stream_getl(data_s); //zlog_err("yang test ...multi_flag:%u", (info->multi_group)); break; case PPP_INTERFACE_INTERFACEIP: memset(info->interfaceip, 0, sizeof(info->interfaceip)); stream_get(info->interfaceip, data_s, len); //zlog_err("yang test interfaceip:%s", info->interfaceip); break; case PPP_INTERFACE_ENABLE: info->enable = stream_getl(data_s); break; case PPP_INTERFACE_AUTHTYPE: info->auth_type = stream_getl(data_s); //zlog_err("yang test ...auth_type:%u", (info->auth_type)); break; case PPP_INTERFACE_AUTHNAME: memset(info->auth_name, 0, sizeof(info->auth_name)); stream_get(info->auth_name, data_s, len); //zlog_err("yang test auth_name:%s", info->auth_name); break; case PPP_INTERFACE_USERNAME: memset(info->username, 0, sizeof(info->username)); stream_get(info->username, data_s, len); //zlog_err("yang test username:%s", info->username); break; case PPP_INTERFACE_PSWD: memset(info->pswd, 0, sizeof(info->pswd)); stream_get(info->pswd, data_s, len); //zlog_err("yang test pswd:%s", info->pswd); break; case PPP_INTERFACE_TIME: memset(info->time, 0, sizeof(info->time)); stream_get(info->time, data_s, len); //zlog_err("yang test time:%s", info->time); break; case PPP_INTERFACE_REMARK: memset(info->remark, 0, sizeof(info->remark)); stream_get(info->remark, data_s, len); //zlog_err("yang test remark:%s", info->remark); break; case PPP_INTERFACE_ACTION: info->action = stream_getl(data_s); listnode_add(digt_list, info); //zlog_err("yang test ...action:%u", (info->action)); break; default: list_delete(digt_list); zlog_err("mcp<%s:%d> wrong type:%u",__FUNCTION__,__LINE__,type); goto error; } } return digt_list; error: return NULL; }
struct connected * zebra_interface_address_read (int type, struct stream *s) { unsigned int ifindex; struct interface *ifp; struct connected *ifc; struct prefix p, d; int family; int plen; u_char ifc_flags; memset (&p, 0, sizeof(p)); memset (&d, 0, sizeof(d)); /* Get interface index. */ ifindex = stream_getl (s); /* Lookup index. */ ifp = if_lookup_by_index (ifindex); if (ifp == NULL) { zlog_warn ("zebra_interface_address_read(%s): " "Can't find interface by ifindex: %d ", (type == ZEBRA_INTERFACE_ADDRESS_ADD? "ADD" : "DELETE"), ifindex); return NULL; } /* Fetch flag. */ ifc_flags = stream_getc (s); /* Fetch interface address. */ family = p.family = stream_getc (s); plen = prefix_blen (&p); stream_get (&p.u.prefix, s, plen); p.prefixlen = stream_getc (s); /* Fetch destination address. */ stream_get (&d.u.prefix, s, plen); d.family = family; if (type == ZEBRA_INTERFACE_ADDRESS_ADD) { /* N.B. NULL destination pointers are encoded as all zeroes */ ifc = connected_add_by_prefix(ifp, &p,(memconstant(&d.u.prefix,0,plen) ? NULL : &d)); if (ifc != NULL) { ifc->flags = ifc_flags; if (ifc->destination) ifc->destination->prefixlen = ifc->address->prefixlen; else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) { /* carp interfaces on OpenBSD with 0.0.0.0/0 as "peer" */ char buf[BUFSIZ]; prefix2str (ifc->address, buf, sizeof(buf)); zlog_warn("warning: interface %s address %s " "with peer flag set, but no peer address!", ifp->name, buf); UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER); } } } else { assert (type == ZEBRA_INTERFACE_ADDRESS_DELETE); ifc = connected_delete_by_prefix(ifp, &p); } return ifc; }
static int lex_get_save(lex_t *lex, json_error_t *error) { char c = stream_get(&lex->stream, error); lex_save(lex, c); return c; }
static int lex_get(lex_t *lex, json_error_t *error) { return stream_get(&lex->stream, error); }
static int lex_get(lex_t *lex, ph_var_err_t *error) { return stream_get(&lex->stream, error); }
static struct bgp_nexthop_cache * zlookup_read_ipv6 (void) { struct stream *s; uint16_t length; u_char version, marker; uint16_t command; int nbytes; struct in6_addr raddr; uint32_t metric; int i; u_char nexthop_num; struct nexthop *nexthop; struct bgp_nexthop_cache *bnc; s = zlookup->ibuf; stream_reset (s); nbytes = stream_read (s, zlookup->sock, 2); length = stream_getw (s); nbytes = stream_read (s, zlookup->sock, length - 2); marker = stream_getc (s); version = stream_getc (s); if (version != ZSERV_VERSION || marker != ZEBRA_HEADER_MARKER) { zlog_err("%s: socket %d version mismatch, marker %d, version %d", __func__, zlookup->sock, marker, version); return NULL; } command = stream_getw (s); stream_get (&raddr, s, 16); metric = stream_getl (s); nexthop_num = stream_getc (s); if (nexthop_num) { bnc = bnc_new (); bnc->valid = 1; bnc->metric = metric; bnc->nexthop_num = nexthop_num; for (i = 0; i < nexthop_num; i++) { nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop)); nexthop->type = stream_getc (s); switch (nexthop->type) { case ZEBRA_NEXTHOP_IPV6: stream_get (&nexthop->gate.ipv6, s, 16); break; case ZEBRA_NEXTHOP_IPV6_IFINDEX: case ZEBRA_NEXTHOP_IPV6_IFNAME: stream_get (&nexthop->gate.ipv6, s, 16); nexthop->ifindex = stream_getl (s); break; case ZEBRA_NEXTHOP_IFINDEX: case ZEBRA_NEXTHOP_IFNAME: nexthop->ifindex = stream_getl (s); break; default: /* do nothing */ break; } bnc_nexthop_add (bnc, nexthop); } } else return NULL; return bnc; }
/* * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and * add kernel route. */ static void zread_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); }
static int ospf6_zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length) { struct stream *s; struct zapi_ipv6 api; unsigned long ifindex; struct prefix_ipv6 p; struct in6_addr *nexthop; s = zclient->ibuf; ifindex = 0; nexthop = NULL; memset (&api, 0, sizeof (api)); /* Type, flags, message. */ api.type = stream_getc (s); api.flags = stream_getc (s); api.message = stream_getc (s); /* IPv6 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)) { api.nexthop_num = stream_getc (s); nexthop = (struct in6_addr *) malloc (api.nexthop_num * sizeof (struct in6_addr)); stream_get (nexthop, s, api.nexthop_num * sizeof (struct in6_addr)); } if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) { api.ifindex_num = stream_getc (s); ifindex = stream_getl (s); } 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 (IS_OSPF6_DEBUG_ZEBRA (RECV)) { char prefixstr[128], nexthopstr[128]; prefix2str ((struct prefix *)&p, prefixstr, sizeof (prefixstr)); if (nexthop) inet_ntop (AF_INET6, nexthop, nexthopstr, sizeof (nexthopstr)); else snprintf (nexthopstr, sizeof (nexthopstr), "::"); zlog_debug ("Zebra Receive route %s: %s %s nexthop %s ifindex %ld", (command == ZEBRA_IPV6_ROUTE_ADD ? "add" : "delete"), zebra_route_string(api.type), prefixstr, nexthopstr, ifindex); } if (command == ZEBRA_IPV6_ROUTE_ADD) ospf6_asbr_redistribute_add (api.type, ifindex, (struct prefix *) &p, api.nexthop_num, nexthop); else ospf6_asbr_redistribute_remove (api.type, ifindex, (struct prefix *) &p); if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) free (nexthop); return 0; }
int ospf6_zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length) { struct stream *s; struct zapi_ipv6 api; unsigned long ifindex; struct prefix_ipv6 p; struct in6_addr *nexthop; char prefixstr[128], nexthopstr[128]; s = zclient->ibuf; ifindex = 0; nexthop = NULL; memset (&api, 0, sizeof (api)); /* Type, flags, message. */ api.type = stream_getc (s); api.flags = stream_getc (s); api.message = stream_getc (s); /* IPv6 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)) { api.nexthop_num = stream_getc (s); nexthop = (struct in6_addr *) malloc (api.nexthop_num * sizeof (struct in6_addr)); stream_get (nexthop, s, api.nexthop_num * sizeof (struct in6_addr)); } if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) { api.ifindex_num = stream_getc (s); ifindex = stream_getl (s); } 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; /* log */ if (IS_OSPF6_DUMP_ZEBRA) { prefix2str ((struct prefix *)&p, prefixstr, sizeof (prefixstr)); inet_ntop (AF_INET6, &nexthop, nexthopstr, sizeof (nexthopstr)); if (command == ZEBRA_IPV6_ROUTE_ADD) zlog_info ("ZEBRA: Receive add %s route: %s nexthop:%s ifindex:%ld", zebra_route_name [api.type], prefixstr, nexthopstr, ifindex); else zlog_info ("ZEBRA: Receive remove %s route: %s nexthop:%s ifindex:%ld", zebra_route_name [api.type], prefixstr, nexthopstr, ifindex); } if (command == ZEBRA_IPV6_ROUTE_ADD) ospf6_asbr_route_add (api.type, ifindex, (struct prefix *) &p, api.nexthop_num, nexthop); else ospf6_asbr_route_remove (api.type, ifindex, (struct prefix *) &p); if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) free (nexthop); return 0; }