?? ipripng.c
字號(hào):
IP_STATIC voidipripng_rtfree(Ipripng_rt *rt, Ip_bool proto_set){ ip_assert(rt != IP_NULL); if (IP_BIT_ISSET(rt->rrt_rflags, RRTF_STACKROUTE)) { ip_assert(ipripng.delete_route != IP_NULL); if (ipripng.delete_route(&(rt->rrt_info), &(rt->rrt_gw), proto_set) != IPCOM_SUCCESS) {/* IPCOM_LOG2(WARNING, "ipripng_rtfree() :: failed to delete stack route %s, errno %d", ipripng_routeinfo(rt), ipcom_errno);*/ } } ipcom_free(rt);}/* *=========================================================================== * ipripng_rtinsert *=========================================================================== * Description: Insert a RIP route, report to the TCP/IP stack * and schedule a RIP triggered update, i.e. flash. * Parameters: rt RIP route entry. * Returns: IPCOM_SUCESS or error code. * */IP_STATIC Ip_erripripng_rtinsert(Ipripng_rt *rt, struct ifc *ifcp){ Ip_err retval; ip_assert(rt != IP_NULL); if (NOT IP_BIT_ISSET(rt->rrt_rflags, RRTF_INTERFACE + RRTF_RIPNGLEARNED + RRTF_AGGREGATE)) { /* Add the route with the TCP/IP stack. */ if (ipripng.add_route(rt, &(rt->rrt_gw), ifcp) == IPCOM_SUCCESS) IP_BIT_SET(rt->rrt_rflags, RRTF_STACKROUTE); else { IPCOM_LOG2(WARNING, "iprip_rtinsert() :: failed to add stack route %s, errno %d", ipripng_routeinfo(rt), ipcom_errno); return IPCOM_ERR_FAILED; } } /* Insert route. */ rt->hdr.key = &rt->rrt_info.rip6_dest; rt->hdr.mask = rt->keymask; retval = ipcom_route_add(ipripng.rtab, &rt->hdr); ip_assert(retval == IPCOM_SUCCESS); ipcom_list_insert_last(&ipripng.rt_head, &rt->rt_list); ipripng.rt_num++; /* New or updated route, flash it. */ ipripng_rtflash(rt); return retval;}/* *=========================================================================== * ipripng_rtremove *=========================================================================== * Description: Remove a route. * Parameters: rt RIPng route entry. * Returns: IPCOM_SUCESS or error code. * */IP_STATIC voidipripng_rtremove(Ipripng_rt *rt){ Ip_err retval; ip_assert(rt != IP_NULL); ipcom_list_remove(&rt->rt_list); retval = ipcom_route_remove(ipripng.rtab, &rt->hdr); ip_assert(retval == IPCOM_SUCCESS); (void)retval; ipripng.rt_num--; ip_assert(ipripng.rt_num >= 0);}/* *=========================================================================== * ipripng_rtlookup *=========================================================================== * Description: * Parameters: * Returns: * */IP_STATIC Ipripng_rt *ipripng_rtlookup(struct netinfo6 *np, Ipripng_rt **prev_rrt){ struct Ipripng_rt *rrt; if (prev_rrt) *prev_rrt = IP_NULL; for (rrt = ipripng.riprt; rrt; rrt = ((Ipripng_rt *)rrt)->rrt_next) { if (((Ipripng_rt *)rrt)->rrt_info.rip6_plen == np->rip6_plen && IP_IN6_ARE_ADDR_EQUAL(&((Ipripng_rt *)rrt)->rrt_info.rip6_dest, &np->rip6_dest)) return (Ipripng_rt *)rrt; if (prev_rrt) *prev_rrt = (Ipripng_rt *)rrt; } if (prev_rrt) *prev_rrt = IP_NULL; return IP_NULL;}/* *=========================================================================== * ipripng_rtnotify *=========================================================================== * Description: Callback that is used each time the status of the route * table changes. * Parameters: rtab - The route table that has changed. * entry - The entry in the route table that was affected. * code - Code that describes the event. * Returns: * */IP_STATIC voidipripng_rtnotify(Ipcom_route *rtab, Ipcom_route_entry *entry, int code){ (void)rtab; (void)entry; if (code == IPCOM_ROUTE_CODE_DUPLICATE) { IP_PANIC(); }}/* *=========================================================================== * ipripng_rtflash *=========================================================================== * Description: Trigger a flash update with this route included. Ignore * scheduling a new flash if there is one already scheduled. * Parameters: re RIPng route entry. * Returns: . * */IP_STATIC voidipripng_rtflash(Ipripng_rt *rt){ ip_assert(rt != IP_NULL); /* Schedule a flash with thir route included. */ rt->update_inst = ipripng.update_inst;/* IPCOM_LOG4(DEBUG2, " ++ route flash: %s/%s -> %s - %s.", ipcom_inet_ntop(IP_AF_INET, &rt->ipaddr_n, iprip.str, sizeof(iprip.str)), ipcom_inet_ntop(IP_AF_INET, &rt->mask_n, iprip.str2, sizeof(iprip.str2)), ipcom_inet_ntop(IP_AF_INET, &rt->router_n, iprip.str3, sizeof(iprip.str3)), IPCOM_TMO_PENDING(&iprip.flash) ? "ignored" : "triggered");*/ if (NOT IPCOM_TMO_PENDING(&ipripng.flash)) { (void)ipcom_tmo_request(&ipripng.flash, ipripng_flash_timeout, IP_NULL, 1000 * ipripng.flash_seconds); }}/* *=========================================================================== * ipripng_sendpacket *=========================================================================== * Description: Transmit a RIPng packet to address sin6. * Parameters: sin6 Address to transmit a RIPng packet to. * len The length of the packet. * Returns: * */IP_STATIC intipripng_sendpacket(struct Ip_sockaddr_in6 *sin6, int len){ struct Ip_msghdr m; struct Ip_cmsghdr *cm; struct Ip_iovec iov[2]; Ip_u8 cmsgbuf[256]; struct Ip_in6_pktinfo *pi; int idx; struct Ip_sockaddr_in6 sin6copy; /* do not overwrite the given sin6 */ sin6copy = *sin6; sin6 = &sin6copy; if (IP_IN6_IS_ADDR_LINK_LOCAL(&sin6->sin6_addr) || IP_IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) { /* XXX: do not mix the interface index and link index */ idx = IN6_LINKLOCAL_IFINDEX(sin6->sin6_addr); SET_IN6_LINKLOCAL_IFINDEX(sin6->sin6_addr, 0); sin6->sin6_scope_id = idx; } else idx = 0; if (ipripng.dflag) ipcom_printf("ipripng_sendpacket, to format the packet\n"); m.msg_name = (char *)sin6; m.msg_namelen = sizeof(*sin6); iov[0].iov_base = (char *)ipripng.ripngbuf; iov[0].iov_len = len; m.msg_iov = iov; m.msg_iovlen = 1; m.msg_flags = 0; if (!idx) { m.msg_control = IP_NULL; m.msg_controllen = 0; } else { memset(cmsgbuf, 0, sizeof(cmsgbuf)); cm = (struct Ip_cmsghdr *)cmsgbuf; m.msg_control = (char *)cm; m.msg_controllen = IP_CMSG_SPACE(sizeof(struct Ip_in6_pktinfo)); cm->cmsg_len = IP_CMSG_LEN(sizeof(struct Ip_in6_pktinfo)); cm->cmsg_level = IP_IPPROTO_IPV6; cm->cmsg_type = IP_IPV6_PKTINFO; pi = (struct Ip_in6_pktinfo *)IP_CMSG_DATA(cm); memset(&pi->ipi6_addr, 0, sizeof(pi->ipi6_addr)); /*::*/ pi->ipi6_ifindex = idx; } if (ipripng.dflag) ipcom_printf("ipripng_sendpacket, to call ipcom_sendmsg\n"); if ((ipcom_sendmsg(ipripng.udp_fd, &m, 0 /*MSG_DONTROUTE*/)) < 0) { IPCOM_LOG1(INFO, "sendmsg: %d", ipcom_errno); return ipcom_errno; } return 0;}/* *=========================================================================== * ipripng_sendrequest *=========================================================================== * Description: Send a RIPng request for all routes on this interface. * Parameters: ifcp Interface to send RIPng request on. * Returns: * */IP_GLOBAL voidipripng_sendrequest(struct ifc *ifcp){ struct netinfo6 *np; int error; char buf[IP_INET6_ADDRSTRLEN]; char buf2[IP_BUFSIZ]; if (ipripng.dflag) ipcom_printf("Calling ipripng_sendrequest, %s\n", ifcp->ifc_name); if (ifcp->ifc_flags & IP_IFF_LOOPBACK) return; ipripng.ripngbuf->rip6_cmd = RIP6_REQUEST; np = ipripng.ripngbuf->rip6_nets; memset(np, 0, sizeof(struct netinfo6)); np->rip6_metric = HOPCNT_INFINITY6; if (ipcom_inet_ntop(IP_AF_INET6, &ifcp->ifc_ripsin.sin6_addr, buf, sizeof (buf)) == IP_NULL) buf[0] = '\0'; /* So doesn't display garbage */ IPCOM_LOG2(INFO, "Send rtdump Request to %s (%s)", ifcp->ifc_name, buf); if (ipripng.dflag) ipcom_printf("Send rtdump Request to %s (%s)", ifcp->ifc_name, buf); error = ipripng_sendpacket(&ifcp->ifc_ripsin, RIPSIZE(1)); if (error == IP_ERRNO_EAFNOSUPPORT) { /* Protocol not supported */ IPCOM_LOG3(INFO, "%s: Could not send rtdump Request to %s (%s): " "set IFF_UP to 0", buf2, ifcp->ifc_name, buf); ifcp->ifc_flags &= ~IP_IFF_UP; /* As if down for AF_INET6 */ } ipripng.ripngbuf->rip6_cmd = RIP6_RESPONSE;}/* *=========================================================================== * ipripng_update_timeout *=========================================================================== * Description: Age all RIPng routes and send a regular RIPng update on all RIPng * interfaces that should transmit. * Parameters: tmo NSTIME timeout structure. * Returns: . * */IP_STATIC Ip_s32ipripng_update_timeout(Ipcom_tmo *tmo, void *cookie){ struct ifc *ifcp; Ipripng_rt *rrt, *rrt_prev, *rrt_next; Ip_time_t t_lifetime, t_holddown; if (ripngStopFlag) return 0; IPRIPNG_LOCK(); (void)tmo; (void)cookie; IPCOM_LOG2(DEBUG2, "+++ update timeout, %ld interfaces, %ld routes:", ipripng.nifc, ipripng.rt_num); /* age the RIPng routes */ rrt_prev = 0; t_lifetime = time_offset(IP_NULL) - RIP_LIFETIME; t_holddown = t_lifetime - RIP_HOLDDOWN; for (rrt = (Ipripng_rt *)ipripng.riprt; rrt; rrt = rrt_next) { rrt_next = (Ipripng_rt *)rrt->rrt_next; if (rrt->rrt_t == 0) { rrt_prev = rrt; continue; } if (rrt->rrt_t < t_holddown) { if (rrt_prev) { rrt_prev->rrt_next = rrt->rrt_next; } else { ipripng.riprt = rrt->rrt_next; } /* * Only delete the route if it wasn't already deleted. * This happens if the user deleted the routes in the kernel * and RIPng learned of the deleted route via the routing socket. * It ages the route with metric 16, but after the timeout * there is of course no need to delete it in the kernel. */ if ((rrt->rrt_rflags & RRTF_DELETED) == 0) { if ((rrt->rrt_rflags & RRTF_RIPNGLEARNED) == 0) { /* * Don't delete static routes unless we've been * asked to age them. Normally static routes have * their rtt set to 0 unless the ripng_age flag is * set, but even in that case, if the interface goes * down, we ahe them so that we can advertise an * INFINITE metric for them. When we are finished * advertising them, we want to delete them from RIPng's * internal table but not from the system route table. */ if ((rrt->rrt_flags & IPNET_RTF_STATIC) == 0 || ipripng.aflag != 0) { IPCOM_LOG0(INFO, "Warning: Ageing a route not learned by RIPng"); /* delroute() shouldn't use PROTO_SET */ ipripng.delete_route(&rrt->rrt_info, &rrt->rrt_gw, IP_FALSE); } } else { ipripng.delete_route(&rrt->rrt_info, &rrt->rrt_gw, IP_TRUE); } } ipcom_free(rrt); continue; } if (rrt->rrt_t < t_lifetime) { rrt->rrt_info.rip6_metric = HOPCNT_INFINITY6; } rrt_prev = rrt; } /* Supply updates */ for (ifcp = ipripng.ifc; ifcp; ifcp = ifcp->ifc_next) { if ((ifcp->ifc_index > 0) && (ifcp->ifc_flags & IP_IFF_UP))
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -