Lines Matching +full:use +full:- +full:rtm

3 /*-
4 * SPDX-License-Identifier: BSD-3-Clause
9 * Redistribution and use in source and binary forms, with or without
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
80 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
81 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
92 struct in6_addr ifc_mylladdr; /* my link-local address */
149 struct riprt *rrt_same; /* same destination - future use */
292 while ((ch = getopt(argc, argv, "A:N:O:R:T:L:t:adDhlnp:P:Q:qsS")) != -1) { in main()
371 argc -= optind; in main()
396 ripbuf->rip6_cmd = RIP6_RESPONSE; in main()
397 ripbuf->rip6_vers = RIP6_VERSION; in main()
398 ripbuf->rip6_res1[0] = 0; in main()
399 ripbuf->rip6_res1[1] = 0; in main()
404 if (ifcp->ifc_index < 0) { in main()
406 "(no link-local address?)\n", ifcp->ifc_name); in main()
435 ripbuf->rip6_cmd = RIP6_RESPONSE; in main()
436 ripbuf->rip6_vers = RIP6_VERSION; in main()
437 ripbuf->rip6_res1[0] = 0; in main()
438 ripbuf->rip6_res1[1] = 0; in main()
459 if (ifcp->ifc_index > 0 && (ifcp->ifc_flags & IFF_UP)) in main()
490 case -1: in main()
554 if (rrt->rrt_rflags & RRTF_AGGREGATE) { in rtdexit()
555 delroute(&rrt->rrt_info, &rrt->rrt_gw); in rtdexit()
582 t_lifetime = time(NULL) - RIP_LIFETIME; in ripalarm()
583 t_holddown = t_lifetime - RIP_HOLDDOWN; in ripalarm()
585 if (rrt->rrt_t == 0) in ripalarm()
587 else if (rrt->rrt_t < t_holddown) { in ripalarm()
589 delroute(&rrt->rrt_info, &rrt->rrt_gw); in ripalarm()
591 } else if (rrt->rrt_t < t_lifetime) in ripalarm()
592 rrt->rrt_info.rip6_metric = HOPCNT_INFINITY6; in ripalarm()
596 if (ifcp->ifc_index > 0 && (ifcp->ifc_flags & IFF_UP)) in ripalarm()
597 ripsend(ifcp, &ifcp->ifc_ripsin, 0); in ripalarm()
625 if (res->ai_next) { in init()
630 ripsock = socket(res->ai_family, res->ai_socktype, res->ai_protocol); in init()
642 if (bind(ripsock, res->ai_addr, res->ai_addrlen) < 0) { in init()
695 if (res->ai_next) { in init()
699 memcpy(&ripsin, res->ai_addr, res->ai_addrlen); in init()
723 set[1].fd = -1; in init()
725 rtsock = -1; /*just for safety */ in init()
747 (sizeof(struct rip6) + ((n)-1) * sizeof(struct netinfo6))
760 ifcp->ifc_name, nrt, in ripflush()
761 inet6_n2p(&sin6->sin6_addr), ntohs(sin6->sin6_port)); in ripflush()
764 nrt, inet6_n2p(&sin6->sin6_addr), ntohs(sin6->sin6_port)); in ripflush()
766 np = ripbuf->rip6_nets; in ripflush()
768 if (np->rip6_metric == NEXTHOP_METRIC) { in ripflush()
769 if (IN6_IS_ADDR_UNSPECIFIED(&np->rip6_dest)) in ripflush()
773 inet6_n2p(&np->rip6_dest)); in ripflush()
777 inet6_n2p(&np->rip6_dest), in ripflush()
778 np->rip6_plen, np->rip6_metric); in ripflush()
780 if (np->rip6_tag) { in ripflush()
782 ntohs(np->rip6_tag) & 0xffff); in ripflush()
793 ifcp->ifc_name, in ripflush()
794 inet6_n2p(&ifcp->ifc_ripsin.sin6_addr)); in ripflush()
796 ifcp->ifc_flags &= ~IFF_UP; in ripflush()
799 inet6_n2p(&sin6->sin6_addr)); in ripflush()
821 * Request from non-link local address is not in ripsend()
824 maxrte = (IFMINMTU - sizeof(struct ip6_hdr) - in ripsend()
825 sizeof(struct udphdr) - in ripsend()
830 np = ripbuf->rip6_nets; in ripsend()
832 if (rrt->rrt_rflags & RRTF_NOADVERTISE) in ripsend()
835 *np = rrt->rrt_info; in ripsend()
841 np = ripbuf->rip6_nets; in ripsend()
850 (qflag || (ifcp->ifc_flags & IFF_LOOPBACK))) in ripsend()
853 /* -N: no use */ in ripsend()
857 /* -T: generate default route only */ in ripsend()
864 rrt_info.rip6_metric += ifcp->ifc_metric; in ripsend()
866 np = ripbuf->rip6_nets; in ripsend()
873 maxrte = (ifcp->ifc_mtu - sizeof(struct ip6_hdr) - in ripsend()
874 sizeof(struct udphdr) - in ripsend()
878 nrt = 0; np = ripbuf->rip6_nets; nh = NULL; in ripsend()
880 if (rrt->rrt_rflags & RRTF_NOADVERTISE) in ripsend()
893 (rrt->rrt_rflags & RRTF_CHANGED) == 0) in ripsend()
897 if (rrt->rrt_index == ifcp->ifc_index && in ripsend()
898 !IN6_IS_ADDR_UNSPECIFIED(&rrt->rrt_gw) && in ripsend()
899 (rrt->rrt_rflags & RRTF_NH_NOT_LLADDR) == 0) { in ripsend()
900 if (nh == NULL || !IN6_ARE_ADDR_EQUAL(nh, &rrt->rrt_gw)) { in ripsend()
901 if (nrt == maxrte - 2) { in ripsend()
905 np = ripbuf->rip6_nets; in ripsend()
908 np->rip6_dest = rrt->rrt_gw; in ripsend()
909 np->rip6_plen = 0; in ripsend()
910 np->rip6_tag = 0; in ripsend()
911 np->rip6_metric = NEXTHOP_METRIC; in ripsend()
912 nh = &rrt->rrt_gw; in ripsend()
915 } else if (nh && (rrt->rrt_index != ifcp->ifc_index || in ripsend()
916 !IN6_ARE_ADDR_EQUAL(nh, &rrt->rrt_gw) || in ripsend()
917 rrt->rrt_rflags & RRTF_NH_NOT_LLADDR)) { in ripsend()
919 if (nrt == maxrte - 2) { in ripsend()
923 np = ripbuf->rip6_nets; in ripsend()
926 np->rip6_metric = NEXTHOP_METRIC; in ripsend()
932 *np = rrt->rrt_info; in ripsend()
938 np = ripbuf->rip6_nets; in ripsend()
946 * outbound filter logic, per-route/interface.
956 * -A: filter out less specific routes, if we have aggregated in out_filter()
959 TAILQ_FOREACH(iffp, &ifcp->ifc_iff_head, iff_next) { in out_filter()
960 if (iffp->iff_type != 'A') in out_filter()
962 if (rrt->rrt_info.rip6_plen <= iffp->iff_plen) in out_filter()
964 ia = rrt->rrt_info.rip6_dest; in out_filter()
965 applyplen(&ia, iffp->iff_plen); in out_filter()
966 if (IN6_ARE_ADDR_EQUAL(&ia, &iffp->iff_addr)) in out_filter()
972 * interfaces specified on -A. in out_filter()
974 if ((rrt->rrt_rflags & RRTF_AGGREGATE) != 0) { in out_filter()
976 TAILQ_FOREACH(iffp, &ifcp->ifc_iff_head, iff_next) { in out_filter()
977 if (iffp->iff_type != 'A') in out_filter()
979 if (rrt->rrt_info.rip6_plen == iffp->iff_plen && in out_filter()
980 IN6_ARE_ADDR_EQUAL(&rrt->rrt_info.rip6_dest, in out_filter()
981 &iffp->iff_addr)) { in out_filter()
991 * -O: advertise only if prefix matches the configured prefix. in out_filter()
995 TAILQ_FOREACH(iffp, &ifcp->ifc_iff_head, iff_next) { in out_filter()
996 if (iffp->iff_type != 'O') in out_filter()
998 if (rrt->rrt_info.rip6_plen < iffp->iff_plen) in out_filter()
1000 ia = rrt->rrt_info.rip6_dest; in out_filter()
1001 applyplen(&ia, iffp->iff_plen); in out_filter()
1002 if (IN6_ARE_ADDR_EQUAL(&ia, &iffp->iff_addr)) { in out_filter()
1024 if (rrt->rrt_flags & RTF_STATIC) { in tobeadv()
1026 if (rrt->rrt_flags & (RTF_REJECT | RTF_BLACKHOLE)) in tobeadv()
1031 if (sflag && rrt->rrt_index != ifcp->ifc_index) in tobeadv()
1036 if (hflag == 0 && rrt->rrt_index == ifcp->ifc_index) in tobeadv()
1059 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) || in sendpacket()
1060 IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) in sendpacket()
1061 idx = sin6->sin6_scope_id; in sendpacket()
1081 cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); in sendpacket()
1082 cm->cmsg_level = IPPROTO_IPV6; in sendpacket()
1083 cm->cmsg_type = IPV6_PKTINFO; in sendpacket()
1085 memset(&pi->ipi6_addr, 0, sizeof(pi->ipi6_addr)); /*::*/ in sendpacket()
1086 pi->ipi6_ifindex = idx; in sendpacket()
1145 if (cm->cmsg_level != IPPROTO_IPV6) in riprecv()
1147 switch (cm->cmsg_type) { in riprecv()
1149 if (cm->cmsg_len != CMSG_LEN(sizeof(*pi))) { in riprecv()
1155 idx = pi->ipi6_ifindex; in riprecv()
1158 if (cm->cmsg_len != CMSG_LEN(sizeof(int))) { in riprecv()
1186 nn = (len - sizeof(struct rip6) + sizeof(struct netinfo6)) / in riprecv()
1189 np = rp->rip6_nets; in riprecv()
1191 if (rp->rip6_vers != RIP6_VERSION) { in riprecv()
1192 trace(1, "Incorrect RIP version %d\n", rp->rip6_vers); in riprecv()
1195 if (rp->rip6_cmd == RIP6_REQUEST) { in riprecv()
1206 trace(1, "Response from non-ll addr: %s\n", in riprecv()
1208 return; /* Ignore packets from non-link-local addr */ in riprecv()
1211 trace(1, "Response from non-rip port from %s\n", in riprecv()
1215 if (IN6_IS_ADDR_MULTICAST(&pi->ipi6_addr) && *hlimp != 255) { in riprecv()
1222 * Further validation: since this program does not send off-link in riprecv()
1223 * requests, an incoming response must always come from an on-link in riprecv()
1226 * implementations that (invalidly) allow a packet with a link-local in riprecv()
1228 * So we also check whether the destination address is a link-local in riprecv()
1233 if (!IN6_IS_ADDR_LINKLOCAL(&pi->ipi6_addr) && *hlimp != 255) { in riprecv()
1235 "Response packet possibly from an off-link node: " in riprecv()
1238 inet6_n2p(&pi->ipi6_addr), *hlimp); in riprecv()
1248 if (IN6_ARE_ADDR_EQUAL(&ifcp->ifc_mylladdr, &fsock.sin6_addr)) in riprecv()
1250 if (rp->rip6_cmd != RIP6_RESPONSE) { in riprecv()
1251 trace(1, "Invalid command %d\n", rp->rip6_cmd); in riprecv()
1255 /* -N: no use */ in riprecv()
1260 ifcp->ifc_name, inet6_n2p(&nh), ntohs(fsock.sin6_port), nn); in riprecv()
1263 t_half_lifetime = t - (RIP_LIFETIME/2); in riprecv()
1264 for (; nn; nn--, np++) { in riprecv()
1265 if (np->rip6_metric == NEXTHOP_METRIC) { in riprecv()
1267 if (IN6_IS_ADDR_LINKLOCAL(&np->rip6_dest)) { in riprecv()
1268 nh = np->rip6_dest; in riprecv()
1270 } else if (IN6_IS_ADDR_UNSPECIFIED(&np->rip6_dest)) { in riprecv()
1276 inet6_n2p(&np->rip6_dest)); in riprecv()
1280 if (IN6_IS_ADDR_MULTICAST(&np->rip6_dest)) { in riprecv()
1282 inet6_n2p(&np->rip6_dest), in riprecv()
1283 np->rip6_plen, np->rip6_metric); in riprecv()
1286 if (IN6_IS_ADDR_LOOPBACK(&np->rip6_dest)) { in riprecv()
1288 inet6_n2p(&np->rip6_dest), in riprecv()
1289 np->rip6_plen, np->rip6_metric); in riprecv()
1292 if (IN6_IS_ADDR_LINKLOCAL(&np->rip6_dest)) { in riprecv()
1294 inet6_n2p(&np->rip6_dest), in riprecv()
1295 np->rip6_plen, np->rip6_metric); in riprecv()
1299 if (IN6_IS_ADDR_SITELOCAL(&np->rip6_dest) && !lflag) { in riprecv()
1301 inet6_n2p(&np->rip6_dest), in riprecv()
1302 np->rip6_plen, np->rip6_metric); in riprecv()
1306 inet6_n2p(&np->rip6_dest), in riprecv()
1307 np->rip6_plen, np->rip6_metric); in riprecv()
1308 if (np->rip6_tag) in riprecv()
1309 trace(2, " tag=0x%04x", ntohs(np->rip6_tag) & 0xffff); in riprecv()
1311 ia = np->rip6_dest; in riprecv()
1312 applyplen(&ia, np->rip6_plen); in riprecv()
1313 if (!IN6_ARE_ADDR_EQUAL(&ia, &np->rip6_dest)) in riprecv()
1318 * -L: listen only if the prefix matches the configuration in riprecv()
1321 TAILQ_FOREACH(iffp, &ifcp->ifc_iff_head, iff_next) { in riprecv()
1322 if (iffp->iff_type != IFIL_TYPE_L) in riprecv()
1325 if (np->rip6_plen < iffp->iff_plen) in riprecv()
1328 if (iffp->iff_plen == 0 && np->rip6_plen > 0) in riprecv()
1330 ia = np->rip6_dest; in riprecv()
1331 applyplen(&ia, iffp->iff_plen); in riprecv()
1332 if (IN6_ARE_ADDR_EQUAL(&ia, &iffp->iff_addr)) { in riprecv()
1343 np->rip6_metric++; in riprecv()
1344 np->rip6_metric += ifcp->ifc_metric; in riprecv()
1345 if (np->rip6_metric > HOPCNT_INFINITY6) in riprecv()
1346 np->rip6_metric = HOPCNT_INFINITY6; in riprecv()
1348 applyplen(&np->rip6_dest, np->rip6_plen); in riprecv()
1350 if (rrt->rrt_t == 0) in riprecv()
1352 nq = &rrt->rrt_info; in riprecv()
1353 if (nq->rip6_metric > np->rip6_metric) { in riprecv()
1354 if (rrt->rrt_index == ifcp->ifc_index && in riprecv()
1355 IN6_ARE_ADDR_EQUAL(&nh, &rrt->rrt_gw)) { in riprecv()
1357 nq->rip6_metric = np->rip6_metric; in riprecv()
1360 rrt->rrt_index = ifcp->ifc_index; in riprecv()
1362 delroute(nq, &rrt->rrt_gw); in riprecv()
1363 rrt->rrt_gw = nh; in riprecv()
1367 rrt->rrt_rflags |= RRTF_CHANGED; in riprecv()
1368 rrt->rrt_t = t; in riprecv()
1370 } else if (nq->rip6_metric < np->rip6_metric && in riprecv()
1371 rrt->rrt_index == ifcp->ifc_index && in riprecv()
1372 IN6_ARE_ADDR_EQUAL(&nh, &rrt->rrt_gw)) { in riprecv()
1374 nq->rip6_metric = np->rip6_metric; in riprecv()
1375 rrt->rrt_t = t; in riprecv()
1376 rrt->rrt_rflags |= RRTF_CHANGED; in riprecv()
1378 } else if (nq->rip6_metric == np->rip6_metric && in riprecv()
1379 np->rip6_metric < HOPCNT_INFINITY6) { in riprecv()
1380 if (rrt->rrt_index == ifcp->ifc_index && in riprecv()
1381 IN6_ARE_ADDR_EQUAL(&nh, &rrt->rrt_gw)) { in riprecv()
1383 rrt->rrt_t = t; in riprecv()
1384 } else if (rrt->rrt_t < t_half_lifetime) { in riprecv()
1386 rrt->rrt_index = ifcp->ifc_index; in riprecv()
1388 delroute(nq, &rrt->rrt_gw); in riprecv()
1389 rrt->rrt_gw = nh; in riprecv()
1392 rrt->rrt_rflags |= RRTF_CHANGED; in riprecv()
1393 rrt->rrt_t = t; in riprecv()
1397 * if nq->rip6_metric == HOPCNT_INFINITY6 then in riprecv()
1400 } else if (np->rip6_metric < HOPCNT_INFINITY6) { in riprecv()
1407 nq = &rrt->rrt_info; in riprecv()
1409 rrt->rrt_same = NULL; in riprecv()
1410 rrt->rrt_index = ifcp->ifc_index; in riprecv()
1411 rrt->rrt_flags = RTF_UP|RTF_GATEWAY; in riprecv()
1412 rrt->rrt_gw = nh; in riprecv()
1414 applyplen(&nq->rip6_dest, nq->rip6_plen); in riprecv()
1415 if (nq->rip6_plen == sizeof(struct in6_addr) * 8) in riprecv()
1416 rrt->rrt_flags |= RTF_HOST; in riprecv()
1420 rrt->rrt_rflags |= RRTF_CHANGED; in riprecv()
1422 rrt->rrt_t = t; in riprecv()
1432 if (ifcp->ifc_index == ic->ifc_index) in riprecv()
1434 if (ic->ifc_flags & IFF_UP) in riprecv()
1435 ripsend(ic, &ic->ifc_ripsin, in riprecv()
1441 rrt->rrt_rflags &= ~RRTF_CHANGED; in riprecv()
1455 if (ifcp->ifc_flags & IFF_LOOPBACK) in sendrequest()
1457 ripbuf->rip6_cmd = RIP6_REQUEST; in sendrequest()
1458 np = ripbuf->rip6_nets; in sendrequest()
1460 np->rip6_metric = HOPCNT_INFINITY6; in sendrequest()
1462 ifcp->ifc_name, inet6_n2p(&ifcp->ifc_ripsin.sin6_addr)); in sendrequest()
1463 error = sendpacket(&ifcp->ifc_ripsin, RIPSIZE(1)); in sendrequest()
1468 ifcp->ifc_name, inet6_n2p(&ifcp->ifc_ripsin.sin6_addr)); in sendrequest()
1469 ifcp->ifc_flags &= ~IFF_UP; /* As if down for AF_INET6 */ in sendrequest()
1471 ripbuf->rip6_cmd = RIP6_RESPONSE; in sendrequest()
1486 if (!(nn == 1 && IN6_IS_ADDR_UNSPECIFIED(&np->rip6_dest) && in riprequest()
1487 np->rip6_plen == 0 && np->rip6_metric == HOPCNT_INFINITY6)) { in riprequest()
1488 /* Specific response, don't split-horizon */ in riprequest()
1493 np->rip6_metric = rrt->rrt_info.rip6_metric; in riprequest()
1495 np->rip6_metric = HOPCNT_INFINITY6; in riprequest()
1501 trace(1, "\tRIP Request -- whole routing table\n"); in riprequest()
1526 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { in ifconfig()
1527 if (ifa->ifa_addr->sa_family != AF_INET6) in ifconfig()
1529 ifcp = ifc_find(ifa->ifa_name); in ifconfig()
1530 /* we are interested in multicast-capable interfaces */ in ifconfig()
1531 if ((ifa->ifa_flags & IFF_MULTICAST) == 0) in ifconfig()
1541 ifcp->ifc_index = -1; in ifconfig()
1542 strlcpy(ifcp->ifc_name, ifa->ifa_name, in ifconfig()
1543 sizeof(ifcp->ifc_name)); in ifconfig()
1544 TAILQ_INIT(&ifcp->ifc_ifac_head); in ifconfig()
1545 TAILQ_INIT(&ifcp->ifc_iff_head); in ifconfig()
1546 ifcp->ifc_flags = ifa->ifa_flags; in ifconfig()
1548 trace(1, "newif %s <%s>\n", ifcp->ifc_name, in ifconfig()
1549 ifflags(ifcp->ifc_flags)); in ifconfig()
1550 if (!strcmp(ifcp->ifc_name, LOOPBACK_IF)) in ifconfig()
1554 if (ifcp->ifc_flags != ifa->ifa_flags) { in ifconfig()
1555 trace(1, "%s: <%s> -> ", ifcp->ifc_name, in ifconfig()
1556 ifflags(ifcp->ifc_flags)); in ifconfig()
1557 trace(1, "<%s>\n", ifflags(ifa->ifa_flags)); in ifconfig()
1558 ifcp->ifc_cflags |= IFC_CHANGED; in ifconfig()
1560 ifcp->ifc_flags = ifa->ifa_flags; in ifconfig()
1562 if (ifconfig1(ifa->ifa_name, ifa->ifa_addr, ifcp, s) < 0) { in ifconfig()
1566 if ((ifcp->ifc_flags & (IFF_LOOPBACK | IFF_UP)) == IFF_UP in ifconfig()
1567 && 0 < ifcp->ifc_index && !ifcp->ifc_joined) { in ifconfig()
1568 mreq.ipv6mr_multiaddr = ifcp->ifc_ripsin.sin6_addr; in ifconfig()
1569 mreq.ipv6mr_interface = ifcp->ifc_index; in ifconfig()
1575 trace(1, "join %s %s\n", ifcp->ifc_name, RIP6_DEST); in ifconfig()
1576 ifcp->ifc_joined++; in ifconfig()
1596 if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) && !lflag) in ifconfig1()
1597 return (-1); in ifconfig1()
1602 return (-1); in ifconfig1()
1605 if ((ifac = ifa_match(ifcp, &sin6->sin6_addr, plen)) != NULL) { in ifconfig1()
1609 return (-1); in ifconfig1()
1620 ifac->ifac_ifc = ifcp; in ifconfig1()
1621 ifac->ifac_addr = sin6->sin6_addr; in ifconfig1()
1622 ifac->ifac_plen = plen; in ifconfig1()
1623 ifac->ifac_scope_id = sin6->sin6_scope_id; in ifconfig1()
1624 if (ifcp->ifc_flags & IFF_POINTOPOINT) { in ifconfig1()
1630 ifac->ifac_raddr = ifr.ifr_dstaddr.sin6_addr; in ifconfig1()
1631 inet_ntop(AF_INET6, (void *)&ifac->ifac_raddr, buf, in ifconfig1()
1633 trace(1, "found address %s/%d -- %s\n", in ifconfig1()
1634 inet6_n2p(&ifac->ifac_addr), ifac->ifac_plen, buf); in ifconfig1()
1637 inet6_n2p(&ifac->ifac_addr), ifac->ifac_plen); in ifconfig1()
1639 if (ifcp->ifc_index < 0 && IN6_IS_ADDR_LINKLOCAL(&ifac->ifac_addr)) { in ifconfig1()
1640 ifcp->ifc_mylladdr = ifac->ifac_addr; in ifconfig1()
1641 ifcp->ifc_index = ifac->ifac_scope_id; in ifconfig1()
1642 memcpy(&ifcp->ifc_ripsin, &ripsin, ripsin.ss_len); in ifconfig1()
1643 ifcp->ifc_ripsin.sin6_scope_id = ifcp->ifc_index; in ifconfig1()
1644 setindex2ifc(ifcp->ifc_index, ifcp); in ifconfig1()
1645 ifcp->ifc_mtu = getifmtu(ifcp->ifc_index); in ifconfig1()
1646 if (ifcp->ifc_mtu > RIP6_MAXMTU) in ifconfig1()
1647 ifcp->ifc_mtu = RIP6_MAXMTU; in ifconfig1()
1652 ifcp->ifc_metric = ifr.ifr_metric; in ifconfig1()
1654 ifcp->ifc_index, ifcp->ifc_mtu, ifcp->ifc_metric); in ifconfig1()
1656 ifcp->ifc_cflags |= IFC_CHANGED; in ifconfig1()
1658 TAILQ_INSERT_HEAD(&ifcp->ifc_ifac_head, ifac, ifac_next); in ifconfig1()
1670 if (ifcp->ifc_index == ifindex) in ifremove()
1676 tracet(1, "ifremove: %s is departed.\n", ifcp->ifc_name); in ifremove()
1680 if (rrt->rrt_index == ifcp->ifc_index && in ifremove()
1681 rrt->rrt_rflags & RRTF_AGGREGATE) in ifremove()
1682 delroute(&rrt->rrt_info, &rrt->rrt_gw); in ifremove()
1696 struct rt_msghdr *rtm; in rtrecv() local
1715 if (len < sizeof(*rtm)) { in rtrecv()
1717 len, (u_long)sizeof(*rtm)); in rtrecv()
1730 for (p = buf; p - buf < len; p += in rtrecv()
1731 ((struct rt_msghdr *)(void *)p)->rtm_msglen) { in rtrecv()
1732 if (((struct rt_msghdr *)(void *)p)->rtm_version != RTM_VERSION) in rtrecv()
1736 if (((struct rt_msghdr *)(void *)p)->rtm_msglen <= 0) { in rtrecv()
1738 ((struct rt_msghdr *)(void *)p)->rtm_msglen); in rtrecv()
1741 rtm = NULL; in rtrecv()
1744 switch (((struct rt_msghdr *)(void *)p)->rtm_type) { in rtrecv()
1748 addrs = ifam->ifam_addrs; in rtrecv()
1753 addrs = ifm->ifm_addrs; in rtrecv()
1758 switch (ifan->ifan_what) { in rtrecv()
1763 ifremove(ifan->ifan_index); in rtrecv()
1769 rtm = (struct rt_msghdr *)(void *)p; in rtrecv()
1770 if (rtm->rtm_version != RTM_VERSION) { in rtrecv()
1773 rtm->rtm_version, RTM_VERSION); in rtrecv()
1777 * Only messages that use the struct rt_msghdr in rtrecv()
1780 if (rtm->rtm_type > RTM_RESOLVE) { in rtrecv()
1782 rtm->rtm_type); in rtrecv()
1785 addrs = rtm->rtm_addrs; in rtrecv()
1786 q = (char *)(rtm + 1); in rtrecv()
1787 if (rtm->rtm_pid == pid) { in rtrecv()
1799 q += ROUNDUP(rta[i]->sin6_len); in rtrecv()
1807 i < ((struct rt_msghdr *)(void *)p)->rtm_msglen; in rtrecv()
1818 * We may be able to optimize by using ifm->ifm_index or in rtrecv()
1819 * ifam->ifam_index. For simplicity we don't do that here. in rtrecv()
1821 switch (((struct rt_msghdr *)(void *)p)->rtm_type) { in rtrecv()
1843 if (rta[RTAX_DST]->sin6_family != AF_INET6) { in rtrecv()
1847 if (IN6_IS_ADDR_LINKLOCAL(&rta[RTAX_DST]->sin6_addr)) { in rtrecv()
1851 if (IN6_ARE_ADDR_EQUAL(&rta[RTAX_DST]->sin6_addr, &in6addr_loopback)) { in rtrecv()
1855 if (IN6_IS_ADDR_MULTICAST(&rta[RTAX_DST]->sin6_addr)) { in rtrecv()
1862 switch (((struct rt_msghdr *)(void *)p)->rtm_type) { in rtrecv()
1879 if ((rtm->rtm_flags & RTF_HOST) != 0) { in rtrecv()
1903 if (ifam->ifam_index < nindex2ifc) in rtrecv()
1904 ifcp = index2ifc[ifam->ifam_index]; in rtrecv()
1909 ifam->ifam_index); in rtrecv()
1923 if (ifcp->ifc_cflags & IFC_CHANGED) { in rtrecv()
1926 if (ifcp->ifc_index == ic->ifc_index) in rtrecv()
1928 if (ic->ifc_flags & IFF_UP) in rtrecv()
1929 ripsend(ic, &ic->ifc_ripsin, in rtrecv()
1934 rrt->rrt_rflags &= ~RRTF_CHANGED; in rtrecv()
1937 ifcp->ifc_cflags &= ~IFC_CHANGED; in rtrecv()
1962 if (sdst->sin6_family != AF_INET6) { in rt_del()
1964 return -1; in rt_del()
1966 if (IN6_IS_ADDR_LINKLOCAL(&sdst->sin6_addr) in rt_del()
1967 || IN6_ARE_ADDR_EQUAL(&sdst->sin6_addr, &in6addr_loopback) in rt_del()
1968 || IN6_IS_ADDR_MULTICAST(&sdst->sin6_addr)) { in rt_del()
1970 inet6_n2p(&sdst->sin6_addr)); in rt_del()
1971 return -1; in rt_del()
1973 dst = &sdst->sin6_addr; in rt_del()
1974 if (sgw->sin6_family == AF_INET6) { in rt_del()
1976 gw = &sgw->sin6_addr; in rt_del()
1978 } else if (sgw->sin6_family == AF_LINK) { in rt_del()
1990 if (IN6_ARE_ADDR_EQUAL(&rrt->rrt_info.rip6_dest, in rt_del()
1991 &sdst->sin6_addr) in rt_del()
1992 && IN6_IS_ADDR_LOOPBACK(&rrt->rrt_gw)) { in rt_del()
1994 || longest->rrt_info.rip6_plen < in rt_del()
1995 rrt->rrt_info.rip6_plen) { in rt_del()
2003 return -1; in rt_del()
2006 prefix = rrt->rrt_info.rip6_plen; in rt_del()
2008 trace(1, "\tunsupported af: (gw=%d)\n", sgw->sin6_family); in rt_del()
2009 return -1; in rt_del()
2014 t_lifetime = time(NULL) - RIP_LIFETIME; in rt_del()
2024 return -1; in rt_del()
2027 if ((rrt->rrt_flags & RTF_STATIC) == 0) { in rt_del()
2031 if (!IN6_ARE_ADDR_EQUAL(&rrt->rrt_gw, gw)) { in rt_del()
2032 trace(1, "\tgw mismatch: %s <-> ", in rt_del()
2033 inet6_n2p(&rrt->rrt_gw)); in rt_del()
2037 if (rrt->rrt_t == 0 || rrt->rrt_t > t_lifetime) { in rt_del()
2038 rrt->rrt_t = t_lifetime; in rt_del()
2039 rrt->rrt_info.rip6_metric = HOPCNT_INFINITY6; in rt_del()
2061 if (sifa->sin6_family != AF_INET6) { in rt_deladdr()
2063 return -1; in rt_deladdr()
2065 addr = &sifa->sin6_addr; in rt_deladdr()
2069 inet6_n2p(addr), prefix, ifcp->ifc_name); in rt_deladdr()
2073 inet6_n2p(addr), prefix, ifcp->ifc_name); in rt_deladdr()
2074 return -1; in rt_deladdr()
2076 if (ifac->ifac_ifc != ifcp) { in rt_deladdr()
2079 ifcp->ifc_name, ifac->ifac_ifc->ifc_name); in rt_deladdr()
2080 return -1; in rt_deladdr()
2082 TAILQ_REMOVE(&ifcp->ifc_ifac_head, ifac, ifac_next); in rt_deladdr()
2083 t_lifetime = time(NULL) - RIP_LIFETIME; in rt_deladdr()
2086 ni6.rip6_dest = ifac->ifac_addr; in rt_deladdr()
2087 ni6.rip6_plen = ifac->ifac_plen; in rt_deladdr()
2090 inet6_n2p(&ni6.rip6_dest), ni6.rip6_plen, ifcp->ifc_index); in rt_deladdr()
2094 if (rrt->rrt_index == ifcp->ifc_index && in rt_deladdr()
2095 (IN6_ARE_ADDR_EQUAL(&rrt->rrt_gw, &none) || in rt_deladdr()
2096 IN6_IS_ADDR_LOOPBACK(&rrt->rrt_gw))) { in rt_deladdr()
2098 if (rrt->rrt_t == 0 || rrt->rrt_t > t_lifetime) { in rt_deladdr()
2099 rrt->rrt_t = t_lifetime; in rt_deladdr()
2100 rrt->rrt_info.rip6_metric = HOPCNT_INFINITY6; in rt_deladdr()
2104 trace(1, "\tnon-interface route found: %s/%d on %d\n", in rt_deladdr()
2105 inet6_n2p(&rrt->rrt_info.rip6_dest), in rt_deladdr()
2106 rrt->rrt_info.rip6_plen, in rt_deladdr()
2107 rrt->rrt_index); in rt_deladdr()
2112 if (ifcp->ifc_flags & IFF_POINTOPOINT) { in rt_deladdr()
2114 ni6.rip6_dest = ifac->ifac_raddr; in rt_deladdr()
2119 ifcp->ifc_index); in rt_deladdr()
2121 if (rrt->rrt_index == ifcp->ifc_index && in rt_deladdr()
2122 IN6_ARE_ADDR_EQUAL(&rrt->rrt_gw, in rt_deladdr()
2123 &ifac->ifac_addr)) { in rt_deladdr()
2125 if (rrt->rrt_t == 0 || rrt->rrt_t > t_lifetime) { in rt_deladdr()
2126 rrt->rrt_t = t_lifetime; in rt_deladdr()
2127 rrt->rrt_info.rip6_metric = in rt_deladdr()
2132 trace(1, "\tnon-p2p route found: %s/%d on %d\n", in rt_deladdr()
2133 inet6_n2p(&rrt->rrt_info.rip6_dest), in rt_deladdr()
2134 rrt->rrt_info.rip6_plen, in rt_deladdr()
2135 rrt->rrt_index); in rt_deladdr()
2142 return ((updated) ? 0 : -1); in rt_deladdr()
2159 if (ifcp->ifc_flags & IFF_LOOPBACK) in ifrt()
2163 if (ifcp->ifc_flags & IFF_POINTOPOINT) { in ifrt()
2168 TAILQ_FOREACH(ifac, &ifcp->ifc_ifac_head, ifac_next) { in ifrt()
2169 if (IN6_IS_ADDR_LINKLOCAL(&ifac->ifac_addr)) { in ifrt()
2173 inet6_n2p(&ifac->ifac_addr), ifcp->ifc_name); in ifrt()
2177 if (IN6_IS_ADDR_UNSPECIFIED(&ifac->ifac_addr)) { in ifrt()
2180 ifcp->ifc_name); in ifrt()
2184 if (IN6_IS_ADDR_LOOPBACK(&ifac->ifac_addr)) { in ifrt()
2187 ifcp->ifc_name); in ifrt()
2191 if (ifcp->ifc_flags & IFF_UP) { in ifrt()
2195 rrt->rrt_same = NULL; in ifrt()
2196 rrt->rrt_index = ifcp->ifc_index; in ifrt()
2197 rrt->rrt_t = 0; /* don't age */ in ifrt()
2198 rrt->rrt_info.rip6_dest = ifac->ifac_addr; in ifrt()
2199 rrt->rrt_info.rip6_tag = htons(routetag & 0xffff); in ifrt()
2200 rrt->rrt_info.rip6_metric = 1 + ifcp->ifc_metric; in ifrt()
2201 rrt->rrt_info.rip6_plen = ifac->ifac_plen; in ifrt()
2202 rrt->rrt_flags = RTF_HOST; in ifrt()
2203 rrt->rrt_rflags |= RRTF_CHANGED; in ifrt()
2204 applyplen(&rrt->rrt_info.rip6_dest, ifac->ifac_plen); in ifrt()
2205 memset(&rrt->rrt_gw, 0, sizeof(struct in6_addr)); in ifrt()
2206 rrt->rrt_gw = ifac->ifac_addr; in ifrt()
2207 np = &rrt->rrt_info; in ifrt()
2210 if (search_rrt->rrt_info.rip6_metric <= in ifrt()
2211 rrt->rrt_info.rip6_metric) { in ifrt()
2216 inet6_n2p(&np->rip6_dest), np->rip6_plen, in ifrt()
2217 ifcp->ifc_name); in ifrt()
2223 delroute(&search_rrt->rrt_info, in ifrt()
2224 &search_rrt->rrt_gw); in ifrt()
2229 inet6_n2p(&np->rip6_dest), np->rip6_plen, in ifrt()
2230 ifcp->ifc_name); in ifrt()
2232 addroute(rrt, &rrt->rrt_gw, ifcp); in ifrt()
2235 ripsend(ifcp, &ifcp->ifc_ripsin, 0); in ifrt()
2239 if (loop_rrt->rrt_index == ifcp->ifc_index) { in ifrt()
2240 t_lifetime = time(NULL) - RIP_LIFETIME; in ifrt()
2241 if (loop_rrt->rrt_t == 0 || loop_rrt->rrt_t > t_lifetime) { in ifrt()
2242 loop_rrt->rrt_t = t_lifetime; in ifrt()
2243 loop_rrt->rrt_info.rip6_metric = HOPCNT_INFINITY6; in ifrt()
2244 loop_rrt->rrt_rflags |= RRTF_CHANGED; in ifrt()
2278 TAILQ_FOREACH(ifac, &ifcp->ifc_ifac_head, ifac_next) { in ifrt_p2p()
2279 addr = ifac->ifac_addr; in ifrt_p2p()
2280 dest = ifac->ifac_raddr; in ifrt_p2p()
2281 applyplen(&addr, ifac->ifac_plen); in ifrt_p2p()
2282 applyplen(&dest, ifac->ifac_plen); in ifrt_p2p()
2319 * A/n -> announce A/n in ifrt_p2p()
2320 * A B/n, A and B share prefix -> A/n (= B/n) in ifrt_p2p()
2321 * A B/n, do not share prefix -> A/128 and B/128 in ifrt_p2p()
2324 * A/64 -> A/64 in ifrt_p2p()
2325 * A B/128 -> A/128 and B/128 in ifrt_p2p()
2327 if (!IN6_IS_ADDR_UNSPECIFIED(&ifac->ifac_raddr)) { in ifrt_p2p()
2348 rrt->rrt_same = NULL; in ifrt_p2p()
2349 rrt->rrt_index = ifcp->ifc_index; in ifrt_p2p()
2350 rrt->rrt_t = 0; /* don't age */ in ifrt_p2p()
2353 rrt->rrt_info.rip6_dest = ifac->ifac_addr; in ifrt_p2p()
2354 rrt->rrt_info.rip6_plen = ifac->ifac_plen; in ifrt_p2p()
2355 applyplen(&rrt->rrt_info.rip6_dest, in ifrt_p2p()
2356 ifac->ifac_plen); in ifrt_p2p()
2360 rrt->rrt_info.rip6_dest = ifac->ifac_addr; in ifrt_p2p()
2361 rrt->rrt_info.rip6_plen = 128; in ifrt_p2p()
2362 rrt->rrt_gw = in6addr_loopback; in ifrt_p2p()
2366 rrt->rrt_info.rip6_dest = ifac->ifac_raddr; in ifrt_p2p()
2367 rrt->rrt_info.rip6_plen = 128; in ifrt_p2p()
2368 rrt->rrt_gw = ifac->ifac_addr; in ifrt_p2p()
2372 if (IN6_IS_ADDR_UNSPECIFIED(&rrt->rrt_info.rip6_dest) || in ifrt_p2p()
2373 IN6_IS_ADDR_LINKLOCAL(&rrt->rrt_info.rip6_dest)) { in ifrt_p2p()
2376 "(%s on %s)\n", category, ifcp->ifc_name); in ifrt_p2p()
2382 rrt->rrt_rflags |= RRTF_NOADVERTISE; in ifrt_p2p()
2383 noadv = ", NO-ADV"; in ifrt_p2p()
2386 rrt->rrt_info.rip6_tag = htons(routetag & 0xffff); in ifrt_p2p()
2387 rrt->rrt_info.rip6_metric = 1 + ifcp->ifc_metric; in ifrt_p2p()
2388 np = &rrt->rrt_info; in ifrt_p2p()
2394 inet6_n2p(&np->rip6_dest), np->rip6_plen, in ifrt_p2p()
2395 category, ifcp->ifc_name, noadv); in ifrt_p2p()
2397 } else if (rrt->rrt_index != orrt->rrt_index || in ifrt_p2p()
2398 rrt->rrt_info.rip6_metric != orrt->rrt_info.rip6_metric) { in ifrt_p2p()
2405 inet6_n2p(&np->rip6_dest), np->rip6_plen, in ifrt_p2p()
2406 category, ifcp->ifc_name, noadv); in ifrt_p2p()
2412 inet6_n2p(&np->rip6_dest), in ifrt_p2p()
2413 np->rip6_plen, category, in ifrt_p2p()
2414 ifcp->ifc_name, noadv); in ifrt_p2p()
2454 mtu = ifm->ifm_data.ifi_mtu; in getifmtu()
2455 if (ifindex != ifm->ifm_index) { in getifmtu()
2464 rttypes(struct rt_msghdr *rtm) in rttypes() argument
2468 if (rtm->rtm_type == (f)) \ in rttypes()
2499 rtflags(struct rt_msghdr *rtm) in rtflags() argument
2509 if (rtm->rtm_flags & (f)) \ in rtflags()
2600 struct rt_msghdr *rtm; in krtread() local
2642 for (p = buf; p < lim; p += rtm->rtm_msglen) { in krtread()
2643 rtm = (struct rt_msghdr *)(void *)p; in krtread()
2644 rt_entry(rtm, again); in krtread()
2650 rt_entry(struct rt_msghdr *rtm, int again) in rt_entry() argument
2660 if ((rtm->rtm_flags & RTF_UP) == 0 || rtm->rtm_flags & in rt_entry()
2666 if (rtm->rtm_flags & RTF_WASCLONED) in rt_entry()
2670 if (rtm->rtm_flags & RTF_CLONED) in rt_entry()
2674 if (!(rtm->rtm_flags & (RTF_GATEWAY|RTF_HOST|RTF_STATIC))) in rt_entry()
2680 if (rtm->rtm_flags & RTF_DYNAMIC) in rt_entry()
2682 rtmp = (char *)(rtm + 1); in rt_entry()
2684 if ((rtm->rtm_addrs & RTA_DST) == 0) in rt_entry()
2687 rtmp += ROUNDUP(sin6_dst->sin6_len); in rt_entry()
2688 if (rtm->rtm_addrs & RTA_GATEWAY) { in rt_entry()
2690 rtmp += ROUNDUP(sin6_gw->sin6_len); in rt_entry()
2692 if (rtm->rtm_addrs & RTA_NETMASK) { in rt_entry()
2694 rtmp += ROUNDUP(sin6_mask->sin6_len); in rt_entry()
2696 if (rtm->rtm_addrs & RTA_GENMASK) { in rt_entry()
2698 rtmp += ROUNDUP(sin6_genmask->sin6_len); in rt_entry()
2700 if (rtm->rtm_addrs & RTA_IFP) { in rt_entry()
2702 rtmp += ROUNDUP(sin6_ifp->sin6_len); in rt_entry()
2706 if (sin6_dst->sin6_family != AF_INET6) in rt_entry()
2708 if (IN6_IS_ADDR_LINKLOCAL(&sin6_dst->sin6_addr)) in rt_entry()
2709 return; /* Link-local */ in rt_entry()
2710 if (IN6_ARE_ADDR_EQUAL(&sin6_dst->sin6_addr, &in6addr_loopback)) in rt_entry()
2712 if (IN6_IS_ADDR_MULTICAST(&sin6_dst->sin6_addr)) in rt_entry()
2720 np = &rrt->rrt_info; in rt_entry()
2721 rrt->rrt_same = NULL; in rt_entry()
2722 rrt->rrt_t = time(NULL); in rt_entry()
2723 if (aflag == 0 && (rtm->rtm_flags & RTF_STATIC)) in rt_entry()
2724 rrt->rrt_t = 0; /* Don't age static routes */ in rt_entry()
2725 if (rtm->rtm_flags & Pflag) in rt_entry()
2726 rrt->rrt_t = 0; /* Don't age PROTO[123] routes */ in rt_entry()
2727 if ((rtm->rtm_flags & (RTF_HOST|RTF_GATEWAY)) == RTF_HOST) in rt_entry()
2728 rrt->rrt_t = 0; /* Don't age non-gateway host routes */ in rt_entry()
2729 np->rip6_tag = 0; in rt_entry()
2730 np->rip6_metric = rtm->rtm_rmx.rmx_hopcount; in rt_entry()
2731 if (np->rip6_metric < 1) in rt_entry()
2732 np->rip6_metric = 1; in rt_entry()
2733 rrt->rrt_flags = rtm->rtm_flags; in rt_entry()
2734 np->rip6_dest = sin6_dst->sin6_addr; in rt_entry()
2737 if (rtm->rtm_flags & RTF_HOST) in rt_entry()
2738 np->rip6_plen = 128; /* Host route */ in rt_entry()
2740 np->rip6_plen = sin6mask2len(sin6_mask); in rt_entry()
2742 np->rip6_plen = 0; in rt_entry()
2745 if (orrt && orrt->rrt_info.rip6_metric != HOPCNT_INFINITY6) { in rt_entry()
2749 inet6_n2p(&np->rip6_dest), np->rip6_plen, in rt_entry()
2750 rtflags(rtm)); in rt_entry()
2757 memset(&rrt->rrt_gw, 0, sizeof(struct in6_addr)); in rt_entry()
2759 if (sin6_gw->sin6_family == AF_INET6) in rt_entry()
2760 rrt->rrt_gw = sin6_gw->sin6_addr; in rt_entry()
2761 else if (sin6_gw->sin6_family == AF_LINK) { in rt_entry()
2763 rrt->rrt_gw = in6addr_loopback; in rt_entry()
2765 memset(&rrt->rrt_gw, 0, sizeof(struct in6_addr)); in rt_entry()
2768 inet6_n2p(&np->rip6_dest), np->rip6_plen, rtflags(rtm)); in rt_entry()
2769 trace(1, " gw %s", inet6_n2p(&rrt->rrt_gw)); in rt_entry()
2772 ifindex = rtm->rtm_index; in rt_entry()
2774 ifname = index2ifc[ifindex]->ifc_name; in rt_entry()
2781 rrt->rrt_index = ifindex; in rt_entry()
2786 if (!IN6_IS_ADDR_LINKLOCAL(&rrt->rrt_gw) && in rt_entry()
2787 !IN6_IS_ADDR_LOOPBACK(&rrt->rrt_gw) && in rt_entry()
2788 (rrt->rrt_flags & RTF_LOCAL) == 0) { in rt_entry()
2789 trace(0, "***** Gateway %s is not a link-local address.\n", in rt_entry()
2790 inet6_n2p(&rrt->rrt_gw)); in rt_entry()
2791 trace(0, "***** dest(%s) if(%s) -- Not optimized.\n", in rt_entry()
2792 inet6_n2p(&rrt->rrt_info.rip6_dest), ifname); in rt_entry()
2793 rrt->rrt_rflags |= RRTF_NH_NOT_LLADDR; in rt_entry()
2797 if (orrt && orrt->rrt_info.rip6_metric == HOPCNT_INFINITY6) { in rt_entry()
2803 inet6_n2p(&np->rip6_dest), np->rip6_plen, in rt_entry()
2804 rtflags(rtm)); in rt_entry()
2817 struct rt_msghdr *rtm; in addroute() local
2821 np = &rrt->rrt_info; in addroute()
2823 inet_ntop(AF_INET6, (void *)&ifcp->ifc_mylladdr, (char *)buf2, sizeof(buf2)); in addroute()
2825 inet6_n2p(&np->rip6_dest), np->rip6_plen, buf1, in addroute()
2826 np->rip6_metric - 1, buf2); in addroute()
2829 inet6_n2p(&np->rip6_dest), np->rip6_plen, buf1, in addroute()
2830 np->rip6_metric - 1, buf2); in addroute()
2835 rtm = (struct rt_msghdr *)(void *)buf; in addroute()
2836 rtm->rtm_type = RTM_ADD; in addroute()
2837 rtm->rtm_version = RTM_VERSION; in addroute()
2838 rtm->rtm_seq = ++seq; in addroute()
2839 rtm->rtm_pid = pid; in addroute()
2840 rtm->rtm_flags = rrt->rrt_flags; in addroute()
2841 rtm->rtm_flags |= Qflag; in addroute()
2842 rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; in addroute()
2843 rtm->rtm_rmx.rmx_hopcount = np->rip6_metric - 1; in addroute()
2844 rtm->rtm_inits = RTV_HOPCOUNT; in addroute()
2847 sin6->sin6_len = sizeof(struct sockaddr_in6); in addroute()
2848 sin6->sin6_family = AF_INET6; in addroute()
2849 sin6->sin6_addr = np->rip6_dest; in addroute()
2850 sin6 = (struct sockaddr_in6 *)(void *)((char *)sin6 + ROUNDUP(sin6->sin6_len)); in addroute()
2852 sin6->sin6_len = sizeof(struct sockaddr_in6); in addroute()
2853 sin6->sin6_family = AF_INET6; in addroute()
2854 sin6->sin6_addr = *gw; in addroute()
2855 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) in addroute()
2856 sin6->sin6_scope_id = ifcp->ifc_index; in addroute()
2857 sin6 = (struct sockaddr_in6 *)(void *)((char *)sin6 + ROUNDUP(sin6->sin6_len)); in addroute()
2859 sin6->sin6_len = sizeof(struct sockaddr_in6); in addroute()
2860 sin6->sin6_family = AF_INET6; in addroute()
2861 sin6->sin6_addr = *(plen2mask(np->rip6_plen)); in addroute()
2862 sin6 = (struct sockaddr_in6 *)(void *)((char *)sin6 + ROUNDUP(sin6->sin6_len)); in addroute()
2864 len = (char *)sin6 - (char *)buf; in addroute()
2865 rtm->rtm_msglen = len; in addroute()
2871 inet6_n2p(&np->rip6_dest), np->rip6_plen, buf1); in addroute()
2874 inet6_n2p(&np->rip6_dest), np->rip6_plen, buf1); in addroute()
2882 return -1; in addroute()
2889 struct rt_msghdr *rtm; in delroute() local
2894 tracet(1, "DEL: %s/%d gw %s\n", inet6_n2p(&np->rip6_dest), in delroute()
2895 np->rip6_plen, buf2); in delroute()
2898 hms(), inet6_n2p(&np->rip6_dest), np->rip6_plen, buf2); in delroute()
2903 rtm = (struct rt_msghdr *)(void *)buf; in delroute()
2904 rtm->rtm_type = RTM_DELETE; in delroute()
2905 rtm->rtm_version = RTM_VERSION; in delroute()
2906 rtm->rtm_seq = ++seq; in delroute()
2907 rtm->rtm_pid = pid; in delroute()
2908 rtm->rtm_flags = RTF_UP | RTF_GATEWAY; in delroute()
2909 rtm->rtm_flags |= Qflag; in delroute()
2910 if (np->rip6_plen == sizeof(struct in6_addr) * 8) in delroute()
2911 rtm->rtm_flags |= RTF_HOST; in delroute()
2912 rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; in delroute()
2915 sin6->sin6_len = sizeof(struct sockaddr_in6); in delroute()
2916 sin6->sin6_family = AF_INET6; in delroute()
2917 sin6->sin6_addr = np->rip6_dest; in delroute()
2918 sin6 = (struct sockaddr_in6 *)(void *)((char *)sin6 + ROUNDUP(sin6->sin6_len)); in delroute()
2920 sin6->sin6_len = sizeof(struct sockaddr_in6); in delroute()
2921 sin6->sin6_family = AF_INET6; in delroute()
2922 sin6->sin6_addr = *gw; in delroute()
2923 sin6 = (struct sockaddr_in6 *)(void *)((char *)sin6 + ROUNDUP(sin6->sin6_len)); in delroute()
2925 sin6->sin6_len = sizeof(struct sockaddr_in6); in delroute()
2926 sin6->sin6_family = AF_INET6; in delroute()
2927 sin6->sin6_addr = *(plen2mask(np->rip6_plen)); in delroute()
2928 sin6 = (struct sockaddr_in6 *)(void *)((char *)sin6 + ROUNDUP(sin6->sin6_len)); in delroute()
2930 len = (char *)sin6 - (char *)buf; in delroute()
2931 rtm->rtm_msglen = len; in delroute()
2937 inet6_n2p(&np->rip6_dest), np->rip6_plen, buf2); in delroute()
2940 inet6_n2p(&np->rip6_dest), np->rip6_plen, buf2); in delroute()
2948 return -1; in delroute()
2958 struct rt_msghdr *rtm;
2961 rtm = (struct rt_msghdr *)(void *)buf;
2963 memset(rtm, 0, len);
2964 rtm->rtm_type = RTM_GET;
2965 rtm->rtm_version = RTM_VERSION;
2967 rtm->rtm_seq = myseq;
2968 rtm->rtm_addrs = RTA_DST;
2969 rtm->rtm_msglen = len;
2971 sin6->sin6_len = sizeof(struct sockaddr_in6);
2972 sin6->sin6_family = AF_INET6;
2973 sin6->sin6_addr = np->rip6_dest;
2985 rtm = (struct rt_msghdr *)(void *)buf;
2986 } while (rtm->rtm_type != RTM_GET || rtm->rtm_seq != myseq ||
2987 rtm->rtm_pid != pid);
2989 if (rtm->rtm_addrs & RTA_DST) {
2991 ((char *)sin6 + ROUNDUP(sin6->sin6_len));
2993 if (rtm->rtm_addrs & RTA_GATEWAY) {
2994 *gw = sin6->sin6_addr;
3037 if ((ifcp->ifc_flags & IFF_UP) == 0) in ifdump()
3044 fprintf(dump, " non-advertising interfaces:\n"); in ifdump()
3046 if ((ifcp->ifc_flags & IFF_UP) && in ifdump()
3066 ifcp->ifc_name, ifcp->ifc_index, ifflags(ifcp->ifc_flags), in ifdump0()
3067 inet6_n2p(&ifcp->ifc_mylladdr), in ifdump0()
3068 ifcp->ifc_mtu, ifcp->ifc_metric); in ifdump0()
3069 TAILQ_FOREACH(ifac, &ifcp->ifc_ifac_head, ifac_next) { in ifdump0()
3070 if (ifcp->ifc_flags & IFF_POINTOPOINT) { in ifdump0()
3071 inet_ntop(AF_INET6, (void *)&ifac->ifac_raddr, in ifdump0()
3073 fprintf(dump, "\t%s/%d -- %s\n", in ifdump0()
3074 inet6_n2p(&ifac->ifac_addr), in ifdump0()
3075 ifac->ifac_plen, buf); in ifdump0()
3078 inet6_n2p(&ifac->ifac_addr), in ifdump0()
3079 ifac->ifac_plen); in ifdump0()
3084 TAILQ_FOREACH(iffp, &ifcp->ifc_iff_head, iff_next) { in ifdump0()
3086 switch (iffp->iff_type) { in ifdump0()
3090 ft = "No-use"; break; in ifdump0()
3092 ft = "Advertise-only"; addr++; break; in ifdump0()
3094 ft = "Default-only"; break; in ifdump0()
3096 ft = "Listen-only"; addr++; break; in ifdump0()
3098 snprintf(buf, sizeof(buf), "Unknown-%c", iffp->iff_type); in ifdump0()
3105 fprintf(dump, "(%s/%d)", inet6_n2p(&iffp->iff_addr), in ifdump0()
3106 iffp->iff_plen); in ifdump0()
3129 if (rrt->rrt_t == 0) in rtdump()
3132 age = t - rrt->rrt_t; in rtdump()
3133 inet_ntop(AF_INET6, (void *)&rrt->rrt_info.rip6_dest, in rtdump()
3136 buf, rrt->rrt_info.rip6_plen, rrt->rrt_index, in rtdump()
3137 index2ifc[rrt->rrt_index]->ifc_name, in rtdump()
3138 inet6_n2p(&rrt->rrt_gw), in rtdump()
3139 rrt->rrt_info.rip6_metric, (long)age); in rtdump()
3140 if (rrt->rrt_info.rip6_tag) { in rtdump()
3142 ntohs(rrt->rrt_info.rip6_tag) & 0xffff); in rtdump()
3144 if (rrt->rrt_rflags & RRTF_NH_NOT_LLADDR) in rtdump()
3145 fprintf(dump, " NOT-LL"); in rtdump()
3146 if (rrt->rrt_rflags & RRTF_NOADVERTISE) in rtdump()
3147 fprintf(dump, " NO-ADV"); in rtdump()
3156 * Parse the -A (and -O) options and put corresponding filter object to the
3157 * specified interface structures. Each of the -A/O option has the following
3158 * syntax: -A 5f09:c400::/32,ef0,ef1 (aggregate)
3159 * -O 5f09:c400::/32,ef0,ef1 (only when match)
3192 if (inet_pton(AF_INET6, ap, &iffp->iff_addr) != 1) { in filterconfig()
3199 if (errno || !*p || *ep || plen > sizeof(iffp->iff_addr) * 8) { in filterconfig()
3203 iffp->iff_plen = plen; in filterconfig()
3204 applyplen(&iffp->iff_addr, iffp->iff_plen); in filterconfig()
3206 iffp->iff_type = filtertype[i]; in filterconfig()
3218 if (fnmatch(ifname, ifcp->ifc_name, 0) != 0) in filterconfig()
3228 syslog(LOG_INFO, "Add filter: type %d, ifname %s.", iffp->iff_type, ifname); in filterconfig()
3230 TAILQ_INSERT_HEAD(&ifcp->ifc_iff_head, iffp, iff_next); in filterconfig()
3235 * -A: aggregate configuration. in filterconfig()
3246 rrt->rrt_info.rip6_dest = iff.iff_addr; in filterconfig()
3247 rrt->rrt_info.rip6_plen = iff.iff_plen; in filterconfig()
3248 rrt->rrt_info.rip6_metric = 1; in filterconfig()
3249 rrt->rrt_info.rip6_tag = htons(routetag & 0xffff); in filterconfig()
3250 rrt->rrt_gw = in6addr_loopback; in filterconfig()
3251 rrt->rrt_flags = RTF_UP | RTF_REJECT; in filterconfig()
3252 rrt->rrt_rflags = RRTF_AGGREGATE; in filterconfig()
3253 rrt->rrt_t = 0; in filterconfig()
3254 rrt->rrt_index = loopifcp->ifc_index; in filterconfig()
3256 if (getroute(&rrt->rrt_info, &gw)) { in filterconfig()
3262 delroute(&rrt->rrt_info, &gw); in filterconfig()
3268 inet6_n2p(&rrt->rrt_info.rip6_dest), in filterconfig()
3269 rrt->rrt_info.rip6_plen); in filterconfig()
3278 loopifcp->ifc_name); in filterconfig()
3299 TAILQ_FOREACH(ifac, &ifcp->ifc_ifac_head, ifac_next) { in ifa_match()
3300 if (IN6_ARE_ADDR_EQUAL(&ifac->ifac_addr, ia) && in ifa_match()
3301 ifac->ifac_plen == plen) in ifa_match()
3319 if (rrt->rrt_info.rip6_plen == np->rip6_plen && in rtsearch()
3320 IN6_ARE_ADDR_EQUAL(&rrt->rrt_info.rip6_dest, in rtsearch()
3321 &np->rip6_dest)) in rtsearch()
3332 return mask2len(&sin6->sin6_addr, in sin6mask2len()
3333 sin6->sin6_len - offsetof(struct sockaddr_in6, sin6_addr)); in sin6mask2len()
3373 p = ia->s6_addr; in applyplen()
3379 p++, plen -= 8; in applyplen()
3396 for (i = 0; i < 16; i++, p++, n -= 8) { in plen2mask()
3434 snprintf(buf, sizeof(buf), "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, in hms()
3435 tm->tm_sec); in hms()
3439 #define RIPRANDDEV 1.0 /* 30 +- 15, max - min = 30 */
3446 interval = (int)(timer + timer * RIPRANDDEV * (r / RAND_MAX - 0.5)); in ripinterval()
3459 (RIP_TRIG_INT6_MAX - RIP_TRIG_INT6_MIN) * (r / RAND_MAX));
3529 if (strcmp(name, ifcp->ifc_name) == 0) in ifc_find()
3540 TAILQ_FOREACH(iffp, &ifcp->ifc_iff_head, iff_next) { in iff_find()
3542 type == iffp->iff_type) in iff_find()
3575 memset(p + n, 0, sizeof(*index2ifc) * (nindex2ifc - n)); in setindex2ifc()