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 |
1090 |
/* |
1080 |
* list of addresses associated with the interface, and the Valid |
1091 |
* 5.5.3 (d). If the prefix advertised is not equal to the |
1081 |
* Lifetime is not 0, form an address. We first check if we have |
1092 |
* prefix of an address configured by stateless |
1082 |
* a matching prefix. |
1093 |
* autoconfiguration already in the list of addresses |
1083 |
* Note: we apply a clarification in rfc2462bis-02 here. We only |
1094 |
* associated with the interface, and the Valid Lifetime |
1084 |
* consider autoconfigured addresses while RFC2462 simply said |
1095 |
* is not 0, form an address. We first check if we have |
1085 |
* "address". |
1096 |
* a matching prefix. |
1086 |
*/ |
1097 |
* Note: we apply a clarification in rfc2462bis-02 here. We |
1087 |
IF_ADDR_RLOCK(ifp); |
1098 |
* only consider autoconfigured addresses while RFC2462 simply |
1088 |
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { |
1099 |
* said "address". |
1089 |
struct in6_ifaddr *ifa6; |
1100 |
*/ |
1090 |
u_int32_t remaininglifetime; |
1101 |
IF_ADDR_RLOCK(ifp); |
|
|
1102 |
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { |
1103 |
struct in6_ifaddr *ifa6; |
1104 |
u_int32_t remaininglifetime; |
1091 |
|
1105 |
|
1092 |
if (ifa->ifa_addr->sa_family != AF_INET6) |
1106 |
if (ifa->ifa_addr->sa_family != AF_INET6) |
1093 |
continue; |
1107 |
continue; |
1094 |
|
1108 |
|
1095 |
ifa6 = (struct in6_ifaddr *)ifa; |
1109 |
ifa6 = (struct in6_ifaddr *)ifa; |
1096 |
|
1110 |
|
1097 |
/* |
1111 |
/* |
1098 |
* We only consider autoconfigured addresses as per rfc2462bis. |
1112 |
* We only consider autoconfigured addresses as per |
1099 |
*/ |
1113 |
* rfc2462bis. |
1100 |
if (!(ifa6->ia6_flags & IN6_IFF_AUTOCONF)) |
1114 |
*/ |
1101 |
continue; |
1115 |
if (!(ifa6->ia6_flags & IN6_IFF_AUTOCONF)) |
|
|
1116 |
continue; |
1102 |
|
1117 |
|
1103 |
/* |
1118 |
/* |
1104 |
* Spec is not clear here, but I believe we should concentrate |
1119 |
* Spec is not clear here, but I believe we should |
1105 |
* on unicast (i.e. not anycast) addresses. |
1120 |
* concentrate on unicast (i.e. not anycast) |
1106 |
* XXX: other ia6_flags? detached or duplicated? |
1121 |
* addresses. |
1107 |
*/ |
1122 |
* XXX: other ia6_flags? detached or duplicated? |
1108 |
if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0) |
1123 |
*/ |
1109 |
continue; |
1124 |
if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0) |
|
|
1125 |
continue; |
1110 |
|
1126 |
|
1111 |
/* |
1127 |
/* |
1112 |
* Ignore the address if it is not associated with a prefix |
1128 |
* Ignore the address if it is not associated with a |
1113 |
* or is associated with a prefix that is different from this |
1129 |
* prefix or is associated with a prefix that is |
1114 |
* one. (pr is never NULL here) |
1130 |
* different from this one. (pr is never NULL here) |
1115 |
*/ |
1131 |
*/ |
1116 |
if (ifa6->ia6_ndpr != pr) |
1132 |
if (ifa6->ia6_ndpr != pr) |
1117 |
continue; |
1133 |
continue; |
1118 |
|
1134 |
|
1119 |
if (ia6_match == NULL) /* remember the first one */ |
1135 |
if (ia6_match == NULL) /* remember the first one */ |
1120 |
ia6_match = ifa6; |
1136 |
ia6_match = ifa6; |
1121 |
|
1137 |
|
1122 |
/* |
1138 |
/* |
1123 |
* An already autoconfigured address matched. Now that we |
1139 |
* An already autoconfigured address matched. Now |
1124 |
* are sure there is at least one matched address, we can |
1140 |
* that we are sure there is at least one matched |
1125 |
* proceed to 5.5.3. (e): update the lifetimes according to the |
1141 |
* address, we can proceed to 5.5.3. (e): update |
1126 |
* "two hours" rule and the privacy extension. |
1142 |
* the lifetimes according to the "two hours" rule |
1127 |
* We apply some clarifications in rfc2462bis: |
1143 |
* and the privacy extension. |
1128 |
* - use remaininglifetime instead of storedlifetime as a |
1144 |
* We apply some clarifications in rfc2462bis: |
1129 |
* variable name |
1145 |
* - use remaininglifetime instead of storedlifetime |
1130 |
* - remove the dead code in the "two-hour" rule |
1146 |
* as a variable name |
1131 |
*/ |
1147 |
* - remove the dead code in the "two-hour" rule |
1132 |
#define TWOHOUR (120*60) |
1148 |
*/ |
1133 |
lt6_tmp = ifa6->ia6_lifetime; |
1149 |
#define TWOHOUR (120*60) |
|
|
1150 |
lt6_tmp = ifa6->ia6_lifetime; |
1134 |
|
1151 |
|
1135 |
if (lt6_tmp.ia6t_vltime == ND6_INFINITE_LIFETIME) |
1152 |
if (lt6_tmp.ia6t_vltime == ND6_INFINITE_LIFETIME) |
1136 |
remaininglifetime = ND6_INFINITE_LIFETIME; |
1153 |
remaininglifetime = ND6_INFINITE_LIFETIME; |
1137 |
else if (time_uptime - ifa6->ia6_updatetime > |
1154 |
else if (time_uptime - ifa6->ia6_updatetime > |
1138 |
lt6_tmp.ia6t_vltime) { |
1155 |
lt6_tmp.ia6t_vltime) { |
|
|
1156 |
/* |
1157 |
* The case of "invalid" address. We should |
1158 |
* usually not see this case. |
1159 |
*/ |
1160 |
remaininglifetime = 0; |
1161 |
} else |
1162 |
remaininglifetime = lt6_tmp.ia6t_vltime - |
1163 |
(time_uptime - ifa6->ia6_updatetime); |
1164 |
|
1139 |
/* |
1165 |
/* |
1140 |
* The case of "invalid" address. We should usually |
1166 |
* when not updating, keep the current stored |
1141 |
* not see this case. |
1167 |
* lifetime. |
1142 |
*/ |
1168 |
*/ |
1143 |
remaininglifetime = 0; |
1169 |
lt6_tmp.ia6t_vltime = remaininglifetime; |
1144 |
} else |
|
|
1145 |
remaininglifetime = lt6_tmp.ia6t_vltime - |
1146 |
(time_uptime - ifa6->ia6_updatetime); |
1147 |
|
1170 |
|
1148 |
/* when not updating, keep the current stored lifetime. */ |
1171 |
if (TWOHOUR < new->ndpr_vltime || |
1149 |
lt6_tmp.ia6t_vltime = remaininglifetime; |
1172 |
remaininglifetime < new->ndpr_vltime) { |
1150 |
|
|
|
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; |
1173 |
lt6_tmp.ia6t_vltime = new->ndpr_vltime; |
|
|
1174 |
} else if (remaininglifetime <= TWOHOUR) { |
1175 |
if (auth) { |
1176 |
lt6_tmp.ia6t_vltime = new->ndpr_vltime; |
1177 |
} |
1178 |
} else { |
1179 |
/* |
1180 |
* new->ndpr_vltime <= TWOHOUR && |
1181 |
* TWOHOUR < remaininglifetime |
1182 |
*/ |
1183 |
lt6_tmp.ia6t_vltime = TWOHOUR; |
1157 |
} |
1184 |
} |
1158 |
} else { |
1185 |
|
1159 |
/* |
1186 |
/* |
1160 |
* new->ndpr_vltime <= TWOHOUR && |
1187 |
* The 2 hour rule is not imposed for preferred |
1161 |
* TWOHOUR < remaininglifetime |
1188 |
* lifetime. |
1162 |
*/ |
1189 |
*/ |
1163 |
lt6_tmp.ia6t_vltime = TWOHOUR; |
1190 |
lt6_tmp.ia6t_pltime = new->ndpr_pltime; |
1164 |
} |
|
|
1165 |
|
1191 |
|
1166 |
/* The 2 hour rule is not imposed for preferred lifetime. */ |
1192 |
in6_init_address_ltimes(pr, <6_tmp); |
1167 |
lt6_tmp.ia6t_pltime = new->ndpr_pltime; |
|
|
1168 |
|
1193 |
|
1169 |
in6_init_address_ltimes(pr, <6_tmp); |
1194 |
/* |
|
|
1195 |
* We need to treat lifetimes for temporary addresses |
1196 |
* differently, according to |
1197 |
* draft-ietf-ipv6-privacy-addrs-v2-01.txt 3.3 (1); |
1198 |
* we only update the lifetimes when they are in the |
1199 |
* maximum intervals. |
1200 |
*/ |
1201 |
if ((ifa6->ia6_flags & IN6_IFF_TEMPORARY) != 0) { |
1202 |
u_int32_t maxvltime, maxpltime; |
1170 |
|
1203 |
|
1171 |
/* |
1204 |
if (V_ip6_temp_valid_lifetime > |
1172 |
* We need to treat lifetimes for temporary addresses |
1205 |
(u_int32_t)((time_uptime - |
1173 |
* differently, according to |
1206 |
ifa6->ia6_createtime) + |
1174 |
* draft-ietf-ipv6-privacy-addrs-v2-01.txt 3.3 (1); |
1207 |
V_ip6_desync_factor)) { |
1175 |
* we only update the lifetimes when they are in the maximum |
1208 |
maxvltime = |
1176 |
* intervals. |
1209 |
V_ip6_temp_valid_lifetime - |
1177 |
*/ |
1210 |
(time_uptime - |
1178 |
if ((ifa6->ia6_flags & IN6_IFF_TEMPORARY) != 0) { |
1211 |
ifa6->ia6_createtime) - |
1179 |
u_int32_t maxvltime, maxpltime; |
1212 |
V_ip6_desync_factor; |
|
|
1213 |
} else |
1214 |
maxvltime = 0; |
1215 |
if (V_ip6_temp_preferred_lifetime > |
1216 |
(u_int32_t)((time_uptime - |
1217 |
ifa6->ia6_createtime) + |
1218 |
V_ip6_desync_factor)) { |
1219 |
maxpltime = |
1220 |
V_ip6_temp_preferred_lifetime - |
1221 |
(time_uptime - |
1222 |
ifa6->ia6_createtime) - |
1223 |
V_ip6_desync_factor; |
1224 |
} else |
1225 |
maxpltime = 0; |
1180 |
|
1226 |
|
1181 |
if (V_ip6_temp_valid_lifetime > |
1227 |
if (lt6_tmp.ia6t_vltime == |
1182 |
(u_int32_t)((time_uptime - ifa6->ia6_createtime) + |
1228 |
ND6_INFINITE_LIFETIME || |
1183 |
V_ip6_desync_factor)) { |
1229 |
lt6_tmp.ia6t_vltime > maxvltime) { |
1184 |
maxvltime = V_ip6_temp_valid_lifetime - |
1230 |
lt6_tmp.ia6t_vltime = maxvltime; |
1185 |
(time_uptime - ifa6->ia6_createtime) - |
1231 |
} |
1186 |
V_ip6_desync_factor; |
1232 |
if (lt6_tmp.ia6t_pltime == |
1187 |
} else |
1233 |
ND6_INFINITE_LIFETIME || |
1188 |
maxvltime = 0; |
1234 |
lt6_tmp.ia6t_pltime > maxpltime) { |
1189 |
if (V_ip6_temp_preferred_lifetime > |
1235 |
lt6_tmp.ia6t_pltime = maxpltime; |
1190 |
(u_int32_t)((time_uptime - ifa6->ia6_createtime) + |
1236 |
} |
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 |
|
1198 |
if (lt6_tmp.ia6t_vltime == ND6_INFINITE_LIFETIME || |
1199 |
lt6_tmp.ia6t_vltime > maxvltime) { |
1200 |
lt6_tmp.ia6t_vltime = maxvltime; |
1201 |
} |
1237 |
} |
1202 |
if (lt6_tmp.ia6t_pltime == ND6_INFINITE_LIFETIME || |
1238 |
ifa6->ia6_lifetime = lt6_tmp; |
1203 |
lt6_tmp.ia6t_pltime > maxpltime) { |
1239 |
ifa6->ia6_updatetime = time_uptime; |
1204 |
lt6_tmp.ia6t_pltime = maxpltime; |
|
|
1205 |
} |
1206 |
} |
1240 |
} |
1207 |
ifa6->ia6_lifetime = lt6_tmp; |
1241 |
IF_ADDR_RUNLOCK(ifp); |
1208 |
ifa6->ia6_updatetime = time_uptime; |
1242 |
if (ia6_match == NULL && new->ndpr_vltime) { |
1209 |
} |
1243 |
int ifidlen; |
1210 |
IF_ADDR_RUNLOCK(ifp); |
|
|
1211 |
if (ia6_match == NULL && new->ndpr_vltime) { |
1212 |
int ifidlen; |
1213 |
|
1244 |
|
1214 |
/* |
|
|
1215 |
* 5.5.3 (d) (continued) |
1216 |
* No address matched and the valid lifetime is non-zero. |
1217 |
* Create a new address. |
1218 |
*/ |
1219 |
|
1220 |
/* |
1221 |
* Prefix Length check: |
1222 |
* If the sum of the prefix length and interface identifier |
1223 |
* length does not equal 128 bits, the Prefix Information |
1224 |
* option MUST be ignored. The length of the interface |
1225 |
* identifier is defined in a separate link-type specific |
1226 |
* document. |
1227 |
*/ |
1228 |
ifidlen = in6_if2idlen(ifp); |
1229 |
if (ifidlen < 0) { |
1230 |
/* this should not happen, so we always log it. */ |
1231 |
log(LOG_ERR, "prelist_update: IFID undefined (%s)\n", |
1232 |
if_name(ifp)); |
1233 |
goto end; |
1234 |
} |
1235 |
if (ifidlen + pr->ndpr_plen != 128) { |
1236 |
nd6log((LOG_INFO, |
1237 |
"prelist_update: invalid prefixlen " |
1238 |
"%d for %s, ignored\n", |
1239 |
pr->ndpr_plen, if_name(ifp))); |
1240 |
goto end; |
1241 |
} |
1242 |
|
1243 |
if ((ia6 = in6_ifadd(new, mcast)) != NULL) { |
1244 |
/* |
1245 |
/* |
1245 |
* note that we should use pr (not new) for reference. |
1246 |
* 5.5.3 (d) (continued) |
|
|
1247 |
* No address matched and the valid lifetime is |
1248 |
* non-zero. |
1249 |
* Create a new address. |
1246 |
*/ |
1250 |
*/ |
1247 |
pr->ndpr_refcnt++; |
|
|
1248 |
ia6->ia6_ndpr = pr; |
1249 |
|
1251 |
|
1250 |
/* |
1252 |
/* |
1251 |
* RFC 3041 3.3 (2). |
1253 |
* Prefix Length check: |
1252 |
* When a new public address is created as described |
1254 |
* If the sum of the prefix length and interface |
1253 |
* in RFC2462, also create a new temporary address. |
1255 |
* identifier length does not equal 128 bits, the |
1254 |
* |
1256 |
* Prefix Information option MUST be ignored. The |
1255 |
* RFC 3041 3.5. |
1257 |
* length of the interface identifier is defined in |
1256 |
* When an interface connects to a new link, a new |
1258 |
* a separate link-type specific 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 |
*/ |
1259 |
*/ |
1262 |
if (V_ip6_use_tempaddr) { |
1260 |
ifidlen = in6_if2idlen(ifp); |
1263 |
int e; |
1261 |
if (ifidlen < 0) { |
1264 |
if ((e = in6_tmpifadd(ia6, 1, 1)) != 0) { |
1262 |
/* |
1265 |
nd6log((LOG_NOTICE, "prelist_update: " |
1263 |
* this should not happen, so we always log |
1266 |
"failed to create a temporary " |
1264 |
* it. |
1267 |
"address, errno=%d\n", |
1265 |
*/ |
1268 |
e)); |
1266 |
log(LOG_ERR, "prelist_update: IFID undefined " |
1269 |
} |
1267 |
"(%s)\n", if_name(ifp)); |
|
|
1268 |
goto end; |
1270 |
} |
1269 |
} |
1271 |
ifa_free(&ia6->ia_ifa); |
1270 |
if (ifidlen + pr->ndpr_plen != 128) { |
|
|
1271 |
nd6log((LOG_INFO, |
1272 |
"prelist_update: invalid prefixlen " |
1273 |
"%d for %s, ignored\n", |
1274 |
pr->ndpr_plen, if_name(ifp))); |
1275 |
goto end; |
1276 |
} |
1272 |
|
1277 |
|
|
|
1278 |
if ((ia6 = in6_ifadd(new, mcast)) == NULL) { |
1279 |
/* just set an error. do not bark here. */ |
1280 |
error = EADDRNOTAVAIL; /* XXX: might be unused. */ |
1281 |
goto end; |
1282 |
} |
1283 |
|
1273 |
/* |
1284 |
/* |
1274 |
* A newly added address might affect the status |
1285 |
* 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 |
*/ |
1286 |
*/ |
1278 |
pfxlist_onlink_check(); |
1287 |
pr->ndpr_refcnt++; |
1279 |
} else { |
1288 |
ia6->ia6_ndpr = pr; |
1280 |
/* just set an error. do not bark here. */ |
|
|
1281 |
error = EADDRNOTAVAIL; /* XXX: might be unused. */ |
1282 |
} |
1289 |
} |
1283 |
} |
1290 |
} |
1284 |
|
1291 |
|
|
|
1292 |
/* |
1293 |
* RFC 3041 3.3 (2). |
1294 |
* When a new public address is created as described |
1295 |
* in RFC2462, also create a new temporary address. |
1296 |
* |
1297 |
* RFC 3041 3.5. |
1298 |
* When an interface connects to a new link, a new |
1299 |
* randomized interface identifier should be generated |
1300 |
* immediately together with a new set of temporary |
1301 |
* addresses. Thus, we specifiy 1 as the 2nd arg of |
1302 |
* in6_tmpifadd(). |
1303 |
*/ |
1304 |
if (V_ip6_use_tempaddr) { |
1305 |
int e; |
1306 |
if ((e = in6_tmpifadd(ia6, 1, 1)) != 0) { |
1307 |
nd6log((LOG_NOTICE, "prelist_update: " |
1308 |
"failed to create a temporary " |
1309 |
"address, errno=%d\n", |
1310 |
e)); |
1311 |
} |
1312 |
} |
1313 |
|
1314 |
/* ia6 was created in this function */ |
1315 |
if (ia6_match) |
1316 |
ifa_free(&ia6->ia_ifa); |
1317 |
|
1318 |
/* |
1319 |
* A newly added address might affect the status |
1320 |
* of other addresses, so we check and update it. |
1321 |
* XXX: what if address duplication happens? |
1322 |
*/ |
1323 |
pfxlist_onlink_check(); |
1324 |
|
1285 |
end: |
1325 |
end: |
1286 |
return error; |
1326 |
return error; |
1287 |
} |
1327 |
} |