2 __RCSID("$NetBSD: ipv4.c,v 1.17 2015/08/21 10:39:00 roy Exp $");
5 * dhcpcd - DHCP client daemon
6 * Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 #include <sys/socket.h>
32 #include <sys/types.h>
34 #include <arpa/inet.h>
36 #include <net/route.h>
37 #include <netinet/if_ether.h>
38 #include <netinet/in.h>
53 #include "if-options.h"
58 #define IPV4_LOOPBACK_ROUTE
59 #if defined(__linux__) || (defined(BSD) && defined(RTF_LOCAL))
60 /* Linux has had loopback routes in the local table since 2.2 */
61 #undef IPV4_LOOPBACK_ROUTE
65 inet_ntocidr(struct in_addr address
)
68 uint32_t mask
= htonl(address
.s_addr
);
78 inet_cidrtoaddr(int cidr
, struct in_addr
*addr
)
82 if (cidr
< 1 || cidr
> 32) {
86 ocets
= (cidr
+ 7) / NBBY
;
90 memset(&addr
->s_addr
, 255, (size_t)ocets
- 1);
91 memset((unsigned char *)&addr
->s_addr
+ (ocets
- 1),
92 (256 - (1 << (32 - cidr
) % NBBY
)), 1);
99 ipv4_getnetmask(uint32_t addr
)
108 return ntohl(IN_CLASSA_NET
);
110 return ntohl(IN_CLASSB_NET
);
112 return ntohl(IN_CLASSC_NET
);
118 ipv4_iffindaddr(struct interface
*ifp
,
119 const struct in_addr
*addr
, const struct in_addr
*net
)
121 struct ipv4_state
*state
;
122 struct ipv4_addr
*ap
;
124 state
= IPV4_STATE(ifp
);
126 TAILQ_FOREACH(ap
, &state
->addrs
, next
) {
127 if ((addr
== NULL
|| ap
->addr
.s_addr
== addr
->s_addr
) &&
128 (net
== NULL
|| ap
->net
.s_addr
== net
->s_addr
))
136 ipv4_iffindlladdr(struct interface
*ifp
)
138 struct ipv4_state
*state
;
139 struct ipv4_addr
*ap
;
141 state
= IPV4_STATE(ifp
);
143 TAILQ_FOREACH(ap
, &state
->addrs
, next
) {
144 if (IN_LINKLOCAL(htonl(ap
->addr
.s_addr
)))
152 ipv4_findaddr(struct dhcpcd_ctx
*ctx
, const struct in_addr
*addr
)
154 struct interface
*ifp
;
155 struct ipv4_addr
*ap
;
157 TAILQ_FOREACH(ifp
, ctx
->ifaces
, next
) {
158 ap
= ipv4_iffindaddr(ifp
, addr
, NULL
);
166 ipv4_hasaddr(const struct interface
*ifp
)
168 const struct dhcp_state
*dstate
;
169 const struct ipv4ll_state
*istate
;
171 dstate
= D_CSTATE(ifp
);
172 istate
= IPV4LL_CSTATE(ifp
);
174 dstate
->added
== STATE_ADDED
&&
175 dstate
->addr
.s_addr
!= INADDR_ANY
) ||
176 (istate
&& istate
->addr
.s_addr
!= INADDR_ANY
));
180 ipv4_freeroutes(struct rt_head
*rts
)
190 ipv4_init(struct dhcpcd_ctx
*ctx
)
193 if (ctx
->ipv4_routes
== NULL
) {
194 ctx
->ipv4_routes
= malloc(sizeof(*ctx
->ipv4_routes
));
195 if (ctx
->ipv4_routes
== NULL
)
197 TAILQ_INIT(ctx
->ipv4_routes
);
199 if (ctx
->ipv4_kroutes
== NULL
) {
200 ctx
->ipv4_kroutes
= malloc(sizeof(*ctx
->ipv4_kroutes
));
201 if (ctx
->ipv4_kroutes
== NULL
)
203 TAILQ_INIT(ctx
->ipv4_kroutes
);
209 ipv4_protocol_fd(const struct interface
*ifp
, uint16_t protocol
)
212 if (protocol
== ETHERTYPE_ARP
) {
213 const struct iarp_state
*istate
;
215 istate
= ARP_CSTATE(ifp
);
216 assert(istate
!= NULL
);
219 const struct dhcp_state
*dstate
;
221 dstate
= D_CSTATE(ifp
);
222 assert(dstate
!= NULL
);
223 return dstate
->raw_fd
;
227 /* Interface comparer for working out ordering. */
229 ipv4_ifcmp(const struct interface
*si
, const struct interface
*ti
)
231 const struct dhcp_state
*sis
, *tis
;
241 /* If one has a lease and the other not, it takes precedence. */
242 if (sis
->new && !tis
->new)
244 if (!sis
->new && tis
->new)
246 /* Always prefer proper leases */
247 if (!(sis
->added
& STATE_FAKE
) && (sis
->added
& STATE_FAKE
))
249 if ((sis
->added
& STATE_FAKE
) && !(sis
->added
& STATE_FAKE
))
251 /* If we are either, they neither have a lease, or they both have.
252 * We need to check for IPv4LL and make it non-preferred. */
253 if (sis
->new && tis
->new) {
254 int sill
= (sis
->new->cookie
== htonl(MAGIC_COOKIE
));
255 int till
= (tis
->new->cookie
== htonl(MAGIC_COOKIE
));
265 find_route(struct rt_head
*rts
, const struct rt
*r
, const struct rt
*srt
)
271 TAILQ_FOREACH(rt
, rts
, next
) {
272 if (rt
->dest
.s_addr
== r
->dest
.s_addr
&&
273 #ifdef HAVE_ROUTE_METRIC
274 (srt
|| (r
->iface
== NULL
|| rt
->iface
== NULL
||
275 rt
->iface
->metric
== r
->iface
->metric
)) &&
277 (!srt
|| srt
!= rt
) &&
278 rt
->net
.s_addr
== r
->net
.s_addr
)
285 desc_route(const char *cmd
, const struct rt
*rt
)
287 char addr
[sizeof("000.000.000.000") + 1];
288 struct dhcpcd_ctx
*ctx
= rt
->iface
? rt
->iface
->ctx
: NULL
;
289 const char *ifname
= rt
->iface
? rt
->iface
->name
: NULL
;
291 strlcpy(addr
, inet_ntoa(rt
->dest
), sizeof(addr
));
292 if (rt
->net
.s_addr
== htonl(INADDR_BROADCAST
) &&
293 rt
->gate
.s_addr
== htonl(INADDR_ANY
))
294 logger(ctx
, LOG_INFO
, "%s: %s host route to %s",
296 else if (rt
->net
.s_addr
== htonl(INADDR_BROADCAST
))
297 logger(ctx
, LOG_INFO
, "%s: %s host route to %s via %s",
298 ifname
, cmd
, addr
, inet_ntoa(rt
->gate
));
299 else if (rt
->dest
.s_addr
== htonl(INADDR_ANY
) &&
300 rt
->net
.s_addr
== htonl(INADDR_ANY
) &&
301 rt
->gate
.s_addr
== htonl(INADDR_ANY
))
302 logger(ctx
, LOG_INFO
, "%s: %s default route",
304 else if (rt
->gate
.s_addr
== htonl(INADDR_ANY
))
305 logger(ctx
, LOG_INFO
, "%s: %s route to %s/%d",
306 ifname
, cmd
, addr
, inet_ntocidr(rt
->net
));
307 else if (rt
->dest
.s_addr
== htonl(INADDR_ANY
) &&
308 rt
->net
.s_addr
== htonl(INADDR_ANY
))
309 logger(ctx
, LOG_INFO
, "%s: %s default route via %s",
310 ifname
, cmd
, inet_ntoa(rt
->gate
));
312 logger(ctx
, LOG_INFO
, "%s: %s route to %s/%d via %s",
313 ifname
, cmd
, addr
, inet_ntocidr(rt
->net
),
314 inet_ntoa(rt
->gate
));
318 ipv4_findrt(struct dhcpcd_ctx
*ctx
, const struct rt
*rt
, int flags
)
322 if (ctx
->ipv4_kroutes
== NULL
)
324 TAILQ_FOREACH(r
, ctx
->ipv4_kroutes
, next
) {
325 if (rt
->dest
.s_addr
== r
->dest
.s_addr
&&
326 #ifdef HAVE_ROUTE_METRIC
327 rt
->iface
== r
->iface
&&
328 (!flags
|| rt
->metric
== r
->metric
) &&
330 (!flags
|| rt
->iface
== r
->iface
) &&
332 rt
->net
.s_addr
== r
->net
.s_addr
)
339 ipv4_freerts(struct rt_head
*routes
)
343 while ((rt
= TAILQ_FIRST(routes
))) {
344 TAILQ_REMOVE(routes
, rt
, next
);
349 /* If something other than dhcpcd removes a route,
350 * we need to remove it from our internal table. */
352 ipv4_handlert(struct dhcpcd_ctx
*ctx
, int cmd
, struct rt
*rt
)
356 if (ctx
->ipv4_kroutes
== NULL
)
359 f
= ipv4_findrt(ctx
, rt
, 1);
363 if ((f
= malloc(sizeof(*f
))) == NULL
)
366 TAILQ_INSERT_TAIL(ctx
->ipv4_kroutes
, f
, next
);
371 TAILQ_REMOVE(ctx
->ipv4_kroutes
, f
, next
);
375 /* If we manage the route, remove it */
376 if ((f
= find_route(ctx
->ipv4_routes
, rt
, NULL
))) {
377 desc_route("removing", f
);
378 TAILQ_REMOVE(ctx
->ipv4_routes
, f
, next
);
386 #define n_route(a) nc_route(NULL, a)
387 #define c_route(a, b) nc_route(a, b)
389 nc_route(struct rt
*ort
, struct rt
*nrt
)
393 /* Don't set default routes if not asked to */
394 if (nrt
->dest
.s_addr
== 0 &&
395 nrt
->net
.s_addr
== 0 &&
396 !(nrt
->iface
->options
->options
& DHCPCD_GATEWAY
))
399 desc_route(ort
== NULL
? "adding" : "changing", nrt
);
403 ort
= ipv4_findrt(nrt
->iface
->ctx
, nrt
, 0);
405 ((ort
->flags
& RTF_REJECT
&& nrt
->flags
& RTF_REJECT
) ||
406 (ort
->iface
== nrt
->iface
&&
407 #ifdef HAVE_ROUTE_METRIC
408 ort
->metric
== nrt
->metric
&&
410 ort
->gate
.s_addr
== nrt
->gate
.s_addr
)))
412 if (ort
->mtu
== nrt
->mtu
)
416 } else if (ort
->state
& STATE_FAKE
&& !(nrt
->state
& STATE_FAKE
) &&
417 ort
->iface
== nrt
->iface
&&
418 #ifdef HAVE_ROUTE_METRIC
419 ort
->metric
== nrt
->metric
&&
421 ort
->dest
.s_addr
== nrt
->dest
.s_addr
&&
422 ort
->net
.s_addr
== nrt
->net
.s_addr
&&
423 ort
->gate
.s_addr
== nrt
->gate
.s_addr
)
425 if (ort
->mtu
== nrt
->mtu
)
431 /* BSD can set routes to be cloning routes.
432 * Cloned routes inherit the parent flags.
433 * As such, we need to delete and re-add the route to flush children
434 * to correct the flags. */
435 if (change
&& ort
!= NULL
&& ort
->flags
& RTF_CLONING
)
440 if (if_route(RTM_CHANGE
, nrt
) == 0)
443 logger(nrt
->iface
->ctx
, LOG_ERR
, "if_route (CHG): %m");
446 #ifdef HAVE_ROUTE_METRIC
447 /* With route metrics, we can safely add the new route before
448 * deleting the old route. */
449 if (if_route(RTM_ADD
, nrt
) == 0) {
450 if (ort
&& if_route(RTM_DELETE
, ort
) == -1 && errno
!= ESRCH
)
451 logger(nrt
->iface
->ctx
, LOG_ERR
, "if_route (DEL): %m");
455 /* If the kernel claims the route exists we need to rip out the
457 if (errno
!= EEXIST
|| ort
== NULL
)
461 /* No route metrics, we need to delete the old route before
462 * adding the new one. */
463 if (ort
&& if_route(RTM_DELETE
, ort
) == -1 && errno
!= ESRCH
)
464 logger(nrt
->iface
->ctx
, LOG_ERR
, "if_route (DEL): %m");
465 if (if_route(RTM_ADD
, nrt
) == 0)
467 #ifdef HAVE_ROUTE_METRIC
470 logger(nrt
->iface
->ctx
, LOG_ERR
, "if_route (ADD): %m");
475 d_route(struct rt
*rt
)
479 desc_route("deleting", rt
);
480 retval
= if_route(RTM_DELETE
, rt
);
481 if (retval
!= 0 && errno
!= ENOENT
&& errno
!= ESRCH
)
482 logger(rt
->iface
->ctx
, LOG_ERR
,
483 "%s: if_delroute: %m", rt
->iface
->name
);
487 static struct rt_head
*
488 add_subnet_route(struct rt_head
*rt
, const struct interface
*ifp
)
490 const struct dhcp_state
*s
;
493 if (rt
== NULL
) /* earlier malloc failed */
497 /* Don't create a subnet route for these addresses */
498 if (s
->net
.s_addr
== INADDR_ANY
)
501 /* BSD adds a route in this instance */
502 if (s
->net
.s_addr
== INADDR_BROADCAST
)
506 if ((r
= calloc(1, sizeof(*r
))) == NULL
) {
507 logger(ifp
->ctx
, LOG_ERR
, "%s: %m", __func__
);
511 r
->dest
.s_addr
= s
->addr
.s_addr
& s
->net
.s_addr
;
512 r
->net
.s_addr
= s
->net
.s_addr
;
513 r
->gate
.s_addr
= INADDR_ANY
;
514 r
->mtu
= dhcp_get_mtu(ifp
);
517 TAILQ_INSERT_HEAD(rt
, r
, next
);
521 #ifdef IPV4_LOOPBACK_ROUTE
522 static struct rt_head
*
523 add_loopback_route(struct rt_head
*rt
, const struct interface
*ifp
)
526 const struct dhcp_state
*s
;
528 if (rt
== NULL
) /* earlier malloc failed */
532 if (s
->addr
.s_addr
== INADDR_ANY
)
535 if ((r
= calloc(1, sizeof(*r
))) == NULL
) {
536 logger(ifp
->ctx
, LOG_ERR
, "%s: %m", __func__
);
541 r
->net
.s_addr
= INADDR_BROADCAST
;
542 r
->gate
.s_addr
= htonl(INADDR_LOOPBACK
);
543 r
->mtu
= dhcp_get_mtu(ifp
);
545 TAILQ_INSERT_HEAD(rt
, r
, next
);
550 static struct rt_head
*
551 get_routes(struct interface
*ifp
)
554 struct rt
*rt
, *r
= NULL
;
555 const struct dhcp_state
*state
;
557 if (ifp
->options
->routes
&& TAILQ_FIRST(ifp
->options
->routes
)) {
558 if ((nrt
= malloc(sizeof(*nrt
))) == NULL
)
561 TAILQ_FOREACH(rt
, ifp
->options
->routes
, next
) {
562 if (rt
->gate
.s_addr
== 0)
564 if ((r
= calloc(1, sizeof(*r
))) == NULL
) {
565 logger(ifp
->ctx
, LOG_ERR
, "%s: %m", __func__
);
566 ipv4_freeroutes(nrt
);
569 memcpy(r
, rt
, sizeof(*r
));
570 TAILQ_INSERT_TAIL(nrt
, r
, next
);
573 nrt
= dhcp_get_routes(ifp
);
575 /* Copy our address as the source address */
577 state
= D_CSTATE(ifp
);
578 TAILQ_FOREACH(rt
, nrt
, next
) {
579 rt
->src
= state
->addr
;
586 static struct rt_head
*
587 add_destination_route(struct rt_head
*rt
, const struct interface
*ifp
)
590 const struct dhcp_state
*state
;
592 if (rt
== NULL
|| /* failed a malloc earlier probably */
593 !(ifp
->flags
& IFF_POINTOPOINT
) ||
594 !has_option_mask(ifp
->options
->dstmask
, DHO_ROUTER
) ||
595 (state
= D_CSTATE(ifp
)) == NULL
)
598 if ((r
= calloc(1, sizeof(*r
))) == NULL
) {
599 logger(ifp
->ctx
, LOG_ERR
, "%s: %m", __func__
);
603 r
->dest
.s_addr
= INADDR_ANY
;
604 r
->net
.s_addr
= INADDR_ANY
;
605 r
->gate
.s_addr
= state
->dst
.s_addr
;
606 r
->mtu
= dhcp_get_mtu(ifp
);
607 r
->src
= state
->addr
;
608 TAILQ_INSERT_HEAD(rt
, r
, next
);
612 /* We should check to ensure the routers are on the same subnet
613 * OR supply a host route. If not, warn and add a host route. */
614 static struct rt_head
*
615 add_router_host_route(struct rt_head
*rt
, const struct interface
*ifp
)
617 struct rt
*rtp
, *rtn
;
618 const char *cp
, *cp2
, *cp3
, *cplim
;
619 struct if_options
*ifo
;
620 const struct dhcp_state
*state
;
622 if (rt
== NULL
) /* earlier malloc failed */
625 TAILQ_FOREACH(rtp
, rt
, next
) {
626 if (rtp
->dest
.s_addr
!= INADDR_ANY
)
628 /* Scan for a route to match */
629 TAILQ_FOREACH(rtn
, rt
, next
) {
633 if (rtn
->dest
.s_addr
== rtp
->gate
.s_addr
)
636 cp
= (const char *)&rtp
->gate
.s_addr
;
637 cp2
= (const char *)&rtn
->dest
.s_addr
;
638 cp3
= (const char *)&rtn
->net
.s_addr
;
639 cplim
= cp3
+ sizeof(rtn
->net
.s_addr
);
640 while (cp3
< cplim
) {
641 if ((*cp
++ ^ *cp2
++) & *cp3
++)
649 if ((state
= D_CSTATE(ifp
)) == NULL
)
652 if (ifp
->flags
& IFF_NOARP
) {
653 if (!(ifo
->options
& DHCPCD_ROUTER_HOST_ROUTE_WARNED
) &&
654 !(state
->added
& STATE_FAKE
))
656 ifo
->options
|= DHCPCD_ROUTER_HOST_ROUTE_WARNED
;
657 logger(ifp
->ctx
, LOG_WARNING
,
658 "%s: forcing router %s through interface",
659 ifp
->name
, inet_ntoa(rtp
->gate
));
661 rtp
->gate
.s_addr
= 0;
664 if (!(ifo
->options
& DHCPCD_ROUTER_HOST_ROUTE_WARNED
) &&
665 !(state
->added
& STATE_FAKE
))
667 ifo
->options
|= DHCPCD_ROUTER_HOST_ROUTE_WARNED
;
668 logger(ifp
->ctx
, LOG_WARNING
,
669 "%s: router %s requires a host route",
670 ifp
->name
, inet_ntoa(rtp
->gate
));
672 if ((rtn
= calloc(1, sizeof(*rtn
))) == NULL
) {
673 logger(ifp
->ctx
, LOG_ERR
, "%s: %m", __func__
);
677 rtn
->dest
.s_addr
= rtp
->gate
.s_addr
;
678 rtn
->net
.s_addr
= htonl(INADDR_BROADCAST
);
679 rtn
->gate
.s_addr
= htonl(INADDR_ANY
);
680 rtn
->mtu
= dhcp_get_mtu(ifp
);
681 rtn
->src
= state
->addr
;
682 TAILQ_INSERT_BEFORE(rtp
, rtn
, next
);
688 ipv4_doroute(struct rt
*rt
, struct rt_head
*nrs
)
690 const struct dhcp_state
*state
;
693 state
= D_CSTATE(rt
->iface
);
694 rt
->state
= state
->added
& STATE_FAKE
;
695 #ifdef HAVE_ROUTE_METRIC
696 rt
->metric
= rt
->iface
->metric
;
698 /* Is this route already in our table? */
699 if ((find_route(nrs
, rt
, NULL
)) != NULL
)
701 /* Do we already manage it? */
702 if ((or = find_route(rt
->iface
->ctx
->ipv4_routes
, rt
, NULL
))) {
703 if (state
->added
& STATE_FAKE
)
705 if (or->state
& STATE_FAKE
||
706 or->iface
!= rt
->iface
||
707 #ifdef HAVE_ROUTE_METRIC
708 rt
->metric
!= or->metric
||
710 rt
->src
.s_addr
!= or->src
.s_addr
||
711 rt
->gate
.s_addr
!= or->gate
.s_addr
||
714 if (c_route(or, rt
) != 0)
717 TAILQ_REMOVE(rt
->iface
->ctx
->ipv4_routes
, or, next
);
720 if (state
->added
& STATE_FAKE
) {
721 if ((or = ipv4_findrt(rt
->iface
->ctx
, rt
, 1)) == NULL
)
723 rt
->iface
= or->iface
;
724 rt
->gate
.s_addr
= or->gate
.s_addr
;
725 #ifdef HAVE_ROUTE_METRIC
726 rt
->metric
= or->metric
;
729 rt
->flags
= or->flags
;
731 if (n_route(rt
) != 0)
739 ipv4_buildroutes(struct dhcpcd_ctx
*ctx
)
741 struct rt_head
*nrs
, *dnr
;
743 struct interface
*ifp
;
744 const struct dhcp_state
*state
;
747 /* We need to have the interfaces in the correct order to ensure
748 * our routes are managed correctly. */
749 if_sortinterfaces(ctx
);
751 if ((nrs
= malloc(sizeof(*nrs
))) == NULL
) {
752 logger(ctx
, LOG_ERR
, "%s: %m", __func__
);
758 TAILQ_FOREACH(ifp
, ctx
->ifaces
, next
) {
759 state
= D_CSTATE(ifp
);
760 if (state
!= NULL
&& state
->new != NULL
&& state
->added
) {
761 dnr
= get_routes(ifp
);
762 dnr
= add_subnet_route(dnr
, ifp
);
765 if ((rt
= ipv4ll_subnet_route(ifp
)) != NULL
) {
767 if ((dnr
= malloc(sizeof(*dnr
))) == NULL
) {
768 logger(ifp
->ctx
, LOG_ERR
,
769 "%s: malloc %m", __func__
);
774 TAILQ_INSERT_HEAD(dnr
, rt
, next
);
778 #ifdef IPV4_LOOPBACK_ROUTE
779 dnr
= add_loopback_route(dnr
, ifp
);
781 if (ifp
->options
->options
& DHCPCD_GATEWAY
) {
782 dnr
= add_router_host_route(dnr
, ifp
);
783 dnr
= add_destination_route(dnr
, ifp
);
787 TAILQ_FOREACH_SAFE(rt
, dnr
, next
, rtn
) {
789 if (ipv4_doroute(rt
, nrs
) == 1) {
790 TAILQ_REMOVE(dnr
, rt
, next
);
791 TAILQ_INSERT_TAIL(nrs
, rt
, next
);
792 if (rt
->dest
.s_addr
== INADDR_ANY
)
796 ipv4_freeroutes(dnr
);
799 /* If we don't manage a default route, grab one without a
800 * gateway for any IPv4LL enabled interfaces. */
802 TAILQ_FOREACH(ifp
, ctx
->ifaces
, next
) {
803 if ((rt
= ipv4ll_default_route(ifp
)) != NULL
) {
804 if (ipv4_doroute(rt
, nrs
) == 1)
805 TAILQ_INSERT_TAIL(nrs
, rt
, next
);
812 /* Remove old routes we used to manage */
813 if (ctx
->ipv4_routes
) {
814 TAILQ_FOREACH(rt
, ctx
->ipv4_routes
, next
) {
815 if (find_route(nrs
, rt
, NULL
) == NULL
&&
816 (rt
->iface
->options
->options
&
817 (DHCPCD_EXITING
| DHCPCD_PERSISTENT
)) !=
818 (DHCPCD_EXITING
| DHCPCD_PERSISTENT
))
822 ipv4_freeroutes(ctx
->ipv4_routes
);
823 ctx
->ipv4_routes
= nrs
;
827 ipv4_deladdr(struct interface
*ifp
,
828 const struct in_addr
*addr
, const struct in_addr
*net
, int keeparp
)
830 struct dhcp_state
*dstate
;
832 struct ipv4_state
*state
;
833 struct ipv4_addr
*ap
;
834 struct arp_state
*astate
;
836 logger(ifp
->ctx
, LOG_DEBUG
, "%s: deleting IP address %s/%d",
837 ifp
->name
, inet_ntoa(*addr
), inet_ntocidr(*net
));
839 r
= if_deladdress(ifp
, addr
, net
);
840 if (r
== -1 && errno
!= EADDRNOTAVAIL
&& errno
!= ENXIO
&&
842 logger(ifp
->ctx
, LOG_ERR
, "%s: %s: %m", ifp
->name
, __func__
);
844 if (!keeparp
&& (astate
= arp_find(ifp
, addr
)) != NULL
)
847 state
= IPV4_STATE(ifp
);
848 TAILQ_FOREACH(ap
, &state
->addrs
, next
) {
849 if (ap
->addr
.s_addr
== addr
->s_addr
&&
850 ap
->net
.s_addr
== net
->s_addr
)
852 TAILQ_REMOVE(&state
->addrs
, ap
, next
);
858 /* Have to do this last incase the function arguments
859 * were these very pointers. */
860 dstate
= D_STATE(ifp
);
862 dstate
->addr
.s_addr
== addr
->s_addr
&&
863 dstate
->net
.s_addr
== net
->s_addr
)
866 dstate
->addr
.s_addr
= 0;
867 dstate
->net
.s_addr
= 0;
873 delete_address(struct interface
*ifp
)
876 struct if_options
*ifo
;
877 struct dhcp_state
*state
;
879 state
= D_STATE(ifp
);
881 if (ifo
->options
& DHCPCD_INFORM
||
882 (ifo
->options
& DHCPCD_STATIC
&& ifo
->req_addr
.s_addr
== 0))
884 r
= ipv4_deladdr(ifp
, &state
->addr
, &state
->net
, 0);
889 ipv4_getstate(struct interface
*ifp
)
891 struct ipv4_state
*state
;
893 state
= IPV4_STATE(ifp
);
895 ifp
->if_data
[IF_DATA_IPV4
] = malloc(sizeof(*state
));
896 state
= IPV4_STATE(ifp
);
898 logger(ifp
->ctx
, LOG_ERR
, "%s: %m", __func__
);
901 TAILQ_INIT(&state
->addrs
);
902 TAILQ_INIT(&state
->routes
);
904 state
->buffer_size
= state
->buffer_len
= state
->buffer_pos
= 0;
905 state
->buffer
= NULL
;
912 ipv4_addaddr(struct interface
*ifp
, const struct in_addr
*addr
,
913 const struct in_addr
*mask
, const struct in_addr
*bcast
)
915 struct ipv4_state
*state
;
916 struct ipv4_addr
*ia
;
918 if ((state
= ipv4_getstate(ifp
)) == NULL
) {
919 logger(ifp
->ctx
, LOG_ERR
, "%s: ipv4_getstate: %m", __func__
);
922 if (ifp
->options
->options
& DHCPCD_NOALIAS
) {
923 struct ipv4_addr
*ian
;
925 TAILQ_FOREACH_SAFE(ia
, &state
->addrs
, next
, ian
) {
926 if (ia
->addr
.s_addr
!= addr
->s_addr
)
927 ipv4_deladdr(ifp
, &ia
->addr
, &ia
->net
, 0);
931 if ((ia
= malloc(sizeof(*ia
))) == NULL
) {
932 logger(ifp
->ctx
, LOG_ERR
, "%s: %m", __func__
);
936 logger(ifp
->ctx
, LOG_DEBUG
, "%s: adding IP address %s/%d",
937 ifp
->name
, inet_ntoa(*addr
), inet_ntocidr(*mask
));
938 if (if_addaddress(ifp
, addr
, mask
, bcast
) == -1) {
940 logger(ifp
->ctx
, LOG_ERR
, "%s: if_addaddress: %m",
949 #ifdef IN_IFF_TENTATIVE
950 ia
->addr_flags
= IN_IFF_TENTATIVE
;
952 TAILQ_INSERT_TAIL(&state
->addrs
, ia
, next
);
957 ipv4_daddaddr(struct interface
*ifp
, const struct dhcp_lease
*lease
)
959 struct dhcp_state
*state
;
961 if (ipv4_addaddr(ifp
, &lease
->addr
, &lease
->net
, &lease
->brd
) == NULL
)
964 state
= D_STATE(ifp
);
965 state
->added
= STATE_ADDED
;
967 state
->addr
.s_addr
= lease
->addr
.s_addr
;
968 state
->net
.s_addr
= lease
->net
.s_addr
;
974 ipv4_preferanother(struct interface
*ifp
)
976 struct dhcp_state
*state
= D_STATE(ifp
), *nstate
;
977 struct interface
*ifn
;
987 TAILQ_FOREACH(ifn
, ifp
->ctx
->ifaces
, next
) {
989 break; /* We are already the most preferred */
990 nstate
= D_STATE(ifn
);
991 if (nstate
&& !nstate
->added
&&
992 nstate
->lease
.addr
.s_addr
== state
->addr
.s_addr
)
996 if (ifn
->options
->options
& DHCPCD_ARP
)
999 ipv4_daddaddr(ifn
, &nstate
->lease
);
1000 nstate
->added
= STATE_ADDED
;
1007 ipv4_buildroutes(ifp
->ctx
);
1012 ipv4_applyaddr(void *arg
)
1014 struct interface
*ifp
= arg
, *ifn
;
1015 struct dhcp_state
*state
= D_STATE(ifp
), *nstate
;
1016 struct dhcp_message
*dhcp
;
1017 struct dhcp_lease
*lease
;
1018 struct if_options
*ifo
= ifp
->options
;
1019 struct ipv4_addr
*ap
;
1025 lease
= &state
->lease
;
1027 if_sortinterfaces(ifp
->ctx
);
1029 if ((ifo
->options
& (DHCPCD_EXITING
| DHCPCD_PERSISTENT
)) !=
1030 (DHCPCD_EXITING
| DHCPCD_PERSISTENT
))
1032 if (state
->added
&& !ipv4_preferanother(ifp
)) {
1033 delete_address(ifp
);
1034 ipv4_buildroutes(ifp
->ctx
);
1036 script_runreason(ifp
, state
->reason
);
1038 ipv4_buildroutes(ifp
->ctx
);
1042 /* Ensure only one interface has the address */
1044 TAILQ_FOREACH(ifn
, ifp
->ctx
->ifaces
, next
) {
1046 r
= 1; /* past ourselves */
1049 nstate
= D_STATE(ifn
);
1050 if (nstate
&& nstate
->added
&&
1051 nstate
->addr
.s_addr
== lease
->addr
.s_addr
)
1054 logger(ifp
->ctx
, LOG_INFO
,
1055 "%s: preferring %s on %s",
1057 inet_ntoa(lease
->addr
),
1061 logger(ifp
->ctx
, LOG_INFO
, "%s: preferring %s on %s",
1063 inet_ntoa(lease
->addr
),
1065 ipv4_deladdr(ifn
, &nstate
->addr
, &nstate
->net
, 0);
1070 /* Does another interface already have the address from a prior boot? */
1072 TAILQ_FOREACH(ifn
, ifp
->ctx
->ifaces
, next
) {
1075 ap
= ipv4_iffindaddr(ifn
, &lease
->addr
, NULL
);
1077 ipv4_deladdr(ifn
, &ap
->addr
, &ap
->net
, 0);
1081 /* If the netmask is different, delete the addresss */
1082 ap
= ipv4_iffindaddr(ifp
, &lease
->addr
, NULL
);
1083 if (ap
&& ap
->net
.s_addr
!= lease
->net
.s_addr
)
1084 ipv4_deladdr(ifp
, &ap
->addr
, &ap
->net
, 0);
1086 if (ipv4_iffindaddr(ifp
, &lease
->addr
, &lease
->net
))
1087 logger(ifp
->ctx
, LOG_DEBUG
,
1088 "%s: IP address %s/%d already exists",
1089 ifp
->name
, inet_ntoa(lease
->addr
),
1090 inet_ntocidr(lease
->net
));
1092 r
= ipv4_daddaddr(ifp
, lease
);
1093 if (r
== -1 && errno
!= EEXIST
)
1097 #ifdef IN_IFF_NOTUSEABLE
1098 ap
= ipv4_iffindaddr(ifp
, &lease
->addr
, NULL
);
1100 logger(ifp
->ctx
, LOG_ERR
, "%s: added address vanished",
1103 } else if (ap
->addr_flags
& IN_IFF_NOTUSEABLE
)
1107 /* Delete the old address if different */
1108 if (state
->addr
.s_addr
!= lease
->addr
.s_addr
&&
1109 state
->addr
.s_addr
!= 0 &&
1110 ipv4_iffindaddr(ifp
, &lease
->addr
, NULL
))
1111 delete_address(ifp
);
1113 state
->added
= STATE_ADDED
;
1114 state
->addr
.s_addr
= lease
->addr
.s_addr
;
1115 state
->net
.s_addr
= lease
->net
.s_addr
;
1117 /* Find any freshly added routes, such as the subnet route.
1118 * We do this because we cannot rely on recieving the kernel
1119 * notification right now via our link socket. */
1121 ipv4_buildroutes(ifp
->ctx
);
1122 script_runreason(ifp
, state
->reason
);
1124 dhcpcd_daemonise(ifp
->ctx
);
1128 ipv4_handleifa(struct dhcpcd_ctx
*ctx
,
1129 int cmd
, struct if_head
*ifs
, const char *ifname
,
1130 const struct in_addr
*addr
, const struct in_addr
*net
,
1131 const struct in_addr
*dst
, int flags
)
1133 struct interface
*ifp
;
1134 struct ipv4_state
*state
;
1135 struct ipv4_addr
*ap
;
1143 if (addr
->s_addr
== INADDR_ANY
) {
1147 if ((ifp
= if_find(ifs
, ifname
)) == NULL
)
1149 if ((state
= ipv4_getstate(ifp
)) == NULL
) {
1154 ap
= ipv4_iffindaddr(ifp
, addr
, net
);
1155 if (cmd
== RTM_NEWADDR
) {
1157 if ((ap
= malloc(sizeof(*ap
))) == NULL
) {
1158 logger(ifp
->ctx
, LOG_ERR
, "%s: %m", __func__
);
1165 ap
->dst
.s_addr
= dst
->s_addr
;
1167 ap
->dst
.s_addr
= INADDR_ANY
;
1168 TAILQ_INSERT_TAIL(&state
->addrs
, ap
, next
);
1170 ap
->addr_flags
= flags
;
1171 } else if (cmd
== RTM_DELADDR
) {
1173 TAILQ_REMOVE(&state
->addrs
, ap
, next
);
1178 dhcp_handleifa(cmd
, ifp
, addr
, net
, dst
, flags
);
1179 arp_handleifa(cmd
, ifp
, addr
, flags
);
1183 ipv4_free(struct interface
*ifp
)
1185 struct ipv4_state
*state
;
1186 struct ipv4_addr
*addr
;
1189 state
= IPV4_STATE(ifp
);
1191 while ((addr
= TAILQ_FIRST(&state
->addrs
))) {
1192 TAILQ_REMOVE(&state
->addrs
, addr
, next
);
1195 ipv4_freerts(&state
->routes
);
1197 free(state
->buffer
);
1205 ipv4_ctxfree(struct dhcpcd_ctx
*ctx
)
1208 ipv4_freeroutes(ctx
->ipv4_routes
);
1209 ipv4_freeroutes(ctx
->ipv4_kroutes
);