in6.c (99124467fc36229ace556d16d998ca29bd87de66) | in6.c (09a52a5532c1b2c0c21e383f06fea52ccd9080b7) |
---|---|
1/* $FreeBSD$ */ 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 --- 912 unchanged lines hidden (view full) --- 921 * RA, it is called under an interrupt context. So, we should 922 * call malloc with M_NOWAIT. 923 */ 924 ia = (struct in6_ifaddr *) malloc(sizeof(*ia), M_IFADDR, 925 M_NOWAIT); 926 if (ia == NULL) 927 return (ENOBUFS); 928 bzero((caddr_t)ia, sizeof(*ia)); | 1/* $FreeBSD$ */ 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 --- 912 unchanged lines hidden (view full) --- 921 * RA, it is called under an interrupt context. So, we should 922 * call malloc with M_NOWAIT. 923 */ 924 ia = (struct in6_ifaddr *) malloc(sizeof(*ia), M_IFADDR, 925 M_NOWAIT); 926 if (ia == NULL) 927 return (ENOBUFS); 928 bzero((caddr_t)ia, sizeof(*ia)); |
929 LIST_INIT(&ia->ia6_memberships); |
|
929 /* Initialize the address and masks, and put time stamp */ 930 IFA_LOCK_INIT(&ia->ia_ifa); 931 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; 932 ia->ia_addr.sin6_family = AF_INET6; 933 ia->ia_addr.sin6_len = sizeof(ia->ia_addr); 934 ia->ia6_createtime = time_second; 935 if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) != 0) { 936 /* --- 141 unchanged lines hidden (view full) --- 1078 * transmission of the corresponding MLD report to 1079 * avoid report collision. 1080 * [draft-ietf-ipv6-rfc2462bis-02.txt] 1081 */ 1082 delay = arc4random() % 1083 (MAX_RTR_SOLICITATION_DELAY * hz); 1084 } 1085 imm = in6_joingroup(ifp, &llsol, &error, delay); | 930 /* Initialize the address and masks, and put time stamp */ 931 IFA_LOCK_INIT(&ia->ia_ifa); 932 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; 933 ia->ia_addr.sin6_family = AF_INET6; 934 ia->ia_addr.sin6_len = sizeof(ia->ia_addr); 935 ia->ia6_createtime = time_second; 936 if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) != 0) { 937 /* --- 141 unchanged lines hidden (view full) --- 1079 * transmission of the corresponding MLD report to 1080 * avoid report collision. 1081 * [draft-ietf-ipv6-rfc2462bis-02.txt] 1082 */ 1083 delay = arc4random() % 1084 (MAX_RTR_SOLICITATION_DELAY * hz); 1085 } 1086 imm = in6_joingroup(ifp, &llsol, &error, delay); |
1086 if (error != 0) { | 1087 if (imm == NULL) { |
1087 nd6log((LOG_WARNING, 1088 "in6_update_ifa: addmulti failed for " 1089 "%s on %s (errno=%d)\n", 1090 ip6_sprintf(ip6buf, &llsol), if_name(ifp), 1091 error)); 1092 in6_purgeaddr((struct ifaddr *)ia); 1093 return (error); 1094 } | 1088 nd6log((LOG_WARNING, 1089 "in6_update_ifa: addmulti failed for " 1090 "%s on %s (errno=%d)\n", 1091 ip6_sprintf(ip6buf, &llsol), if_name(ifp), 1092 error)); 1093 in6_purgeaddr((struct ifaddr *)ia); 1094 return (error); 1095 } |
1096 LIST_INSERT_HEAD(&ia->ia6_memberships, 1097 imm, i6mm_chain); |
|
1095 in6m_sol = imm->i6mm_maddr; 1096 1097 bzero(&mltmask, sizeof(mltmask)); 1098 mltmask.sin6_len = sizeof(struct sockaddr_in6); 1099 mltmask.sin6_family = AF_INET6; 1100 mltmask.sin6_addr = in6mask32; 1101#define MLTMASK_LEN 4 /* mltmask's masklen (=32bit=4octet) */ 1102 --- 65 unchanged lines hidden (view full) --- 1168 if (!imm) { 1169 nd6log((LOG_WARNING, 1170 "in6_update_ifa: addmulti failed for " 1171 "%s on %s (errno=%d)\n", 1172 ip6_sprintf(ip6buf, &mltaddr.sin6_addr), 1173 if_name(ifp), error)); 1174 goto cleanup; 1175 } | 1098 in6m_sol = imm->i6mm_maddr; 1099 1100 bzero(&mltmask, sizeof(mltmask)); 1101 mltmask.sin6_len = sizeof(struct sockaddr_in6); 1102 mltmask.sin6_family = AF_INET6; 1103 mltmask.sin6_addr = in6mask32; 1104#define MLTMASK_LEN 4 /* mltmask's masklen (=32bit=4octet) */ 1105 --- 65 unchanged lines hidden (view full) --- 1171 if (!imm) { 1172 nd6log((LOG_WARNING, 1173 "in6_update_ifa: addmulti failed for " 1174 "%s on %s (errno=%d)\n", 1175 ip6_sprintf(ip6buf, &mltaddr.sin6_addr), 1176 if_name(ifp), error)); 1177 goto cleanup; 1178 } |
1179 LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain); |
|
1176 1177 /* 1178 * join node information group address 1179 */ 1180#define hostnamelen strlen(hostname) 1181 delay = 0; 1182 if ((flags & IN6_IFAUPDATE_DADDELAY)) { 1183 /* --- 9 unchanged lines hidden (view full) --- 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", 1198 ip6_sprintf(ip6buf, &mltaddr.sin6_addr), 1199 if_name(ifp), error)); 1200 /* XXX not very fatal, go on... */ | 1180 1181 /* 1182 * join node information group address 1183 */ 1184#define hostnamelen strlen(hostname) 1185 delay = 0; 1186 if ((flags & IN6_IFAUPDATE_DADDELAY)) { 1187 /* --- 9 unchanged lines hidden (view full) --- 1197 delay); /* XXX jinmei */ 1198 if (!imm) { 1199 nd6log((LOG_WARNING, "in6_update_ifa: " 1200 "addmulti failed for %s on %s " 1201 "(errno=%d)\n", 1202 ip6_sprintf(ip6buf, &mltaddr.sin6_addr), 1203 if_name(ifp), error)); 1204 /* XXX not very fatal, go on... */ |
1205 } else { 1206 LIST_INSERT_HEAD(&ia->ia6_memberships, 1207 imm, i6mm_chain); |
|
1201 } 1202 } 1203#undef hostnamelen 1204 1205 /* 1206 * join interface-local all-nodes address. 1207 * (ff01::1%ifN, and ff01::%ifN/32) 1208 */ --- 46 unchanged lines hidden (view full) --- 1255 if (!imm) { 1256 nd6log((LOG_WARNING, "in6_update_ifa: " 1257 "addmulti failed for %s on %s " 1258 "(errno=%d)\n", 1259 ip6_sprintf(ip6buf, &mltaddr.sin6_addr), 1260 if_name(ifp), error)); 1261 goto cleanup; 1262 } | 1208 } 1209 } 1210#undef hostnamelen 1211 1212 /* 1213 * join interface-local all-nodes address. 1214 * (ff01::1%ifN, and ff01::%ifN/32) 1215 */ --- 46 unchanged lines hidden (view full) --- 1262 if (!imm) { 1263 nd6log((LOG_WARNING, "in6_update_ifa: " 1264 "addmulti failed for %s on %s " 1265 "(errno=%d)\n", 1266 ip6_sprintf(ip6buf, &mltaddr.sin6_addr), 1267 if_name(ifp), error)); 1268 goto cleanup; 1269 } |
1270 LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain); |
|
1263#undef MLTMASK_LEN 1264 } 1265 1266 /* 1267 * Perform DAD, if needed. 1268 * XXX It may be of use, if we can administratively 1269 * disable DAD. 1270 */ --- 48 unchanged lines hidden (view full) --- 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]; | 1271#undef MLTMASK_LEN 1272 } 1273 1274 /* 1275 * Perform DAD, if needed. 1276 * XXX It may be of use, if we can administratively 1277 * disable DAD. 1278 */ --- 48 unchanged lines hidden (view full) --- 1327 1328void 1329in6_purgeaddr(ifa) 1330 struct ifaddr *ifa; 1331{ 1332 struct ifnet *ifp = ifa->ifa_ifp; 1333 struct in6_ifaddr *ia = (struct in6_ifaddr *) ifa; 1334 char ip6buf[INET6_ADDRSTRLEN]; |
1335 struct in6_multi_mship *imm; |
|
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 */ --- 10 unchanged lines hidden (view full) --- 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 | 1336 1337 /* stop DAD processing */ 1338 nd6_dad_stop(ifa); 1339 1340 /* 1341 * delete route to the destination of the address being purged. 1342 * The interface must be p2p or loopback in this case. 1343 */ --- 10 unchanged lines hidden (view full) --- 1354 /* proceed anyway... */ 1355 } else 1356 ia->ia_flags &= ~IFA_ROUTE; 1357 } 1358 1359 /* Remove ownaddr's loopback rtentry, if it exists. */ 1360 in6_ifremloop(&(ia->ia_ifa)); 1361 |
1353 if (ifp->if_flags & IFF_MULTICAST) { 1354 /* 1355 * delete solicited multicast addr for deleting host id 1356 */ 1357 struct in6_multi *in6m; 1358 struct in6_addr llsol; 1359 bzero(&llsol, sizeof(struct in6_addr)); 1360 llsol.s6_addr32[0] = IPV6_ADDR_INT32_MLL; 1361 llsol.s6_addr32[1] = 0; 1362 llsol.s6_addr32[2] = htonl(1); 1363 llsol.s6_addr32[3] = 1364 ia->ia_addr.sin6_addr.s6_addr32[3]; 1365 llsol.s6_addr8[12] = 0xff; 1366 (void)in6_setscope(&llsol, ifp, NULL); /* XXX proceed anyway */ 1367 1368 IN6_LOOKUP_MULTI(llsol, ifp, in6m); 1369 if (in6m) 1370 in6_delmulti(in6m); | 1362 /* 1363 * leave from multicast groups we have joined for the interface 1364 */ 1365 while ((imm = ia->ia6_memberships.lh_first) != NULL) { 1366 LIST_REMOVE(imm, i6mm_chain); 1367 in6_leavegroup(imm); |
1371 } 1372 1373 in6_unlink_ifa(ia, ifp); 1374} 1375 1376static void 1377in6_unlink_ifa(ia, ifp) 1378 struct in6_ifaddr *ia; --- 1025 unchanged lines hidden --- | 1368 } 1369 1370 in6_unlink_ifa(ia, ifp); 1371} 1372 1373static void 1374in6_unlink_ifa(ia, ifp) 1375 struct in6_ifaddr *ia; --- 1025 unchanged lines hidden --- |