Deleted Added
full compact
in6.c (164033) in6.c (165118)
1/* $FreeBSD: head/sys/netinet6/in6.c 164033 2006-11-06 13:42:10Z rwatson $ */
1/* $FreeBSD: head/sys/netinet6/in6.c 165118 2006-12-12 12:17:58Z bz $ */
2/* $KAME: in6.c,v 1.259 2002/01/21 11:37:50 keiichi Exp $ */
3
4/*-
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions

--- 125 unchanged lines hidden (view full) ---

135 * This routine does actual work.
136 */
137static void
138in6_ifloop_request(int cmd, struct ifaddr *ifa)
139{
140 struct sockaddr_in6 all1_sa;
141 struct rtentry *nrt = NULL;
142 int e;
2/* $KAME: in6.c,v 1.259 2002/01/21 11:37:50 keiichi Exp $ */
3
4/*-
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions

--- 125 unchanged lines hidden (view full) ---

135 * This routine does actual work.
136 */
137static void
138in6_ifloop_request(int cmd, struct ifaddr *ifa)
139{
140 struct sockaddr_in6 all1_sa;
141 struct rtentry *nrt = NULL;
142 int e;
143 char ip6buf[INET6_ADDRSTRLEN];
143
144 bzero(&all1_sa, sizeof(all1_sa));
145 all1_sa.sin6_family = AF_INET6;
146 all1_sa.sin6_len = sizeof(struct sockaddr_in6);
147 all1_sa.sin6_addr = in6mask128;
148
149 /*
150 * We specify the address itself as the gateway, and set the
151 * RTF_LLINFO flag, so that the corresponding host route would have
152 * the flag, and thus applications that assume traditional behavior
153 * would be happy. Note that we assume the caller of the function
154 * (probably implicitly) set nd6_rtrequest() to ifa->ifa_rtrequest,
155 * which changes the outgoing interface to the loopback interface.
156 */
157 e = rtrequest(cmd, ifa->ifa_addr, ifa->ifa_addr,
158 (struct sockaddr *)&all1_sa, RTF_UP|RTF_HOST|RTF_LLINFO, &nrt);
159 if (e != 0) {
160 /* XXX need more descriptive message */
144
145 bzero(&all1_sa, sizeof(all1_sa));
146 all1_sa.sin6_family = AF_INET6;
147 all1_sa.sin6_len = sizeof(struct sockaddr_in6);
148 all1_sa.sin6_addr = in6mask128;
149
150 /*
151 * We specify the address itself as the gateway, and set the
152 * RTF_LLINFO flag, so that the corresponding host route would have
153 * the flag, and thus applications that assume traditional behavior
154 * would be happy. Note that we assume the caller of the function
155 * (probably implicitly) set nd6_rtrequest() to ifa->ifa_rtrequest,
156 * which changes the outgoing interface to the loopback interface.
157 */
158 e = rtrequest(cmd, ifa->ifa_addr, ifa->ifa_addr,
159 (struct sockaddr *)&all1_sa, RTF_UP|RTF_HOST|RTF_LLINFO, &nrt);
160 if (e != 0) {
161 /* XXX need more descriptive message */
162
161 log(LOG_ERR, "in6_ifloop_request: "
162 "%s operation failed for %s (errno=%d)\n",
163 cmd == RTM_ADD ? "ADD" : "DELETE",
163 log(LOG_ERR, "in6_ifloop_request: "
164 "%s operation failed for %s (errno=%d)\n",
165 cmd == RTM_ADD ? "ADD" : "DELETE",
164 ip6_sprintf(&((struct in6_ifaddr *)ifa)->ia_addr.sin6_addr),
165 e);
166 ip6_sprintf(ip6buf,
167 &((struct in6_ifaddr *)ifa)->ia_addr.sin6_addr), e);
166 }
167
168 /*
169 * Report the addition/removal of the address to the routing socket.
170 * XXX: since we called rtinit for a p2p interface with a destination,
171 * we end up reporting twice in such a case. Should we rather
172 * omit the second report?
173 */

--- 628 unchanged lines hidden (view full) ---

802 int error = 0, hostIsNew = 0, plen = -1;
803 struct in6_ifaddr *oia;
804 struct sockaddr_in6 dst6;
805 struct in6_addrlifetime *lt;
806 struct in6_multi_mship *imm;
807 struct in6_multi *in6m_sol;
808 struct rtentry *rt;
809 int delay;
168 }
169
170 /*
171 * Report the addition/removal of the address to the routing socket.
172 * XXX: since we called rtinit for a p2p interface with a destination,
173 * we end up reporting twice in such a case. Should we rather
174 * omit the second report?
175 */

--- 628 unchanged lines hidden (view full) ---

804 int error = 0, hostIsNew = 0, plen = -1;
805 struct in6_ifaddr *oia;
806 struct sockaddr_in6 dst6;
807 struct in6_addrlifetime *lt;
808 struct in6_multi_mship *imm;
809 struct in6_multi *in6m_sol;
810 struct rtentry *rt;
811 int delay;
812 char ip6buf[INET6_ADDRSTRLEN];
810
811 /* Validate parameters */
812 if (ifp == NULL || ifra == NULL) /* this maybe redundant */
813 return (EINVAL);
814
815 /*
816 * The destination address for a p2p link must have a family
817 * of AF_UNSPEC or AF_INET6.

--- 78 unchanged lines hidden (view full) ---

896 return (EINVAL);
897 if (lt->ia6t_vltime == 0) {
898 /*
899 * the following log might be noisy, but this is a typical
900 * configuration mistake or a tool's bug.
901 */
902 nd6log((LOG_INFO,
903 "in6_update_ifa: valid lifetime is 0 for %s\n",
813
814 /* Validate parameters */
815 if (ifp == NULL || ifra == NULL) /* this maybe redundant */
816 return (EINVAL);
817
818 /*
819 * The destination address for a p2p link must have a family
820 * of AF_UNSPEC or AF_INET6.

--- 78 unchanged lines hidden (view full) ---

899 return (EINVAL);
900 if (lt->ia6t_vltime == 0) {
901 /*
902 * the following log might be noisy, but this is a typical
903 * configuration mistake or a tool's bug.
904 */
905 nd6log((LOG_INFO,
906 "in6_update_ifa: valid lifetime is 0 for %s\n",
904 ip6_sprintf(&ifra->ifra_addr.sin6_addr)));
907 ip6_sprintf(ip6buf, &ifra->ifra_addr.sin6_addr)));
905
906 if (ia == NULL)
907 return (0); /* there's nothing to do */
908 }
909
910 /*
911 * If this is a new address, allocate a new ifaddr and link it
912 * into chains.

--- 50 unchanged lines hidden (view full) ---

963 * address, because
964 * + such an operation should be rare in IPv6, and
965 * + the operation would confuse prefix management.
966 */
967 if (ia->ia_prefixmask.sin6_len &&
968 in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL) != plen) {
969 nd6log((LOG_INFO, "in6_update_ifa: the prefix length of an"
970 " existing (%s) address should not be changed\n",
908
909 if (ia == NULL)
910 return (0); /* there's nothing to do */
911 }
912
913 /*
914 * If this is a new address, allocate a new ifaddr and link it
915 * into chains.

--- 50 unchanged lines hidden (view full) ---

966 * address, because
967 * + such an operation should be rare in IPv6, and
968 * + the operation would confuse prefix management.
969 */
970 if (ia->ia_prefixmask.sin6_len &&
971 in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL) != plen) {
972 nd6log((LOG_INFO, "in6_update_ifa: the prefix length of an"
973 " existing (%s) address should not be changed\n",
971 ip6_sprintf(&ia->ia_addr.sin6_addr)));
974 ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr)));
972 error = EINVAL;
973 goto unlink;
974 }
975 ia->ia_prefixmask = ifra->ifra_prefixmask;
976 }
977
978 /*
979 * If a new destination address is specified, scrub the old one and
980 * install the new destination. Note that the interface must be
981 * p2p or loopback (see the check above.)
982 */
983 if (dst6.sin6_family == AF_INET6 &&
984 !IN6_ARE_ADDR_EQUAL(&dst6.sin6_addr, &ia->ia_dstaddr.sin6_addr)) {
985 int e;
986
987 if ((ia->ia_flags & IFA_ROUTE) != 0 &&
988 (e = rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST)) != 0) {
989 nd6log((LOG_ERR, "in6_update_ifa: failed to remove "
990 "a route to the old destination: %s\n",
975 error = EINVAL;
976 goto unlink;
977 }
978 ia->ia_prefixmask = ifra->ifra_prefixmask;
979 }
980
981 /*
982 * If a new destination address is specified, scrub the old one and
983 * install the new destination. Note that the interface must be
984 * p2p or loopback (see the check above.)
985 */
986 if (dst6.sin6_family == AF_INET6 &&
987 !IN6_ARE_ADDR_EQUAL(&dst6.sin6_addr, &ia->ia_dstaddr.sin6_addr)) {
988 int e;
989
990 if ((ia->ia_flags & IFA_ROUTE) != 0 &&
991 (e = rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST)) != 0) {
992 nd6log((LOG_ERR, "in6_update_ifa: failed to remove "
993 "a route to the old destination: %s\n",
991 ip6_sprintf(&ia->ia_addr.sin6_addr)));
994 ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr)));
992 /* proceed anyway... */
993 } else
994 ia->ia_flags &= ~IFA_ROUTE;
995 ia->ia_dstaddr = dst6;
996 }
997
998 /*
999 * Set lifetimes. We do not refer to ia6t_expire and ia6t_preferred

--- 79 unchanged lines hidden (view full) ---

1079 delay = arc4random() %
1080 (MAX_RTR_SOLICITATION_DELAY * hz);
1081 }
1082 imm = in6_joingroup(ifp, &llsol, &error, delay);
1083 if (error != 0) {
1084 nd6log((LOG_WARNING,
1085 "in6_update_ifa: addmulti failed for "
1086 "%s on %s (errno=%d)\n",
995 /* proceed anyway... */
996 } else
997 ia->ia_flags &= ~IFA_ROUTE;
998 ia->ia_dstaddr = dst6;
999 }
1000
1001 /*
1002 * Set lifetimes. We do not refer to ia6t_expire and ia6t_preferred

--- 79 unchanged lines hidden (view full) ---

1082 delay = arc4random() %
1083 (MAX_RTR_SOLICITATION_DELAY * hz);
1084 }
1085 imm = in6_joingroup(ifp, &llsol, &error, delay);
1086 if (error != 0) {
1087 nd6log((LOG_WARNING,
1088 "in6_update_ifa: addmulti failed for "
1089 "%s on %s (errno=%d)\n",
1087 ip6_sprintf(&llsol), if_name(ifp),
1090 ip6_sprintf(ip6buf, &llsol), if_name(ifp),
1088 error));
1089 in6_purgeaddr((struct ifaddr *)ia);
1090 return (error);
1091 }
1092 in6m_sol = imm->i6mm_maddr;
1093
1094 bzero(&mltmask, sizeof(mltmask));
1095 mltmask.sin6_len = sizeof(struct sockaddr_in6);

--- 65 unchanged lines hidden (view full) ---

1161 RTFREE_LOCKED(rt);
1162 }
1163
1164 imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error, 0);
1165 if (!imm) {
1166 nd6log((LOG_WARNING,
1167 "in6_update_ifa: addmulti failed for "
1168 "%s on %s (errno=%d)\n",
1091 error));
1092 in6_purgeaddr((struct ifaddr *)ia);
1093 return (error);
1094 }
1095 in6m_sol = imm->i6mm_maddr;
1096
1097 bzero(&mltmask, sizeof(mltmask));
1098 mltmask.sin6_len = sizeof(struct sockaddr_in6);

--- 65 unchanged lines hidden (view full) ---

1164 RTFREE_LOCKED(rt);
1165 }
1166
1167 imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error, 0);
1168 if (!imm) {
1169 nd6log((LOG_WARNING,
1170 "in6_update_ifa: addmulti failed for "
1171 "%s on %s (errno=%d)\n",
1169 ip6_sprintf(&mltaddr.sin6_addr),
1172 ip6_sprintf(ip6buf, &mltaddr.sin6_addr),
1170 if_name(ifp), error));
1171 goto cleanup;
1172 }
1173
1174 /*
1175 * join node information group address
1176 */
1177#define hostnamelen strlen(hostname)

