Deleted Added
sdiff udiff text old ( 164033 ) new ( 165118 )
full compact
1/* $FreeBSD: head/sys/netinet6/in6.c 164033 2006-11-06 13:42:10Z rwatson $ */
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
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 */
161 log(LOG_ERR, "in6_ifloop_request: "
162 "%s operation failed for %s (errno=%d)\n",
163 cmd == RTM_ADD ? "ADD" : "DELETE",
164 ip6_sprintf(&((struct in6_ifaddr *)ifa)->ia_addr.sin6_addr),
165 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;
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",
904 ip6_sprintf(&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",
971 ip6_sprintf(&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",
991 ip6_sprintf(&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",
1087 ip6_sprintf(&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",
1169 ip6_sprintf(&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",
1195 ip6_sprintf(&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",
1256 ip6_sprintf(&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;
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",
1339 ip6_sprintf(&ia->ia_addr.sin6_addr), if_name(ifp),
1340 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/*
1892 * Convert IP6 address to printable (loggable) representation.
1893 */
1894static char digits[] = "0123456789abcdef";
1895static int ip6round = 0;
1896char *
1897ip6_sprintf(addr)
1898 const struct in6_addr *addr;
1899{
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
1907 ip6round = (ip6round + 1) & 7;
1908 cp = ip6buf[ip6round];
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 }
1941 *--cp = 0;
1942 return (ip6buf[ip6round]);
1943}
1944
1945int
1946in6_localaddr(in6)
1947 struct in6_addr *in6;
1948{
1949 struct in6_ifaddr *ia;
1950

--- 438 unchanged lines hidden ---