Lines 69-76
__FBSDID("$FreeBSD$");
Link Here
|
69 |
|
69 |
|
70 |
static int rtpref(struct nd_defrouter *); |
70 |
static int rtpref(struct nd_defrouter *); |
71 |
static struct nd_defrouter *defrtrlist_update(struct nd_defrouter *); |
71 |
static struct nd_defrouter *defrtrlist_update(struct nd_defrouter *); |
72 |
static int prelist_update(struct nd_prefixctl *, struct nd_defrouter *, |
|
|
73 |
struct mbuf *, int); |
74 |
static struct in6_ifaddr *in6_ifadd(struct nd_prefixctl *, int); |
72 |
static struct in6_ifaddr *in6_ifadd(struct nd_prefixctl *, int); |
75 |
static struct nd_pfxrouter *pfxrtr_lookup(struct nd_prefix *, |
73 |
static struct nd_pfxrouter *pfxrtr_lookup(struct nd_prefix *, |
76 |
struct nd_defrouter *); |
74 |
struct nd_defrouter *); |
Lines 357-363
nd6_ra_input(struct mbuf *m, int off, int icmp6len
Link Here
|
357 |
pr.ndpr_plen = pi->nd_opt_pi_prefix_len; |
355 |
pr.ndpr_plen = pi->nd_opt_pi_prefix_len; |
358 |
pr.ndpr_vltime = ntohl(pi->nd_opt_pi_valid_time); |
356 |
pr.ndpr_vltime = ntohl(pi->nd_opt_pi_valid_time); |
359 |
pr.ndpr_pltime = ntohl(pi->nd_opt_pi_preferred_time); |
357 |
pr.ndpr_pltime = ntohl(pi->nd_opt_pi_preferred_time); |
360 |
(void)prelist_update(&pr, dr, m, mcast); |
358 |
(void)prelist_update(&pr, dr, m, mcast, NULL, NULL); |
361 |
} |
359 |
} |
362 |
} |
360 |
} |
363 |
|
361 |
|
Lines 951-961
prelist_remove(struct nd_prefix *pr)
Link Here
|
951 |
* dr - may be NULL |
949 |
* dr - may be NULL |
952 |
*/ |
950 |
*/ |
953 |
|
951 |
|
954 |
static int |
952 |
int |
955 |
prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr, |
953 |
prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr, |
956 |
struct mbuf *m, int mcast) |
954 |
struct mbuf *m, int mcast, struct nd_prefix **newp, |
|
|
955 |
struct in6_ifaddr *ia6) |
957 |
{ |
956 |
{ |
958 |
struct in6_ifaddr *ia6 = NULL, *ia6_match = NULL; |
957 |
struct in6_ifaddr *ia6_match = NULL; |
959 |
struct ifaddr *ifa; |
958 |
struct ifaddr *ifa; |
960 |
struct ifnet *ifp = new->ndpr_ifp; |
959 |
struct ifnet *ifp = new->ndpr_ifp; |
961 |
struct nd_prefix *pr; |
960 |
struct nd_prefix *pr; |
Lines 1035-1040
prelist_update(struct nd_prefixctl *new, struct nd
Link Here
|
1035 |
ip6_sprintf(ip6buf, &new->ndpr_prefix.sin6_addr), |
1034 |
ip6_sprintf(ip6buf, &new->ndpr_prefix.sin6_addr), |
1036 |
new->ndpr_plen, if_name(new->ndpr_ifp), |
1035 |
new->ndpr_plen, if_name(new->ndpr_ifp), |
1037 |
error, newpr)); |
1036 |
error, newpr)); |
|
|
1037 |
if (newpr == NULL) |
1038 |
error = EINVAL; |
1038 |
goto end; /* we should just give up in this case. */ |
1039 |
goto end; /* we should just give up in this case. */ |
1039 |
} |
1040 |
} |
1040 |
|
1041 |
|
Lines 1054-1059
prelist_update(struct nd_prefixctl *new, struct nd
Link Here
|
1054 |
pr = newpr; |
1055 |
pr = newpr; |
1055 |
} |
1056 |
} |
1056 |
|
1057 |
|
|
|
1058 |
if (newp != NULL) |
1059 |
*newp = pr; |
1060 |
|
1061 |
/* relate the address to the prefix */ |
1062 |
if (ia6 && ia6->ia6_ndpr == NULL) { |
1063 |
/* note that we should use pr (not new) for reference. */ |
1064 |
ia6->ia6_ndpr = pr; |
1065 |
pr->ndpr_refcnt++; |
1066 |
} |
1067 |
|
1057 |
/* |
1068 |
/* |
1058 |
* Address autoconfiguration based on Section 5.5.3 of RFC 2462. |
1069 |
* Address autoconfiguration based on Section 5.5.3 of RFC 2462. |
1059 |
* Note that pr must be non NULL at this point. |
1070 |
* Note that pr must be non NULL at this point. |
Lines 1074-1287
prelist_update(struct nd_prefixctl *new, struct nd
Link Here
|
1074 |
goto end; |
1085 |
goto end; |
1075 |
} |
1086 |
} |
1076 |
|
1087 |
|
1077 |
/* |
1088 |
/* no address provided, prefix is from RA */ |
1078 |
* 5.5.3 (d). If the prefix advertised is not equal to the prefix of |
1089 |
if (ia6 == NULL) { |
1079 |
* an address configured by stateless autoconfiguration already in the |
|
|
1080 |
* list of addresses associated with the interface, and the Valid |
1081 |
* Lifetime is not 0, form an address. We first check if we have |
1082 |
* a matching prefix. |
1083 |
* Note: we apply a clarification in rfc2462bis-02 here. We only |
1084 |
* consider autoconfigured addresses while RFC2462 simply said |
1085 |
* "address". |
1086 |
*/ |
1087 |
IF_ADDR_RLOCK(ifp); |
1088 |
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { |
1089 |
struct in6_ifaddr *ifa6; |
1090 |
u_int32_t remaininglifetime; |
1091 |
|
1092 |
if (ifa->ifa_addr->sa_family != AF_INET6) |
1093 |
continue; |
1094 |
|
1095 |
ifa6 = (struct in6_ifaddr *)ifa; |
1096 |
|
1097 |
/* |
1090 |
/* |
1098 |
* We only consider autoconfigured addresses as per rfc2462bis. |
1091 |
* 5.5.3 (d). If the prefix advertised is not equal to the prefix of |
|
|
1092 |
* an address configured by stateless autoconfiguration already in the |
1093 |
* list of addresses associated with the interface, and the Valid |
1094 |
* Lifetime is not 0, form an address. We first check if we have |
1095 |
* a matching prefix. |
1096 |
* Note: we apply a clarification in rfc2462bis-02 here. We only |
1097 |
* consider autoconfigured addresses while RFC2462 simply said |
1098 |
* "address". |
1099 |
*/ |
1099 |
*/ |
1100 |
if (!(ifa6->ia6_flags & IN6_IFF_AUTOCONF)) |
1100 |
IF_ADDR_RLOCK(ifp); |
1101 |
continue; |
1101 |
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { |
|
|
1102 |
struct in6_ifaddr *ifa6; |
1103 |
u_int32_t remaininglifetime; |
1102 |
|
1104 |
|
1103 |
/* |
1105 |
if (ifa->ifa_addr->sa_family != AF_INET6) |
1104 |
* Spec is not clear here, but I believe we should concentrate |
1106 |
continue; |
1105 |
* on unicast (i.e. not anycast) addresses. |
|
|
1106 |
* XXX: other ia6_flags? detached or duplicated? |
1107 |
*/ |
1108 |
if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0) |
1109 |
continue; |
1110 |
|
1107 |
|
1111 |
/* |
1108 |
ifa6 = (struct in6_ifaddr *)ifa; |
1112 |
* Ignore the address if it is not associated with a prefix |
|
|
1113 |
* or is associated with a prefix that is different from this |
1114 |
* one. (pr is never NULL here) |
1115 |
*/ |
1116 |
if (ifa6->ia6_ndpr != pr) |
1117 |
continue; |
1118 |
|
1109 |
|
1119 |
if (ia6_match == NULL) /* remember the first one */ |
1110 |
/* |
1120 |
ia6_match = ifa6; |
1111 |
* We only consider autoconfigured addresses as per rfc2462bis. |
|
|
1112 |
*/ |
1113 |
if (!(ifa6->ia6_flags & IN6_IFF_AUTOCONF)) |
1114 |
continue; |
1121 |
|
1115 |
|
1122 |
/* |
1116 |
/* |
1123 |
* An already autoconfigured address matched. Now that we |
1117 |
* Spec is not clear here, but I believe we should concentrate |
1124 |
* are sure there is at least one matched address, we can |
1118 |
* on unicast (i.e. not anycast) addresses. |
1125 |
* proceed to 5.5.3. (e): update the lifetimes according to the |
1119 |
* XXX: other ia6_flags? detached or duplicated? |
1126 |
* "two hours" rule and the privacy extension. |
1120 |
*/ |
1127 |
* We apply some clarifications in rfc2462bis: |
1121 |
if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0) |
1128 |
* - use remaininglifetime instead of storedlifetime as a |
1122 |
continue; |
1129 |
* variable name |
|
|
1130 |
* - remove the dead code in the "two-hour" rule |
1131 |
*/ |
1132 |
#define TWOHOUR (120*60) |
1133 |
lt6_tmp = ifa6->ia6_lifetime; |
1134 |
|
1123 |
|
1135 |
if (lt6_tmp.ia6t_vltime == ND6_INFINITE_LIFETIME) |
|
|
1136 |
remaininglifetime = ND6_INFINITE_LIFETIME; |
1137 |
else if (time_uptime - ifa6->ia6_updatetime > |
1138 |
lt6_tmp.ia6t_vltime) { |
1139 |
/* |
1124 |
/* |
1140 |
* The case of "invalid" address. We should usually |
1125 |
* Ignore the address if it is not associated with a prefix |
1141 |
* not see this case. |
1126 |
* or is associated with a prefix that is different from this |
|
|
1127 |
* one. (pr is never NULL here) |
1142 |
*/ |
1128 |
*/ |
1143 |
remaininglifetime = 0; |
1129 |
if (ifa6->ia6_ndpr != pr) |
1144 |
} else |
1130 |
continue; |
1145 |
remaininglifetime = lt6_tmp.ia6t_vltime - |
|
|
1146 |
(time_uptime - ifa6->ia6_updatetime); |
1147 |
|
1131 |
|
1148 |
/* when not updating, keep the current stored lifetime. */ |
1132 |
if (ia6_match == NULL) /* remember the first one */ |
1149 |
lt6_tmp.ia6t_vltime = remaininglifetime; |
1133 |
ia6_match = ifa6; |
1150 |
|
1134 |
|
1151 |
if (TWOHOUR < new->ndpr_vltime || |
|
|
1152 |
remaininglifetime < new->ndpr_vltime) { |
1153 |
lt6_tmp.ia6t_vltime = new->ndpr_vltime; |
1154 |
} else if (remaininglifetime <= TWOHOUR) { |
1155 |
if (auth) { |
1156 |
lt6_tmp.ia6t_vltime = new->ndpr_vltime; |
1157 |
} |
1158 |
} else { |
1159 |
/* |
1135 |
/* |
1160 |
* new->ndpr_vltime <= TWOHOUR && |
1136 |
* An already autoconfigured address matched. Now that we |
1161 |
* TWOHOUR < remaininglifetime |
1137 |
* are sure there is at least one matched address, we can |
|
|
1138 |
* proceed to 5.5.3. (e): update the lifetimes according to the |
1139 |
* "two hours" rule and the privacy extension. |
1140 |
* We apply some clarifications in rfc2462bis: |
1141 |
* - use remaininglifetime instead of storedlifetime as a |
1142 |
* variable name |
1143 |
* - remove the dead code in the "two-hour" rule |
1162 |
*/ |
1144 |
*/ |
1163 |
lt6_tmp.ia6t_vltime = TWOHOUR; |
1145 |
#define TWOHOUR (120*60) |
1164 |
} |
1146 |
lt6_tmp = ifa6->ia6_lifetime; |
1165 |
|
1147 |
|
1166 |
/* The 2 hour rule is not imposed for preferred lifetime. */ |
1148 |
if (lt6_tmp.ia6t_vltime == ND6_INFINITE_LIFETIME) |
1167 |
lt6_tmp.ia6t_pltime = new->ndpr_pltime; |
1149 |
remaininglifetime = ND6_INFINITE_LIFETIME; |
|
|
1150 |
else if (time_uptime - ifa6->ia6_updatetime > |
1151 |
lt6_tmp.ia6t_vltime) { |
1152 |
/* |
1153 |
* The case of "invalid" address. We should usually |
1154 |
* not see this case. |
1155 |
*/ |
1156 |
remaininglifetime = 0; |
1157 |
} else |
1158 |
remaininglifetime = lt6_tmp.ia6t_vltime - |
1159 |
(time_uptime - ifa6->ia6_updatetime); |
1168 |
|
1160 |
|
1169 |
in6_init_address_ltimes(pr, <6_tmp); |
1161 |
/* when not updating, keep the current stored lifetime. */ |
|
|
1162 |
lt6_tmp.ia6t_vltime = remaininglifetime; |
1170 |
|
1163 |
|
1171 |
/* |
1164 |
if (TWOHOUR < new->ndpr_vltime || |
1172 |
* We need to treat lifetimes for temporary addresses |
1165 |
remaininglifetime < new->ndpr_vltime) { |
1173 |
* differently, according to |
1166 |
lt6_tmp.ia6t_vltime = new->ndpr_vltime; |
1174 |
* draft-ietf-ipv6-privacy-addrs-v2-01.txt 3.3 (1); |
1167 |
} else if (remaininglifetime <= TWOHOUR) { |
1175 |
* we only update the lifetimes when they are in the maximum |
1168 |
if (auth) { |
1176 |
* intervals. |
1169 |
lt6_tmp.ia6t_vltime = new->ndpr_vltime; |
1177 |
*/ |
1170 |
} |
1178 |
if ((ifa6->ia6_flags & IN6_IFF_TEMPORARY) != 0) { |
1171 |
} else { |
1179 |
u_int32_t maxvltime, maxpltime; |
1172 |
/* |
|
|
1173 |
* new->ndpr_vltime <= TWOHOUR && |
1174 |
* TWOHOUR < remaininglifetime |
1175 |
*/ |
1176 |
lt6_tmp.ia6t_vltime = TWOHOUR; |
1177 |
} |
1180 |
|
1178 |
|
1181 |
if (V_ip6_temp_valid_lifetime > |
1179 |
/* The 2 hour rule is not imposed for preferred lifetime. */ |
1182 |
(u_int32_t)((time_uptime - ifa6->ia6_createtime) + |
1180 |
lt6_tmp.ia6t_pltime = new->ndpr_pltime; |
1183 |
V_ip6_desync_factor)) { |
|
|
1184 |
maxvltime = V_ip6_temp_valid_lifetime - |
1185 |
(time_uptime - ifa6->ia6_createtime) - |
1186 |
V_ip6_desync_factor; |
1187 |
} else |
1188 |
maxvltime = 0; |
1189 |
if (V_ip6_temp_preferred_lifetime > |
1190 |
(u_int32_t)((time_uptime - ifa6->ia6_createtime) + |
1191 |
V_ip6_desync_factor)) { |
1192 |
maxpltime = V_ip6_temp_preferred_lifetime - |
1193 |
(time_uptime - ifa6->ia6_createtime) - |
1194 |
V_ip6_desync_factor; |
1195 |
} else |
1196 |
maxpltime = 0; |
1197 |
|
1181 |
|
1198 |
if (lt6_tmp.ia6t_vltime == ND6_INFINITE_LIFETIME || |
1182 |
in6_init_address_ltimes(pr, <6_tmp); |
1199 |
lt6_tmp.ia6t_vltime > maxvltime) { |
|
|
1200 |
lt6_tmp.ia6t_vltime = maxvltime; |
1201 |
} |
1202 |
if (lt6_tmp.ia6t_pltime == ND6_INFINITE_LIFETIME || |
1203 |
lt6_tmp.ia6t_pltime > maxpltime) { |
1204 |
lt6_tmp.ia6t_pltime = maxpltime; |
1205 |
} |
1206 |
} |
1207 |
ifa6->ia6_lifetime = lt6_tmp; |
1208 |
ifa6->ia6_updatetime = time_uptime; |
1209 |
} |
1210 |
IF_ADDR_RUNLOCK(ifp); |
1211 |
if (ia6_match == NULL && new->ndpr_vltime) { |
1212 |
int ifidlen; |
1213 |
|
1183 |
|
1214 |
/* |
1184 |
/* |
1215 |
* 5.5.3 (d) (continued) |
1185 |
* We need to treat lifetimes for temporary addresses |
1216 |
* No address matched and the valid lifetime is non-zero. |
1186 |
* differently, according to |
1217 |
* Create a new address. |
1187 |
* draft-ietf-ipv6-privacy-addrs-v2-01.txt 3.3 (1); |
1218 |
*/ |
1188 |
* we only update the lifetimes when they are in the maximum |
|
|
1189 |
* intervals. |
1190 |
*/ |
1191 |
if ((ifa6->ia6_flags & IN6_IFF_TEMPORARY) != 0) { |
1192 |
u_int32_t maxvltime, maxpltime; |
1219 |
|
1193 |
|
1220 |
/* |
1194 |
if (V_ip6_temp_valid_lifetime > |
1221 |
* Prefix Length check: |
1195 |
(u_int32_t)((time_uptime - ifa6->ia6_createtime) + |
1222 |
* If the sum of the prefix length and interface identifier |
1196 |
V_ip6_desync_factor)) { |
1223 |
* length does not equal 128 bits, the Prefix Information |
1197 |
maxvltime = V_ip6_temp_valid_lifetime - |
1224 |
* option MUST be ignored. The length of the interface |
1198 |
(time_uptime - ifa6->ia6_createtime) - |
1225 |
* identifier is defined in a separate link-type specific |
1199 |
V_ip6_desync_factor; |
1226 |
* document. |
1200 |
} else |
1227 |
*/ |
1201 |
maxvltime = 0; |
1228 |
ifidlen = in6_if2idlen(ifp); |
1202 |
if (V_ip6_temp_preferred_lifetime > |
1229 |
if (ifidlen < 0) { |
1203 |
(u_int32_t)((time_uptime - ifa6->ia6_createtime) + |
1230 |
/* this should not happen, so we always log it. */ |
1204 |
V_ip6_desync_factor)) { |
1231 |
log(LOG_ERR, "prelist_update: IFID undefined (%s)\n", |
1205 |
maxpltime = V_ip6_temp_preferred_lifetime - |
1232 |
if_name(ifp)); |
1206 |
(time_uptime - ifa6->ia6_createtime) - |
1233 |
goto end; |
1207 |
V_ip6_desync_factor; |
|
|
1208 |
} else |
1209 |
maxpltime = 0; |
1210 |
|
1211 |
if (lt6_tmp.ia6t_vltime == ND6_INFINITE_LIFETIME || |
1212 |
lt6_tmp.ia6t_vltime > maxvltime) { |
1213 |
lt6_tmp.ia6t_vltime = maxvltime; |
1214 |
} |
1215 |
if (lt6_tmp.ia6t_pltime == ND6_INFINITE_LIFETIME || |
1216 |
lt6_tmp.ia6t_pltime > maxpltime) { |
1217 |
lt6_tmp.ia6t_pltime = maxpltime; |
1218 |
} |
1219 |
} |
1220 |
ifa6->ia6_lifetime = lt6_tmp; |
1221 |
ifa6->ia6_updatetime = time_uptime; |
1234 |
} |
1222 |
} |
1235 |
if (ifidlen + pr->ndpr_plen != 128) { |
1223 |
IF_ADDR_RUNLOCK(ifp); |
1236 |
nd6log((LOG_INFO, |
1224 |
if (ia6_match == NULL && new->ndpr_vltime) { |
1237 |
"prelist_update: invalid prefixlen " |
1225 |
int ifidlen; |
1238 |
"%d for %s, ignored\n", |
|
|
1239 |
pr->ndpr_plen, if_name(ifp))); |
1240 |
goto end; |
1241 |
} |
1242 |
|
1226 |
|
1243 |
if ((ia6 = in6_ifadd(new, mcast)) != NULL) { |
|
|
1244 |
/* |
1227 |
/* |
1245 |
* note that we should use pr (not new) for reference. |
1228 |
* 5.5.3 (d) (continued) |
|
|
1229 |
* No address matched and the valid lifetime is non-zero. |
1230 |
* Create a new address. |
1246 |
*/ |
1231 |
*/ |
1247 |
pr->ndpr_refcnt++; |
|
|
1248 |
ia6->ia6_ndpr = pr; |
1249 |
|
1232 |
|
1250 |
/* |
1233 |
/* |
1251 |
* RFC 3041 3.3 (2). |
1234 |
* Prefix Length check: |
1252 |
* When a new public address is created as described |
1235 |
* If the sum of the prefix length and interface identifier |
1253 |
* in RFC2462, also create a new temporary address. |
1236 |
* length does not equal 128 bits, the Prefix Information |
1254 |
* |
1237 |
* option MUST be ignored. The length of the interface |
1255 |
* RFC 3041 3.5. |
1238 |
* identifier is defined in a separate link-type specific |
1256 |
* When an interface connects to a new link, a new |
1239 |
* document. |
1257 |
* randomized interface identifier should be generated |
|
|
1258 |
* immediately together with a new set of temporary |
1259 |
* addresses. Thus, we specifiy 1 as the 2nd arg of |
1260 |
* in6_tmpifadd(). |
1261 |
*/ |
1240 |
*/ |
1262 |
if (V_ip6_use_tempaddr) { |
1241 |
ifidlen = in6_if2idlen(ifp); |
1263 |
int e; |
1242 |
if (ifidlen < 0) { |
1264 |
if ((e = in6_tmpifadd(ia6, 1, 1)) != 0) { |
1243 |
/* this should not happen, so we always log it. */ |
1265 |
nd6log((LOG_NOTICE, "prelist_update: " |
1244 |
log(LOG_ERR, "prelist_update: IFID undefined (%s)\n", |
1266 |
"failed to create a temporary " |
1245 |
if_name(ifp)); |
1267 |
"address, errno=%d\n", |
1246 |
goto end; |
1268 |
e)); |
|
|
1269 |
} |
1270 |
} |
1247 |
} |
1271 |
ifa_free(&ia6->ia_ifa); |
1248 |
if (ifidlen + pr->ndpr_plen != 128) { |
|
|
1249 |
nd6log((LOG_INFO, |
1250 |
"prelist_update: invalid prefixlen " |
1251 |
"%d for %s, ignored\n", |
1252 |
pr->ndpr_plen, if_name(ifp))); |
1253 |
goto end; |
1254 |
} |
1272 |
|
1255 |
|
|
|
1256 |
if ((ia6 = in6_ifadd(new, mcast)) == NULL) { |
1257 |
/* just set an error. do not bark here. */ |
1258 |
error = EADDRNOTAVAIL; /* XXX: might be unused. */ |
1259 |
goto end; |
1260 |
} |
1261 |
|
1273 |
/* |
1262 |
/* |
1274 |
* A newly added address might affect the status |
1263 |
* note that we should use pr (not new) for reference. |
1275 |
* of other addresses, so we check and update it. |
|
|
1276 |
* XXX: what if address duplication happens? |
1277 |
*/ |
1264 |
*/ |
1278 |
pfxlist_onlink_check(); |
1265 |
pr->ndpr_refcnt++; |
1279 |
} else { |
1266 |
ia6->ia6_ndpr = pr; |
1280 |
/* just set an error. do not bark here. */ |
|
|
1281 |
error = EADDRNOTAVAIL; /* XXX: might be unused. */ |
1282 |
} |
1267 |
} |
1283 |
} |
1268 |
} |
1284 |
|
1269 |
|
|
|
1270 |
/* |
1271 |
* RFC 3041 3.3 (2). |
1272 |
* When a new public address is created as described |
1273 |
* in RFC2462, also create a new temporary address. |
1274 |
* |
1275 |
* RFC 3041 3.5. |
1276 |
* When an interface connects to a new link, a new |
1277 |
* randomized interface identifier should be generated |
1278 |
* immediately together with a new set of temporary |
1279 |
* addresses. Thus, we specifiy 1 as the 2nd arg of |
1280 |
* in6_tmpifadd(). |
1281 |
*/ |
1282 |
if (V_ip6_use_tempaddr) { |
1283 |
int e; |
1284 |
if ((e = in6_tmpifadd(ia6, 1, 1)) != 0) { |
1285 |
nd6log((LOG_NOTICE, "prelist_update: " |
1286 |
"failed to create a temporary " |
1287 |
"address, errno=%d\n", |
1288 |
e)); |
1289 |
} |
1290 |
} |
1291 |
|
1292 |
/* ia6 was created in this function */ |
1293 |
if (ia6_match) |
1294 |
ifa_free(&ia6->ia_ifa); |
1295 |
|
1296 |
/* |
1297 |
* A newly added address might affect the status |
1298 |
* of other addresses, so we check and update it. |
1299 |
* XXX: what if address duplication happens? |
1300 |
*/ |
1301 |
pfxlist_onlink_check(); |
1302 |
|
1285 |
end: |
1303 |
end: |
1286 |
return error; |
1304 |
return error; |
1287 |
} |
1305 |
} |