--- 9 unchanged lines hidden (view full) ---

1187 if (in6_nigroup(ifp, hostname, hostnamelen, &mltaddr.sin6_addr)
1188 == 0) {
1189 imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error,
1190 delay); /* XXX jinmei */
1191 if (!imm) {
1192 nd6log((LOG_WARNING, "in6_update_ifa: "
1193 "addmulti failed for %s on %s "
1194 "(errno=%d)\n",
1173 if_name(ifp), error));
1174 goto cleanup;
1175 }
1176
1177 /*
1178 * join node information group address
1179 */
1180#define hostnamelen strlen(hostname)

--- 9 unchanged lines hidden (view full) ---

1190 if (in6_nigroup(ifp, hostname, hostnamelen, &mltaddr.sin6_addr)
1191 == 0) {
1192 imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error,
1193 delay); /* XXX jinmei */
1194 if (!imm) {
1195 nd6log((LOG_WARNING, "in6_update_ifa: "
1196 "addmulti failed for %s on %s "
1197 "(errno=%d)\n",
1195 ip6_sprintf(&mltaddr.sin6_addr),
1198 ip6_sprintf(ip6buf, &mltaddr.sin6_addr),
1196 if_name(ifp), error));
1197 /* XXX not very fatal, go on... */
1198 }
1199 }
1200#undef hostnamelen
1201
1202 /*
1203 * join interface-local all-nodes address.

--- 44 unchanged lines hidden (view full) ---

1248 RTFREE_LOCKED(rt);
1249 }
1250
1251 imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error, 0);
1252 if (!imm) {
1253 nd6log((LOG_WARNING, "in6_update_ifa: "
1254 "addmulti failed for %s on %s "
1255 "(errno=%d)\n",
1199 if_name(ifp), error));
1200 /* XXX not very fatal, go on... */
1201 }
1202 }
1203#undef hostnamelen
1204
1205 /*
1206 * join interface-local all-nodes address.

--- 44 unchanged lines hidden (view full) ---

1251 RTFREE_LOCKED(rt);
1252 }
1253
1254 imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error, 0);
1255 if (!imm) {
1256 nd6log((LOG_WARNING, "in6_update_ifa: "
1257 "addmulti failed for %s on %s "
1258 "(errno=%d)\n",
1256 ip6_sprintf(&mltaddr.sin6_addr),
1259 ip6_sprintf(ip6buf, &mltaddr.sin6_addr),
1257 if_name(ifp), error));
1258 goto cleanup;
1259 }
1260#undef MLTMASK_LEN
1261 }
1262
1263 /*
1264 * Perform DAD, if needed.

--- 50 unchanged lines hidden (view full) ---

1315}
1316
1317void
1318in6_purgeaddr(ifa)
1319 struct ifaddr *ifa;
1320{
1321 struct ifnet *ifp = ifa->ifa_ifp;
1322 struct in6_ifaddr *ia = (struct in6_ifaddr *) ifa;
1260 if_name(ifp), error));
1261 goto cleanup;
1262 }
1263#undef MLTMASK_LEN
1264 }
1265
1266 /*
1267 * Perform DAD, if needed.

--- 50 unchanged lines hidden (view full) ---

1318}
1319
1320void
1321in6_purgeaddr(ifa)
1322 struct ifaddr *ifa;
1323{
1324 struct ifnet *ifp = ifa->ifa_ifp;
1325 struct in6_ifaddr *ia = (struct in6_ifaddr *) ifa;
1326 char ip6buf[INET6_ADDRSTRLEN];
1323
1324 /* stop DAD processing */
1325 nd6_dad_stop(ifa);
1326
1327 /*
1328 * delete route to the destination of the address being purged.
1329 * The interface must be p2p or loopback in this case.
1330 */
1331 if ((ia->ia_flags & IFA_ROUTE) != 0 && ia->ia_dstaddr.sin6_len != 0) {
1332 int e;
1333
1334 if ((e = rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST))
1335 != 0) {
1336 log(LOG_ERR, "in6_purgeaddr: failed to remove "
1337 "a route to the p2p destination: %s on %s, "
1338 "errno=%d\n",
1327
1328 /* stop DAD processing */
1329 nd6_dad_stop(ifa);
1330
1331 /*
1332 * delete route to the destination of the address being purged.
1333 * The interface must be p2p or loopback in this case.
1334 */
1335 if ((ia->ia_flags & IFA_ROUTE) != 0 && ia->ia_dstaddr.sin6_len != 0) {
1336 int e;
1337
1338 if ((e = rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST))
1339 != 0) {
1340 log(LOG_ERR, "in6_purgeaddr: failed to remove "
1341 "a route to the p2p destination: %s on %s, "
1342 "errno=%d\n",
1339 ip6_sprintf(&ia->ia_addr.sin6_addr), if_name(ifp),
1340 e);
1343 ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr),
1344 if_name(ifp), e);
1341 /* proceed anyway... */
1342 } else
1343 ia->ia_flags &= ~IFA_ROUTE;
1344 }
1345
1346 /* Remove ownaddr's loopback rtentry, if it exists. */
1347 in6_ifremloop(&(ia->ia_ifa));
1348

