table.c (18322) | table.c (19885) |
---|---|
1/* 2 * Copyright (c) 1983, 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 22 unchanged lines hidden (view full) --- 31 * SUCH DAMAGE. 32 */ 33 34#if !defined(lint) && !defined(sgi) && !defined(__NetBSD__) 35static char sccsid[] = "@(#)tables.c 8.1 (Berkeley) 6/5/93"; 36#elif defined(__NetBSD__) 37static char rcsid[] = "$NetBSD$"; 38#endif | 1/* 2 * Copyright (c) 1983, 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 22 unchanged lines hidden (view full) --- 31 * SUCH DAMAGE. 32 */ 33 34#if !defined(lint) && !defined(sgi) && !defined(__NetBSD__) 35static char sccsid[] = "@(#)tables.c 8.1 (Berkeley) 6/5/93"; 36#elif defined(__NetBSD__) 37static char rcsid[] = "$NetBSD$"; 38#endif |
39#ident "$Revision: 1.1.1.1 $" | |
40 41#include "defs.h" 42 43static struct rt_spare *rts_better(struct rt_entry *); 44 45struct radix_node_head *rhead; /* root of the radix tree */ 46 47int need_flash = 1; /* flash update needed --- 4 unchanged lines hidden (view full) --- 52struct timeval need_kern = { /* need to update kernel table */ 53 EPOCH+MIN_WAITTIME-1 54}; 55 56int stopint; 57 58int total_routes; 59 | 39 40#include "defs.h" 41 42static struct rt_spare *rts_better(struct rt_entry *); 43 44struct radix_node_head *rhead; /* root of the radix tree */ 45 46int need_flash = 1; /* flash update needed --- 4 unchanged lines hidden (view full) --- 51struct timeval need_kern = { /* need to update kernel table */ 52 EPOCH+MIN_WAITTIME-1 53}; 54 55int stopint; 56 57int total_routes; 58 |
59/* zap any old routes through this gateway */ |
|
60naddr age_bad_gate; 61 62 63/* It is desirable to "aggregate" routes, to combine differing routes of 64 * the same metric and next hop into a common route with a smaller netmask 65 * or to suppress redundant routes, routes that add no information to 66 * routes with smaller netmasks. 67 * --- 631 unchanged lines hidden (view full) --- 699 700#ifndef NO_INSTALL 701 cc = write(rt_sock, &w, w.w_rtm.rtm_msglen); 702 if (cc == w.w_rtm.rtm_msglen) 703 return; 704 if (cc < 0) { 705 if (errno == ESRCH 706 && (action == RTM_CHANGE || action == RTM_DELETE)) { | 60naddr age_bad_gate; 61 62 63/* It is desirable to "aggregate" routes, to combine differing routes of 64 * the same metric and next hop into a common route with a smaller netmask 65 * or to suppress redundant routes, routes that add no information to 66 * routes with smaller netmasks. 67 * --- 631 unchanged lines hidden (view full) --- 699 700#ifndef NO_INSTALL 701 cc = write(rt_sock, &w, w.w_rtm.rtm_msglen); 702 if (cc == w.w_rtm.rtm_msglen) 703 return; 704 if (cc < 0) { 705 if (errno == ESRCH 706 && (action == RTM_CHANGE || action == RTM_DELETE)) { |
707 trace_act("route to %s disappeared before %s\n", | 707 trace_act("route to %s disappeared before %s", |
708 addrname(dst, mask, 0), 709 rtm_type_name(action)); 710 if (action == RTM_CHANGE) { 711 action = RTM_ADD; 712 goto again; 713 } 714 return; 715 } --- 110 unchanged lines hidden (view full) --- 826 naddr mask; 827 828 829 if (rtm->rtm_flags & RTF_HOST) { 830 mask = HOST_MASK; 831 } else if (INFO_MASK(info) != 0) { 832 mask = ntohl(S_ADDR(INFO_MASK(info))); 833 } else { | 708 addrname(dst, mask, 0), 709 rtm_type_name(action)); 710 if (action == RTM_CHANGE) { 711 action = RTM_ADD; 712 goto again; 713 } 714 return; 715 } --- 110 unchanged lines hidden (view full) --- 826 naddr mask; 827 828 829 if (rtm->rtm_flags & RTF_HOST) { 830 mask = HOST_MASK; 831 } else if (INFO_MASK(info) != 0) { 832 mask = ntohl(S_ADDR(INFO_MASK(info))); 833 } else { |
834 msglog("punt %s without mask", | 834 msglog("ignore %s without mask", |
835 rtm_type_name(rtm->rtm_type)); 836 return; 837 } 838 839 if (INFO_GATE(info) == 0 840 || INFO_GATE(info)->sa_family != AF_INET) { | 835 rtm_type_name(rtm->rtm_type)); 836 return; 837 } 838 839 if (INFO_GATE(info) == 0 840 || INFO_GATE(info)->sa_family != AF_INET) { |
841 msglog("punt %s without gateway", | 841 msglog("ignore %s without gateway", |
842 rtm_type_name(rtm->rtm_type)); 843 return; 844 } 845 846 k = kern_add(S_ADDR(INFO_DST(info)), mask); 847 if (k->k_state & KS_NEW) 848 k->k_keep = now.tv_sec+keep; 849 k->k_gate = S_ADDR(INFO_GATE(info)); --- 12 unchanged lines hidden (view full) --- 862 if (supplier) { 863 /* Routers are not supposed to listen to redirects, 864 * so delete it. 865 */ 866 k->k_state &= ~KS_DYNAMIC; 867 k->k_state |= KS_DELETE; 868 LIM_SEC(need_kern, 0); 869 trace_act("mark redirected %s --> %s for deletion" | 842 rtm_type_name(rtm->rtm_type)); 843 return; 844 } 845 846 k = kern_add(S_ADDR(INFO_DST(info)), mask); 847 if (k->k_state & KS_NEW) 848 k->k_keep = now.tv_sec+keep; 849 k->k_gate = S_ADDR(INFO_GATE(info)); --- 12 unchanged lines hidden (view full) --- 862 if (supplier) { 863 /* Routers are not supposed to listen to redirects, 864 * so delete it. 865 */ 866 k->k_state &= ~KS_DYNAMIC; 867 k->k_state |= KS_DELETE; 868 LIM_SEC(need_kern, 0); 869 trace_act("mark redirected %s --> %s for deletion" |
870 " since this is a router\n", | 870 " since this is a router", |
871 addrname(k->k_dst, k->k_mask, 0), 872 naddr_ntoa(k->k_gate)); 873 } else { 874 k->k_state |= KS_DYNAMIC; 875 k->k_redirect_time = now.tv_sec; 876 } 877 return; 878 } --- 5 unchanged lines hidden (view full) --- 884 k->k_state |= KS_DELETE; 885 LIM_SEC(need_kern, k->k_keep); 886 return; 887 } 888 889 /* Put static routes with real metrics into the daemon table so 890 * they can be advertised. 891 * | 871 addrname(k->k_dst, k->k_mask, 0), 872 naddr_ntoa(k->k_gate)); 873 } else { 874 k->k_state |= KS_DYNAMIC; 875 k->k_redirect_time = now.tv_sec; 876 } 877 return; 878 } --- 5 unchanged lines hidden (view full) --- 884 k->k_state |= KS_DELETE; 885 LIM_SEC(need_kern, k->k_keep); 886 return; 887 } 888 889 /* Put static routes with real metrics into the daemon table so 890 * they can be advertised. 891 * |
892 * Find the interface concerned | 892 * Find the interface toward the gateway. |
893 */ 894 ifp = iflookup(k->k_gate); 895 if (ifp == 0) { 896 /* if there is no known interface, 897 * maybe there is a new interface 898 */ 899 ifinit(); 900 ifp = iflookup(k->k_gate); --- 10 unchanged lines hidden (view full) --- 911/* deal with packet loss 912 */ 913static void 914rtm_lose(struct rt_msghdr *rtm, 915 struct rt_addrinfo *info) 916{ 917 if (INFO_GATE(info) == 0 918 || INFO_GATE(info)->sa_family != AF_INET) { | 893 */ 894 ifp = iflookup(k->k_gate); 895 if (ifp == 0) { 896 /* if there is no known interface, 897 * maybe there is a new interface 898 */ 899 ifinit(); 900 ifp = iflookup(k->k_gate); --- 10 unchanged lines hidden (view full) --- 911/* deal with packet loss 912 */ 913static void 914rtm_lose(struct rt_msghdr *rtm, 915 struct rt_addrinfo *info) 916{ 917 if (INFO_GATE(info) == 0 918 || INFO_GATE(info)->sa_family != AF_INET) { |
919 msglog("punt %s without gateway", | 919 msglog("ignore %s without gateway", |
920 rtm_type_name(rtm->rtm_type)); 921 return; 922 } 923 924 if (!supplier) 925 rdisc_age(S_ADDR(INFO_GATE(info))); 926 927 age(S_ADDR(INFO_GATE(info))); --- 132 unchanged lines hidden (view full) --- 1060 } 1061 1062 if (m.r.rtm.rtm_type == RTM_IFINFO 1063 || m.r.rtm.rtm_type == RTM_NEWADDR 1064 || m.r.rtm.rtm_type == RTM_DELADDR) { 1065 ifp = ifwithindex(m.ifm.ifm_index); 1066 if (ifp == 0) 1067 trace_act("note %s with flags %#x" | 920 rtm_type_name(rtm->rtm_type)); 921 return; 922 } 923 924 if (!supplier) 925 rdisc_age(S_ADDR(INFO_GATE(info))); 926 927 age(S_ADDR(INFO_GATE(info))); --- 132 unchanged lines hidden (view full) --- 1060 } 1061 1062 if (m.r.rtm.rtm_type == RTM_IFINFO 1063 || m.r.rtm.rtm_type == RTM_NEWADDR 1064 || m.r.rtm.rtm_type == RTM_DELADDR) { 1065 ifp = ifwithindex(m.ifm.ifm_index); 1066 if (ifp == 0) 1067 trace_act("note %s with flags %#x" |
1068 " for index #%d\n", | 1068 " for index #%d", |
1069 rtm_type_name(m.r.rtm.rtm_type), 1070 m.ifm.ifm_flags, 1071 m.ifm.ifm_index); 1072 else | 1069 rtm_type_name(m.r.rtm.rtm_type), 1070 m.ifm.ifm_flags, 1071 m.ifm.ifm_index); 1072 else |
1073 trace_act("note %s with flags %#x for %s\n", | 1073 trace_act("note %s with flags %#x for %s", |
1074 rtm_type_name(m.r.rtm.rtm_type), 1075 m.ifm.ifm_flags, 1076 ifp->int_name); 1077 1078 /* After being informed of a change to an interface, 1079 * check them all now if the check would otherwise 1080 * be a long time from now, if the interface is 1081 * not known, or if the interface has been turned --- 11 unchanged lines hidden (view full) --- 1093 strp = &str[strlen(str)]; 1094 if (m.r.rtm.rtm_type <= RTM_CHANGE) 1095 strp += sprintf(strp," from pid %d",m.r.rtm.rtm_pid); 1096 1097 rt_xaddrs(&info, m.r.addrs, &m.r.addrs[RTAX_MAX], 1098 m.r.rtm.rtm_addrs); 1099 1100 if (INFO_DST(&info) == 0) { | 1074 rtm_type_name(m.r.rtm.rtm_type), 1075 m.ifm.ifm_flags, 1076 ifp->int_name); 1077 1078 /* After being informed of a change to an interface, 1079 * check them all now if the check would otherwise 1080 * be a long time from now, if the interface is 1081 * not known, or if the interface has been turned --- 11 unchanged lines hidden (view full) --- 1093 strp = &str[strlen(str)]; 1094 if (m.r.rtm.rtm_type <= RTM_CHANGE) 1095 strp += sprintf(strp," from pid %d",m.r.rtm.rtm_pid); 1096 1097 rt_xaddrs(&info, m.r.addrs, &m.r.addrs[RTAX_MAX], 1098 m.r.rtm.rtm_addrs); 1099 1100 if (INFO_DST(&info) == 0) { |
1101 trace_act("ignore %s without dst\n", str); | 1101 trace_act("ignore %s without dst", str); |
1102 continue; 1103 } 1104 1105 if (INFO_DST(&info)->sa_family != AF_INET) { | 1102 continue; 1103 } 1104 1105 if (INFO_DST(&info)->sa_family != AF_INET) { |
1106 trace_act("ignore %s for AF %d\n", str, | 1106 trace_act("ignore %s for AF %d", str, |
1107 INFO_DST(&info)->sa_family); 1108 continue; 1109 } 1110 1111 mask = ((INFO_MASK(&info) != 0) 1112 ? ntohl(S_ADDR(INFO_MASK(&info))) 1113 : (m.r.rtm.rtm_flags & RTF_HOST) 1114 ? HOST_MASK 1115 : std_mask(S_ADDR(INFO_DST(&info)))); 1116 1117 strp += sprintf(strp, ": %s", 1118 addrname(S_ADDR(INFO_DST(&info)), mask, 0)); 1119 1120 if (IN_MULTICAST(ntohl(S_ADDR(INFO_DST(&info))))) { | 1107 INFO_DST(&info)->sa_family); 1108 continue; 1109 } 1110 1111 mask = ((INFO_MASK(&info) != 0) 1112 ? ntohl(S_ADDR(INFO_MASK(&info))) 1113 : (m.r.rtm.rtm_flags & RTF_HOST) 1114 ? HOST_MASK 1115 : std_mask(S_ADDR(INFO_DST(&info)))); 1116 1117 strp += sprintf(strp, ": %s", 1118 addrname(S_ADDR(INFO_DST(&info)), mask, 0)); 1119 1120 if (IN_MULTICAST(ntohl(S_ADDR(INFO_DST(&info))))) { |
1121 trace_act("ignore multicast %s\n", str); | 1121 trace_act("ignore multicast %s", str); |
1122 continue; 1123 } 1124 1125 if (INFO_GATE(&info) != 0 1126 && INFO_GATE(&info)->sa_family == AF_INET) 1127 strp += sprintf(strp, " --> %s", 1128 saddr_ntoa(INFO_GATE(&info))); 1129 1130 if (INFO_AUTHOR(&info) != 0) 1131 strp += sprintf(strp, " by authority of %s", 1132 saddr_ntoa(INFO_AUTHOR(&info))); 1133 1134 switch (m.r.rtm.rtm_type) { 1135 case RTM_ADD: 1136 case RTM_CHANGE: 1137 case RTM_REDIRECT: 1138 if (m.r.rtm.rtm_errno != 0) { | 1122 continue; 1123 } 1124 1125 if (INFO_GATE(&info) != 0 1126 && INFO_GATE(&info)->sa_family == AF_INET) 1127 strp += sprintf(strp, " --> %s", 1128 saddr_ntoa(INFO_GATE(&info))); 1129 1130 if (INFO_AUTHOR(&info) != 0) 1131 strp += sprintf(strp, " by authority of %s", 1132 saddr_ntoa(INFO_AUTHOR(&info))); 1133 1134 switch (m.r.rtm.rtm_type) { 1135 case RTM_ADD: 1136 case RTM_CHANGE: 1137 case RTM_REDIRECT: 1138 if (m.r.rtm.rtm_errno != 0) { |
1139 trace_act("ignore %s with \"%s\" error\n", | 1139 trace_act("ignore %s with \"%s\" error", |
1140 str, strerror(m.r.rtm.rtm_errno)); 1141 } else { | 1140 str, strerror(m.r.rtm.rtm_errno)); 1141 } else { |
1142 trace_act("%s\n", str); | 1142 trace_act("%s", str); |
1143 rtm_add(&m.r.rtm,&info,0); 1144 } 1145 break; 1146 1147 case RTM_DELETE: 1148 if (m.r.rtm.rtm_errno != 0) { | 1143 rtm_add(&m.r.rtm,&info,0); 1144 } 1145 break; 1146 1147 case RTM_DELETE: 1148 if (m.r.rtm.rtm_errno != 0) { |
1149 trace_act("ignore %s with \"%s\" error\n", | 1149 trace_act("ignore %s with \"%s\" error", |
1150 str, strerror(m.r.rtm.rtm_errno)); 1151 } else { | 1150 str, strerror(m.r.rtm.rtm_errno)); 1151 } else { |
1152 trace_act("%s\n", str); | 1152 trace_act("%s", str); |
1153 del_static(S_ADDR(INFO_DST(&info)), mask, 1); 1154 } 1155 break; 1156 1157 case RTM_LOSING: | 1153 del_static(S_ADDR(INFO_DST(&info)), mask, 1); 1154 } 1155 break; 1156 1157 case RTM_LOSING: |
1158 trace_act("%s\n", str); | 1158 trace_act("%s", str); |
1159 rtm_lose(&m.r.rtm,&info); 1160 break; 1161 1162 default: | 1159 rtm_lose(&m.r.rtm,&info); 1160 break; 1161 1162 default: |
1163 trace_act("ignore %s\n", str); | 1163 trace_act("ignore %s", str); |
1164 break; 1165 } 1166 } 1167} 1168 1169 1170/* after aggregating, note routes that belong in the kernel 1171 */ --- 91 unchanged lines hidden (view full) --- 1263 1264 /* If it is not an interface, or an alias for an interface, 1265 * it must be a "gateway." 1266 * 1267 * If it is a "remote" interface, it is also a "gateway" to 1268 * the kernel if is not a alias. 1269 */ 1270 if (RT->rt_ifp == 0 | 1164 break; 1165 } 1166 } 1167} 1168 1169 1170/* after aggregating, note routes that belong in the kernel 1171 */ --- 91 unchanged lines hidden (view full) --- 1263 1264 /* If it is not an interface, or an alias for an interface, 1265 * it must be a "gateway." 1266 * 1267 * If it is a "remote" interface, it is also a "gateway" to 1268 * the kernel if is not a alias. 1269 */ 1270 if (RT->rt_ifp == 0 |
1271 || ((RT->rt_ifp->int_state & IS_REMOTE) 1272 && RT->rt_ifp->int_metric == 0)) | 1271 || (RT->rt_ifp->int_state & IS_REMOTE)) |
1273 ags |= (AGS_GATEWAY | AGS_SUPPRESS | AGS_PROMOTE); 1274 } 1275 1276 if (RT->rt_state & RS_RDISC) 1277 ags |= AGS_CORS_GATE; 1278 1279 /* aggregate good routes without regard to their metric */ 1280 pref = 1; --- 145 unchanged lines hidden (view full) --- 1426 if (k->k_gate != bad_gate 1427 && k->k_redirect_time > old 1428 && !supplier) 1429 continue; 1430 1431 k->k_state |= KS_DELETE; 1432 k->k_state &= ~KS_DYNAMIC; 1433 need_kern.tv_sec = now.tv_sec; | 1272 ags |= (AGS_GATEWAY | AGS_SUPPRESS | AGS_PROMOTE); 1273 } 1274 1275 if (RT->rt_state & RS_RDISC) 1276 ags |= AGS_CORS_GATE; 1277 1278 /* aggregate good routes without regard to their metric */ 1279 pref = 1; --- 145 unchanged lines hidden (view full) --- 1425 if (k->k_gate != bad_gate 1426 && k->k_redirect_time > old 1427 && !supplier) 1428 continue; 1429 1430 k->k_state |= KS_DELETE; 1431 k->k_state &= ~KS_DYNAMIC; 1432 need_kern.tv_sec = now.tv_sec; |
1434 trace_act("mark redirected %s --> %s for deletion\n", | 1433 trace_act("mark redirected %s --> %s for deletion", |
1435 addrname(k->k_dst, k->k_mask, 0), 1436 naddr_ntoa(k->k_gate)); 1437 } 1438 } 1439} 1440 1441 1442/* Start the daemon tables. --- 494 unchanged lines hidden (view full) --- 1937 1938 1939/* Watch for dead routes and interfaces. 1940 */ 1941void 1942age(naddr bad_gate) 1943{ 1944 struct interface *ifp; | 1434 addrname(k->k_dst, k->k_mask, 0), 1435 naddr_ntoa(k->k_gate)); 1436 } 1437 } 1438} 1439 1440 1441/* Start the daemon tables. --- 494 unchanged lines hidden (view full) --- 1936 1937 1938/* Watch for dead routes and interfaces. 1939 */ 1940void 1941age(naddr bad_gate) 1942{ 1943 struct interface *ifp; |
1944 int need_query = 0; |
|
1945 | 1945 |
1946 /* If not listening to RIP, there is no need to age the routes in 1947 * the table. 1948 */ 1949 age_timer.tv_sec = (now.tv_sec 1950 + ((rip_sock < 0) ? NEVER : SUPPLY_INTERVAL)); |
|
1946 | 1951 |
1947 age_timer.tv_sec = now.tv_sec + (rip_sock < 0 1948 ? NEVER 1949 : SUPPLY_INTERVAL); 1950 | 1952 /* Check for dead IS_REMOTE interfaces by timing their 1953 * transmissions. 1954 */ |
1951 for (ifp = ifnet; ifp; ifp = ifp->int_next) { | 1955 for (ifp = ifnet; ifp; ifp = ifp->int_next) { |
1952 /* Check for dead IS_REMOTE interfaces by timing their 1953 * transmissions. | 1956 if (!(ifp->int_state & IS_REMOTE)) 1957 continue; 1958 1959 /* ignore unreachable remote interfaces */ 1960 if (!check_remote(ifp)) 1961 continue; 1962 /* Restore remote interface that has become reachable |
1954 */ | 1963 */ |
1955 if ((ifp->int_state & IS_REMOTE) 1956 && !(ifp->int_state & IS_PASSIVE) 1957 && (ifp->int_state & IS_ACTIVE)) { 1958 LIM_SEC(age_timer, now.tv_sec+SUPPLY_INTERVAL); | 1964 if (ifp->int_state & IS_BROKE) 1965 if_ok(ifp, "remote "); |
1959 | 1966 |
1960 if (now.tv_sec - ifp->int_act_time > EXPIRE_TIME 1961 && !(ifp->int_state & IS_BROKE)) { 1962 msglog("remote interface %s to %s timed out" 1963 "--turned off", 1964 ifp->int_name, 1965 naddr_ntoa(ifp->int_addr)); 1966 if_bad(ifp); 1967 } | 1967 if (ifp->int_act_time != NEVER 1968 && now.tv_sec - ifp->int_act_time > EXPIRE_TIME) { 1969 msglog("remote interface %s to %s timed out after" 1970 " %d:%d", 1971 ifp->int_name, 1972 naddr_ntoa(ifp->int_dstaddr), 1973 (now.tv_sec - ifp->int_act_time)/60, 1974 (now.tv_sec - ifp->int_act_time)%60); 1975 if_sick(ifp); |
1968 } | 1976 } |
1977 1978 /* If we have not heard from the other router 1979 * recently, ask it. 1980 */ 1981 if (now.tv_sec >= ifp->int_query_time) { 1982 ifp->int_query_time = NEVER; 1983 need_query = 1; 1984 } |
|
1969 } 1970 1971 /* Age routes. */ 1972 age_bad_gate = bad_gate; 1973 (void)rn_walktree(rhead, walk_age, 0); 1974 1975 /* Update the kernel routing table. */ 1976 fix_kern(); | 1985 } 1986 1987 /* Age routes. */ 1988 age_bad_gate = bad_gate; 1989 (void)rn_walktree(rhead, walk_age, 0); 1990 1991 /* Update the kernel routing table. */ 1992 fix_kern(); |
1993 1994 /* poke reticent remote gateways */ 1995 if (need_query) 1996 rip_query(); |
|
1977} | 1997} |