]>
Commit | Line | Data |
---|---|---|
718e3744 | 1 | /* |
2 | * Common ioctl functions. | |
3 | * Copyright (C) 1997, 98 Kunihiro Ishiguro | |
4 | * | |
5 | * This file is part of GNU Zebra. | |
6 | * | |
7 | * GNU Zebra is free software; you can redistribute it and/or modify it | |
8 | * under the terms of the GNU General Public License as published by the | |
9 | * Free Software Foundation; either version 2, or (at your option) any | |
10 | * later version. | |
11 | * | |
12 | * GNU Zebra is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with GNU Zebra; see the file COPYING. If not, write to the Free | |
19 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
20 | * 02111-1307, USA. | |
21 | */ | |
22 | ||
23 | #include <zebra.h> | |
24 | ||
25 | #include "linklist.h" | |
26 | #include "if.h" | |
27 | #include "prefix.h" | |
28 | #include "ioctl.h" | |
29 | #include "log.h" | |
edd7c245 | 30 | #include "privs.h" |
718e3744 | 31 | |
32 | #include "zebra/rib.h" | |
33 | #include "zebra/rt.h" | |
34 | ||
edd7c245 | 35 | extern struct zebra_privs_t zserv_privs; |
36 | ||
718e3744 | 37 | /* clear and set interface name string */ |
38 | void | |
39 | ifreq_set_name (struct ifreq *ifreq, struct interface *ifp) | |
40 | { | |
41 | strncpy (ifreq->ifr_name, ifp->name, IFNAMSIZ); | |
42 | } | |
43 | ||
44 | /* call ioctl system call */ | |
45 | int | |
46 | if_ioctl (u_long request, caddr_t buffer) | |
47 | { | |
48 | int sock; | |
4460e7a4 | 49 | int ret; |
50 | int err; | |
718e3744 | 51 | |
edd7c245 | 52 | if (zserv_privs.change(ZPRIVS_RAISE)) |
53 | zlog (NULL, LOG_ERR, "Can't raise privileges"); | |
718e3744 | 54 | sock = socket (AF_INET, SOCK_DGRAM, 0); |
55 | if (sock < 0) | |
56 | { | |
6a52d0d1 | 57 | int save_errno = errno; |
edd7c245 | 58 | if (zserv_privs.change(ZPRIVS_LOWER)) |
59 | zlog (NULL, LOG_ERR, "Can't lower privileges"); | |
6a52d0d1 | 60 | zlog_err("Cannot create UDP socket: %s", safe_strerror(save_errno)); |
718e3744 | 61 | exit (1); |
62 | } | |
4460e7a4 | 63 | if ((ret = ioctl (sock, request, buffer)) < 0) |
64 | err = errno; | |
edd7c245 | 65 | if (zserv_privs.change(ZPRIVS_LOWER)) |
66 | zlog (NULL, LOG_ERR, "Can't lower privileges"); | |
718e3744 | 67 | close (sock); |
68 | ||
69 | if (ret < 0) | |
70 | { | |
71 | errno = err; | |
72 | return ret; | |
73 | } | |
74 | return 0; | |
75 | } | |
76 | ||
77 | #ifdef HAVE_IPV6 | |
a1ac18c4 | 78 | static int |
718e3744 | 79 | if_ioctl_ipv6 (u_long request, caddr_t buffer) |
80 | { | |
81 | int sock; | |
4460e7a4 | 82 | int ret; |
83 | int err; | |
718e3744 | 84 | |
edd7c245 | 85 | if (zserv_privs.change(ZPRIVS_RAISE)) |
86 | zlog (NULL, LOG_ERR, "Can't raise privileges"); | |
718e3744 | 87 | sock = socket (AF_INET6, SOCK_DGRAM, 0); |
88 | if (sock < 0) | |
89 | { | |
6a52d0d1 | 90 | int save_errno = errno; |
edd7c245 | 91 | if (zserv_privs.change(ZPRIVS_LOWER)) |
92 | zlog (NULL, LOG_ERR, "Can't lower privileges"); | |
6a52d0d1 | 93 | zlog_err("Cannot create IPv6 datagram socket: %s", |
94 | safe_strerror(save_errno)); | |
718e3744 | 95 | exit (1); |
96 | } | |
97 | ||
4460e7a4 | 98 | if ((ret = ioctl (sock, request, buffer)) < 0) |
99 | err = errno; | |
edd7c245 | 100 | if (zserv_privs.change(ZPRIVS_LOWER)) |
101 | zlog (NULL, LOG_ERR, "Can't lower privileges"); | |
718e3744 | 102 | close (sock); |
103 | ||
104 | if (ret < 0) | |
105 | { | |
106 | errno = err; | |
107 | return ret; | |
108 | } | |
109 | return 0; | |
110 | } | |
111 | #endif /* HAVE_IPV6 */ | |
112 | ||
113 | /* | |
114 | * get interface metric | |
115 | * -- if value is not avaliable set -1 | |
116 | */ | |
117 | void | |
118 | if_get_metric (struct interface *ifp) | |
119 | { | |
120 | #ifdef SIOCGIFMETRIC | |
121 | struct ifreq ifreq; | |
122 | ||
123 | ifreq_set_name (&ifreq, ifp); | |
124 | ||
125 | if (if_ioctl (SIOCGIFMETRIC, (caddr_t) &ifreq) < 0) | |
126 | return; | |
127 | ifp->metric = ifreq.ifr_metric; | |
128 | if (ifp->metric == 0) | |
129 | ifp->metric = 1; | |
130 | #else /* SIOCGIFMETRIC */ | |
131 | ifp->metric = -1; | |
132 | #endif /* SIOCGIFMETRIC */ | |
133 | } | |
134 | ||
135 | /* get interface MTU */ | |
136 | void | |
137 | if_get_mtu (struct interface *ifp) | |
138 | { | |
139 | struct ifreq ifreq; | |
140 | ||
141 | ifreq_set_name (&ifreq, ifp); | |
142 | ||
143 | #if defined(SIOCGIFMTU) | |
144 | if (if_ioctl (SIOCGIFMTU, (caddr_t) & ifreq) < 0) | |
145 | { | |
146 | zlog_info ("Can't lookup mtu by ioctl(SIOCGIFMTU)"); | |
44145db3 | 147 | ifp->mtu6 = ifp->mtu = -1; |
718e3744 | 148 | return; |
149 | } | |
150 | ||
151 | #ifdef SUNOS_5 | |
44145db3 | 152 | ifp->mtu6 = ifp->mtu = ifreq.ifr_metric; |
718e3744 | 153 | #else |
44145db3 | 154 | ifp->mtu6 = ifp->mtu = ifreq.ifr_mtu; |
718e3744 | 155 | #endif /* SUNOS_5 */ |
156 | ||
157 | #else | |
158 | zlog (NULL, LOG_INFO, "Can't lookup mtu on this system"); | |
44145db3 | 159 | ifp->mtu6 = ifp->mtu = -1; |
718e3744 | 160 | #endif |
161 | } | |
162 | ||
163 | #ifdef HAVE_NETLINK | |
164 | /* Interface address setting via netlink interface. */ | |
165 | int | |
166 | if_set_prefix (struct interface *ifp, struct connected *ifc) | |
167 | { | |
168 | return kernel_address_add_ipv4 (ifp, ifc); | |
169 | } | |
170 | ||
171 | /* Interface address is removed using netlink interface. */ | |
172 | int | |
173 | if_unset_prefix (struct interface *ifp, struct connected *ifc) | |
174 | { | |
175 | return kernel_address_delete_ipv4 (ifp, ifc); | |
176 | } | |
177 | #else /* ! HAVE_NETLINK */ | |
178 | #ifdef HAVE_IFALIASREQ | |
179 | /* Set up interface's IP address, netmask (and broadcas? ). *BSD may | |
180 | has ifaliasreq structure. */ | |
181 | int | |
182 | if_set_prefix (struct interface *ifp, struct connected *ifc) | |
183 | { | |
184 | int ret; | |
185 | struct ifaliasreq addreq; | |
186 | struct sockaddr_in addr; | |
187 | struct sockaddr_in mask; | |
188 | struct prefix_ipv4 *p; | |
189 | ||
190 | p = (struct prefix_ipv4 *) ifc->address; | |
191 | ||
192 | memset (&addreq, 0, sizeof addreq); | |
193 | strncpy ((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name); | |
194 | ||
195 | memset (&addr, 0, sizeof (struct sockaddr_in)); | |
196 | addr.sin_addr = p->prefix; | |
197 | addr.sin_family = p->family; | |
198 | #ifdef HAVE_SIN_LEN | |
199 | addr.sin_len = sizeof (struct sockaddr_in); | |
200 | #endif | |
201 | memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in)); | |
202 | ||
203 | memset (&mask, 0, sizeof (struct sockaddr_in)); | |
204 | masklen2ip (p->prefixlen, &mask.sin_addr); | |
205 | mask.sin_family = p->family; | |
206 | #ifdef HAVE_SIN_LEN | |
207 | mask.sin_len = sizeof (struct sockaddr_in); | |
208 | #endif | |
209 | memcpy (&addreq.ifra_mask, &mask, sizeof (struct sockaddr_in)); | |
210 | ||
211 | ret = if_ioctl (SIOCAIFADDR, (caddr_t) &addreq); | |
212 | if (ret < 0) | |
213 | return ret; | |
214 | return 0; | |
215 | } | |
216 | ||
217 | /* Set up interface's IP address, netmask (and broadcas? ). *BSD may | |
218 | has ifaliasreq structure. */ | |
219 | int | |
220 | if_unset_prefix (struct interface *ifp, struct connected *ifc) | |
221 | { | |
222 | int ret; | |
223 | struct ifaliasreq addreq; | |
224 | struct sockaddr_in addr; | |
225 | struct sockaddr_in mask; | |
226 | struct prefix_ipv4 *p; | |
227 | ||
228 | p = (struct prefix_ipv4 *)ifc->address; | |
229 | ||
230 | memset (&addreq, 0, sizeof addreq); | |
231 | strncpy ((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name); | |
232 | ||
233 | memset (&addr, 0, sizeof (struct sockaddr_in)); | |
234 | addr.sin_addr = p->prefix; | |
235 | addr.sin_family = p->family; | |
236 | #ifdef HAVE_SIN_LEN | |
237 | addr.sin_len = sizeof (struct sockaddr_in); | |
238 | #endif | |
239 | memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in)); | |
240 | ||
241 | memset (&mask, 0, sizeof (struct sockaddr_in)); | |
242 | masklen2ip (p->prefixlen, &mask.sin_addr); | |
243 | mask.sin_family = p->family; | |
244 | #ifdef HAVE_SIN_LEN | |
245 | mask.sin_len = sizeof (struct sockaddr_in); | |
246 | #endif | |
247 | memcpy (&addreq.ifra_mask, &mask, sizeof (struct sockaddr_in)); | |
248 | ||
249 | ret = if_ioctl (SIOCDIFADDR, (caddr_t) &addreq); | |
250 | if (ret < 0) | |
251 | return ret; | |
252 | return 0; | |
253 | } | |
254 | #else | |
255 | /* Set up interface's address, netmask (and broadcas? ). Linux or | |
256 | Solaris uses ifname:number semantics to set IP address aliases. */ | |
257 | int | |
258 | if_set_prefix (struct interface *ifp, struct connected *ifc) | |
259 | { | |
260 | int ret; | |
261 | struct ifreq ifreq; | |
262 | struct sockaddr_in addr; | |
263 | struct sockaddr_in broad; | |
264 | struct sockaddr_in mask; | |
265 | struct prefix_ipv4 ifaddr; | |
266 | struct prefix_ipv4 *p; | |
267 | ||
268 | p = (struct prefix_ipv4 *) ifc->address; | |
269 | ||
270 | ifaddr = *p; | |
271 | ||
272 | ifreq_set_name (&ifreq, ifp); | |
273 | ||
274 | addr.sin_addr = p->prefix; | |
275 | addr.sin_family = p->family; | |
276 | memcpy (&ifreq.ifr_addr, &addr, sizeof (struct sockaddr_in)); | |
277 | ret = if_ioctl (SIOCSIFADDR, (caddr_t) &ifreq); | |
278 | if (ret < 0) | |
279 | return ret; | |
280 | ||
281 | /* We need mask for make broadcast addr. */ | |
282 | masklen2ip (p->prefixlen, &mask.sin_addr); | |
283 | ||
284 | if (if_is_broadcast (ifp)) | |
285 | { | |
286 | apply_mask_ipv4 (&ifaddr); | |
287 | addr.sin_addr = ifaddr.prefix; | |
288 | ||
289 | broad.sin_addr.s_addr = (addr.sin_addr.s_addr | ~mask.sin_addr.s_addr); | |
290 | broad.sin_family = p->family; | |
291 | ||
292 | memcpy (&ifreq.ifr_broadaddr, &broad, sizeof (struct sockaddr_in)); | |
293 | ret = if_ioctl (SIOCSIFBRDADDR, (caddr_t) &ifreq); | |
294 | if (ret < 0) | |
295 | return ret; | |
296 | } | |
297 | ||
298 | mask.sin_family = p->family; | |
299 | #ifdef SUNOS_5 | |
300 | memcpy (&mask, &ifreq.ifr_addr, sizeof (mask)); | |
301 | #else | |
302 | memcpy (&ifreq.ifr_netmask, &mask, sizeof (struct sockaddr_in)); | |
303 | #endif /* SUNOS5 */ | |
304 | ret = if_ioctl (SIOCSIFNETMASK, (caddr_t) &ifreq); | |
305 | if (ret < 0) | |
306 | return ret; | |
307 | ||
308 | return 0; | |
309 | } | |
310 | ||
311 | /* Set up interface's address, netmask (and broadcas? ). Linux or | |
312 | Solaris uses ifname:number semantics to set IP address aliases. */ | |
313 | int | |
314 | if_unset_prefix (struct interface *ifp, struct connected *ifc) | |
315 | { | |
316 | int ret; | |
317 | struct ifreq ifreq; | |
318 | struct sockaddr_in addr; | |
319 | struct prefix_ipv4 *p; | |
320 | ||
321 | p = (struct prefix_ipv4 *) ifc->address; | |
322 | ||
323 | ifreq_set_name (&ifreq, ifp); | |
324 | ||
325 | memset (&addr, 0, sizeof (struct sockaddr_in)); | |
326 | addr.sin_family = p->family; | |
327 | memcpy (&ifreq.ifr_addr, &addr, sizeof (struct sockaddr_in)); | |
328 | ret = if_ioctl (SIOCSIFADDR, (caddr_t) &ifreq); | |
329 | if (ret < 0) | |
330 | return ret; | |
331 | ||
332 | return 0; | |
333 | } | |
334 | #endif /* HAVE_IFALIASREQ */ | |
335 | #endif /* HAVE_NETLINK */ | |
336 | ||
337 | /* get interface flags */ | |
338 | void | |
339 | if_get_flags (struct interface *ifp) | |
340 | { | |
341 | int ret; | |
342 | struct ifreq ifreq; | |
343 | ||
344 | ifreq_set_name (&ifreq, ifp); | |
345 | ||
346 | ret = if_ioctl (SIOCGIFFLAGS, (caddr_t) &ifreq); | |
347 | if (ret < 0) | |
348 | { | |
6a52d0d1 | 349 | zlog_err("if_ioctl(SIOCGIFFLAGS) failed: %s", safe_strerror(errno)); |
718e3744 | 350 | return; |
351 | } | |
352 | ||
353 | ifp->flags = ifreq.ifr_flags & 0x0000ffff; | |
354 | } | |
355 | ||
356 | /* Set interface flags */ | |
357 | int | |
358 | if_set_flags (struct interface *ifp, unsigned long flags) | |
359 | { | |
360 | int ret; | |
361 | struct ifreq ifreq; | |
362 | ||
d1724b65 | 363 | memset (&ifreq, 0, sizeof(struct ifreq)); |
718e3744 | 364 | ifreq_set_name (&ifreq, ifp); |
365 | ||
366 | ifreq.ifr_flags = ifp->flags; | |
367 | ifreq.ifr_flags |= flags; | |
368 | ||
369 | ret = if_ioctl (SIOCSIFFLAGS, (caddr_t) &ifreq); | |
370 | ||
371 | if (ret < 0) | |
372 | { | |
373 | zlog_info ("can't set interface flags"); | |
374 | return ret; | |
375 | } | |
376 | return 0; | |
377 | } | |
378 | ||
379 | /* Unset interface's flag. */ | |
380 | int | |
381 | if_unset_flags (struct interface *ifp, unsigned long flags) | |
382 | { | |
383 | int ret; | |
384 | struct ifreq ifreq; | |
385 | ||
d1724b65 | 386 | memset (&ifreq, 0, sizeof(struct ifreq)); |
718e3744 | 387 | ifreq_set_name (&ifreq, ifp); |
388 | ||
389 | ifreq.ifr_flags = ifp->flags; | |
390 | ifreq.ifr_flags &= ~flags; | |
391 | ||
392 | ret = if_ioctl (SIOCSIFFLAGS, (caddr_t) &ifreq); | |
393 | ||
394 | if (ret < 0) | |
395 | { | |
396 | zlog_info ("can't unset interface flags"); | |
397 | return ret; | |
398 | } | |
399 | return 0; | |
400 | } | |
401 | ||
402 | #ifdef HAVE_IPV6 | |
403 | ||
404 | #ifdef LINUX_IPV6 | |
405 | #ifndef _LINUX_IN6_H | |
406 | /* linux/include/net/ipv6.h */ | |
407 | struct in6_ifreq | |
408 | { | |
409 | struct in6_addr ifr6_addr; | |
410 | u_int32_t ifr6_prefixlen; | |
411 | int ifr6_ifindex; | |
412 | }; | |
413 | #endif /* _LINUX_IN6_H */ | |
414 | ||
415 | /* Interface's address add/delete functions. */ | |
416 | int | |
417 | if_prefix_add_ipv6 (struct interface *ifp, struct connected *ifc) | |
418 | { | |
419 | int ret; | |
420 | struct prefix_ipv6 *p; | |
421 | struct in6_ifreq ifreq; | |
422 | ||
423 | p = (struct prefix_ipv6 *) ifc->address; | |
424 | ||
425 | memset (&ifreq, 0, sizeof (struct in6_ifreq)); | |
426 | ||
427 | memcpy (&ifreq.ifr6_addr, &p->prefix, sizeof (struct in6_addr)); | |
428 | ifreq.ifr6_ifindex = ifp->ifindex; | |
429 | ifreq.ifr6_prefixlen = p->prefixlen; | |
430 | ||
431 | ret = if_ioctl_ipv6 (SIOCSIFADDR, (caddr_t) &ifreq); | |
432 | ||
433 | return ret; | |
434 | } | |
435 | ||
436 | int | |
437 | if_prefix_delete_ipv6 (struct interface *ifp, struct connected *ifc) | |
438 | { | |
439 | int ret; | |
440 | struct prefix_ipv6 *p; | |
441 | struct in6_ifreq ifreq; | |
442 | ||
443 | p = (struct prefix_ipv6 *) ifc->address; | |
444 | ||
445 | memset (&ifreq, 0, sizeof (struct in6_ifreq)); | |
446 | ||
447 | memcpy (&ifreq.ifr6_addr, &p->prefix, sizeof (struct in6_addr)); | |
448 | ifreq.ifr6_ifindex = ifp->ifindex; | |
449 | ifreq.ifr6_prefixlen = p->prefixlen; | |
450 | ||
451 | ret = if_ioctl_ipv6 (SIOCDIFADDR, (caddr_t) &ifreq); | |
452 | ||
453 | return ret; | |
454 | } | |
455 | #else /* LINUX_IPV6 */ | |
456 | #ifdef HAVE_IN6_ALIASREQ | |
457 | #ifndef ND6_INFINITE_LIFETIME | |
458 | #define ND6_INFINITE_LIFETIME 0xffffffffL | |
459 | #endif /* ND6_INFINITE_LIFETIME */ | |
460 | int | |
461 | if_prefix_add_ipv6 (struct interface *ifp, struct connected *ifc) | |
462 | { | |
463 | int ret; | |
464 | struct in6_aliasreq addreq; | |
465 | struct sockaddr_in6 addr; | |
466 | struct sockaddr_in6 mask; | |
467 | struct prefix_ipv6 *p; | |
468 | ||
469 | p = (struct prefix_ipv6 * ) ifc->address; | |
470 | ||
471 | memset (&addreq, 0, sizeof addreq); | |
472 | strncpy ((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name); | |
473 | ||
474 | memset (&addr, 0, sizeof (struct sockaddr_in6)); | |
475 | addr.sin6_addr = p->prefix; | |
476 | addr.sin6_family = p->family; | |
477 | #ifdef HAVE_SIN_LEN | |
478 | addr.sin6_len = sizeof (struct sockaddr_in6); | |
479 | #endif | |
480 | memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in6)); | |
481 | ||
482 | memset (&mask, 0, sizeof (struct sockaddr_in6)); | |
483 | masklen2ip6 (p->prefixlen, &mask.sin6_addr); | |
484 | mask.sin6_family = p->family; | |
485 | #ifdef HAVE_SIN_LEN | |
486 | mask.sin6_len = sizeof (struct sockaddr_in6); | |
487 | #endif | |
488 | memcpy (&addreq.ifra_prefixmask, &mask, sizeof (struct sockaddr_in6)); | |
0e4f190e | 489 | |
490 | addreq.ifra_lifetime.ia6t_vltime = 0xffffffff; | |
491 | addreq.ifra_lifetime.ia6t_pltime = 0xffffffff; | |
718e3744 | 492 | |
726f9b2b | 493 | #ifdef HAVE_IFRA_LIFETIME |
718e3744 | 494 | addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; |
495 | addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; | |
726f9b2b | 496 | #endif |
718e3744 | 497 | |
498 | ret = if_ioctl_ipv6 (SIOCAIFADDR_IN6, (caddr_t) &addreq); | |
499 | if (ret < 0) | |
500 | return ret; | |
501 | return 0; | |
502 | } | |
503 | ||
504 | int | |
505 | if_prefix_delete_ipv6 (struct interface *ifp, struct connected *ifc) | |
506 | { | |
507 | int ret; | |
508 | struct in6_aliasreq addreq; | |
509 | struct sockaddr_in6 addr; | |
510 | struct sockaddr_in6 mask; | |
511 | struct prefix_ipv6 *p; | |
512 | ||
513 | p = (struct prefix_ipv6 *) ifc->address; | |
514 | ||
515 | memset (&addreq, 0, sizeof addreq); | |
516 | strncpy ((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name); | |
517 | ||
518 | memset (&addr, 0, sizeof (struct sockaddr_in6)); | |
519 | addr.sin6_addr = p->prefix; | |
520 | addr.sin6_family = p->family; | |
521 | #ifdef HAVE_SIN_LEN | |
522 | addr.sin6_len = sizeof (struct sockaddr_in6); | |
523 | #endif | |
524 | memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in6)); | |
525 | ||
526 | memset (&mask, 0, sizeof (struct sockaddr_in6)); | |
527 | masklen2ip6 (p->prefixlen, &mask.sin6_addr); | |
528 | mask.sin6_family = p->family; | |
529 | #ifdef HAVE_SIN_LEN | |
530 | mask.sin6_len = sizeof (struct sockaddr_in6); | |
531 | #endif | |
532 | memcpy (&addreq.ifra_prefixmask, &mask, sizeof (struct sockaddr_in6)); | |
533 | ||
726f9b2b | 534 | #ifdef HAVE_IFRA_LIFETIME |
718e3744 | 535 | addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; |
536 | addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; | |
726f9b2b | 537 | #endif |
718e3744 | 538 | |
539 | ret = if_ioctl_ipv6 (SIOCDIFADDR_IN6, (caddr_t) &addreq); | |
540 | if (ret < 0) | |
541 | return ret; | |
542 | return 0; | |
543 | } | |
544 | #else | |
545 | int | |
546 | if_prefix_add_ipv6 (struct interface *ifp, struct connected *ifc) | |
547 | { | |
548 | return 0; | |
549 | } | |
550 | ||
551 | int | |
552 | if_prefix_delete_ipv6 (struct interface *ifp, struct connected *ifc) | |
553 | { | |
554 | return 0; | |
555 | } | |
556 | #endif /* HAVE_IN6_ALIASREQ */ | |
557 | ||
558 | #endif /* LINUX_IPV6 */ | |
559 | ||
560 | #endif /* HAVE_IPV6 */ |