--- 535 unchanged lines hidden (view full) ---

1884 if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa)))
1885 break;
1886 }
1887
1888 return ((struct in6_ifaddr *)ifa);
1889}
1890
1891/*
1345 /* proceed anyway... */
1346 } else
1347 ia->ia_flags &= ~IFA_ROUTE;
1348 }
1349
1350 /* Remove ownaddr's loopback rtentry, if it exists. */
1351 in6_ifremloop(&(ia->ia_ifa));
1352

--- 535 unchanged lines hidden (view full) ---

1888 if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa)))
1889 break;
1890 }
1891
1892 return ((struct in6_ifaddr *)ifa);
1893}
1894
1895/*
1892 * Convert IP6 address to printable (loggable) representation.
1896 * Convert IP6 address to printable (loggable) representation. Caller
1897 * has to make sure that ip6buf is at least INET6_ADDRSTRLEN long.
1893 */
1894static char digits[] = "0123456789abcdef";
1898 */
1899static char digits[] = "0123456789abcdef";
1895static int ip6round = 0;
1896char *
1900char *
1897ip6_sprintf(addr)
1898 const struct in6_addr *addr;
1901ip6_sprintf(char *ip6buf, const struct in6_addr *addr)
1899{
1902{
1900 static char ip6buf[8][48];
1901 int i;
1902 char *cp;
1903 const u_int16_t *a = (const u_int16_t *)addr;
1904 const u_int8_t *d;
1905 int dcolon = 0;
1906
1903 int i;
1904 char *cp;
1905 const u_int16_t *a = (const u_int16_t *)addr;
1906 const u_int8_t *d;
1907 int dcolon = 0;
1908
1907 ip6round = (ip6round + 1) & 7;
1908 cp = ip6buf[ip6round];
1909 cp = ip6buf;
1909
1910 for (i = 0; i < 8; i++) {
1911 if (dcolon == 1) {
1912 if (*a == 0) {
1913 if (i == 7)
1914 *cp++ = ':';
1915 a++;
1916 continue;

--- 16 unchanged lines hidden (view full) ---

1933 d = (const u_char *)a;
1934 *cp++ = digits[*d >> 4];
1935 *cp++ = digits[*d++ & 0xf];
1936 *cp++ = digits[*d >> 4];
1937 *cp++ = digits[*d & 0xf];
1938 *cp++ = ':';
1939 a++;
1940 }
1910
1911 for (i = 0; i < 8; i++) {
1912 if (dcolon == 1) {
1913 if (*a == 0) {
1914 if (i == 7)
1915 *cp++ = ':';
1916 a++;
1917 continue;

--- 16 unchanged lines hidden (view full) ---

1934 d = (const u_char *)a;
1935 *cp++ = digits[*d >> 4];
1936 *cp++ = digits[*d++ & 0xf];
1937 *cp++ = digits[*d >> 4];
1938 *cp++ = digits[*d & 0xf];
1939 *cp++ = ':';
1940 a++;
1941 }
1941 *--cp = 0;
1942 return (ip6buf[ip6round]);
1942 *--cp = '\0';
1943 return (ip6buf);
1943}
1944
1945int
1946in6_localaddr(in6)
1947 struct in6_addr *in6;
1948{
1949 struct in6_ifaddr *ia;
1950

--- 438 unchanged lines hidden ---
1944}
1945
1946int
1947in6_localaddr(in6)
1948 struct in6_addr *in6;
1949{
1950 struct in6_ifaddr *ia;
1951

--- 438 unchanged lines hidden ---