if_address6 works.
Use a pointer to the ipv4_addr for the address we added for dhcp and ipv4ll
states.
This is quite some churn throughout the IPv4 stack, but makes the
binary smaller (at least on Linux/amd64).
It will be needed to support adding addresses on Solaris.
}
void
-arp_handleifa(int cmd, struct interface *ifp, const struct in_addr *addr,
- int flags)
+arp_handleifa(int cmd, struct ipv4_addr *addr)
{
#ifdef IN_IFF_DUPLICATED
struct iarp_state *state;
return;
TAILQ_FOREACH_SAFE(astate, &state->arp_states, next, asn) {
- if (astate->addr.s_addr == addr->s_addr) {
+ if (astate->addr.s_addr == addr->addr.s_addr) {
if (flags & IN_IFF_DUPLICATED) {
if (astate->conflicted_cb)
astate->conflicted_cb(astate, NULL);
}
#else
UNUSED(cmd);
- UNUSED(ifp);
UNUSED(addr);
- UNUSED(flags);
#endif
}
#define DEFEND_INTERVAL 10
#include "dhcpcd.h"
+#include "if.h"
struct arp_msg {
uint16_t op;
struct arp_state *arp_find(struct interface *, const struct in_addr *);
void arp_close(struct interface *);
-void arp_handleifa(int, struct interface *, const struct in_addr *, int);
+void arp_handleifa(int, struct ipv4_addr *);
#else
#define arp_close(a) {}
#endif
return -1;
*bootpm = bootp;
- if ((type == DHCP_INFORM || type == DHCP_RELEASE ||
- (type == DHCP_REQUEST && state->mask.s_addr == lease->mask.s_addr &&
+ if (state->addr != NULL &&
+ (type == DHCP_INFORM || type == DHCP_RELEASE ||
+ (type == DHCP_REQUEST &&
+ state->addr->mask.s_addr == lease->mask.s_addr &&
(state->new == NULL || IS_DHCP(state->new)))))
- {
- /* In-case we haven't actually configured the address yet */
- if (type == DHCP_INFORM && state->addr.s_addr == 0)
- bootp->ciaddr = lease->addr.s_addr;
- else
- bootp->ciaddr = state->addr.s_addr;
- }
+ bootp->ciaddr = state->addr->addr.s_addr;
bootp->op = BOOTREQUEST;
bootp->htype = (uint8_t)ifp->family;
if (lease->addr.s_addr && lease->cookie == htonl(MAGIC_COOKIE)) {
if (type == DHCP_DECLINE ||
(type == DHCP_REQUEST &&
- lease->addr.s_addr != state->addr.s_addr))
+ state->addr != NULL &&
+ lease->addr.s_addr != state->addr->addr.s_addr))
{
PUT_ADDR(DHO_IPADDRESS, &lease->addr);
if (lease->server.s_addr)
sin.sin_port = htons(BOOTPC);
if (ifp) {
state = D_STATE(ifp);
- sin.sin_addr.s_addr = state->addr.s_addr;
- } else
- state = NULL; /* appease gcc */
+ if (state->addr)
+ sin.sin_addr.s_addr = state->addr->addr.s_addr;
+ }
if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1)
goto eexit;
size_t len;
ssize_t r;
struct in_addr from, to;
- in_addr_t a = INADDR_ANY;
+ struct ipv4_addr *iap;
struct timespec tv;
int s;
#ifdef IN_IFF_NOTUSEABLE
if (dhcp_open(ifp) == -1)
return;
+ iap = state->addr;
if (state->added && !(state->added & STATE_FAKE) &&
- state->addr.s_addr != INADDR_ANY &&
- state->new != NULL &&
+ state->addr != NULL && state->new != NULL &&
#ifdef IN_IFF_NOTUSEABLE
- ((ia = ipv4_iffindaddr(ifp, &state->addr, NULL)) &&
+ ((ia = ipv4_iffindaddr(ifp, &state->addr->addr, NULL)) &&
!(ia->addr_flags & IN_IFF_NOTUSEABLE)) &&
#endif
(state->lease.server.s_addr ||
logger(ifp->ctx, LOG_ERR,
"%s: dhcp_openudp: %m", ifp->name);
/* We cannot renew */
- a = state->addr.s_addr;
- state->addr.s_addr = INADDR_ANY;
+ state->addr = NULL;
}
}
r = make_message(&bootp, ifp, type);
- if (a != INADDR_ANY)
- state->addr.s_addr = a;
+ state->addr = iap;
if (r == -1)
goto fail;
len = (size_t)r;
!state->lease.frominfo)
dhcp_decline(ifp);
#ifdef IN_IFF_DUPLICATED
- ia = ipv4_iffindaddr(ifp, &astate->addr, NULL);
+ ia = ipv4_iffindaddr(ifp, &astate->addr->addr, NULL);
if (ia)
- ipv4_deladdr(ifp, &ia->addr, &ia->mask, 1);
+ ipv4_deladdr(ia->addr, 1);
#endif
arp_free(astate);
eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
}
/* Bound address */
- if (amsg &&
- (amsg->sip.s_addr == state->addr.s_addr ||
- (amsg->sip.s_addr == 0 && amsg->tip.s_addr == state->addr.s_addr)))
+ if (amsg && state->addr &&
+ (amsg->sip.s_addr == state->addr->addr.s_addr ||
+ (amsg->sip.s_addr == 0 &&
+ amsg->tip.s_addr == state->addr->addr.s_addr)))
{
- astate->failed = state->addr;
+ astate->failed = state->addr->addr;
arp_report_conflicted(astate, amsg);
if (state->state == DHS_BOUND) {
/* For now, just report the duplicated address */
ifp->name, lease->renewaltime);
}
logger(ifp->ctx,
- lease->addr.s_addr == state->addr.s_addr &&
+ state->addr &&
+ lease->addr.s_addr == state->addr->addr.s_addr &&
!(state->added & STATE_FAKE) ?
LOG_DEBUG : LOG_INFO,
"%s: leased %s for %"PRIu32" seconds", ifp->name,
ia = ipv4_iffindaddr(ifp, &ifo->req_addr, NULL);
if (ia != NULL)
/* Netmask must be different, delete it. */
- ipv4_deladdr(ifp, &ia->addr, &ia->mask, 1);
+ ipv4_deladdr(ia, 1);
state->offer_len = dhcp_message_new(&state->offer,
&ifo->req_addr, &ifo->req_mask);
if (dhcp_arp_address(ifp) == 0)
}
}
- state->offer_len = dhcp_message_new(&state->offer, &ia->addr, &ia->mask);
+ state->addr = ia;
+ state->offer_len = dhcp_message_new(&state->offer,
+ &ia->addr, &ia->mask);
if (state->offer_len) {
state->xid = dhcp_xid(ifp);
get_lease(ifp, &state->lease, state->offer, state->offer_len);
return;
ifo = ifp->options;
if ((ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC) &&
- state->addr.s_addr != ifo->req_addr.s_addr) ||
+ (state->addr == NULL ||
+ state->addr->addr.s_addr != ifo->req_addr.s_addr)) ||
(oldopts & (DHCPCD_INFORM | DHCPCD_STATIC) &&
!(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC))))
{
ifp->name, inet_ntoa(from));
return;
}
- if (ifp->flags & IFF_POINTOPOINT && state->brd.s_addr != from.s_addr) {
+ if (ifp->flags & IFF_POINTOPOINT &&
+ (state->addr == NULL || state->addr->brd.s_addr != from.s_addr))
+ {
logger(ifp->ctx, LOG_WARNING,
"%s: server %s is not destination",
ifp->name, inet_ntoa(from));
}
}
if (state->offer) {
+ struct ipv4_addr *ia;
+
get_lease(ifp, &state->lease, state->offer, state->offer_len);
state->lease.frominfo = 1;
if (state->new == NULL &&
- ipv4_iffindaddr(ifp,
- &state->lease.addr, &state->lease.mask))
+ (ia = ipv4_iffindaddr(ifp,
+ &state->lease.addr, &state->lease.mask)) != NULL)
{
/* We still have the IP address from the last lease.
* Fake add the address and routes from it so the lease
if (state->new) {
memcpy(state->new,
state->offer, state->offer_len);
- state->addr = state->lease.addr;
- state->mask = state->lease.mask;
+ state->new_len = state->offer_len;
+ state->addr = ia;
state->added |= STATE_ADDED | STATE_FAKE;
ipv4_buildroutes(ifp->ctx);
} else
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
}
if (!IS_DHCP(state->offer)) {
- if (state->offer->yiaddr == state->addr.s_addr) {
- free(state->offer);
- state->offer = NULL;
- state->offer_len = 0;
- }
+ free(state->offer);
+ state->offer = NULL;
+ state->offer_len = 0;
} else if (!(ifo->options & DHCPCD_LASTLEASE_EXTEND) &&
state->lease.leasetime != ~0U &&
stat(state->leasefile, &st) == 0)
}
void
-dhcp_handleifa(int cmd, struct interface *ifp,
- const struct in_addr *addr,
- const struct in_addr *mask,
- const struct in_addr *brd,
- int flags)
+dhcp_handleifa(int cmd, struct ipv4_addr *ia)
{
+ struct interface *ifp;
struct dhcp_state *state;
struct if_options *ifo;
uint8_t i;
+ ifp = ia->iface;
state = D_STATE(ifp);
if (state == NULL)
return;
if (cmd == RTM_DELADDR) {
- if (state->addr.s_addr == addr->s_addr &&
- state->mask.s_addr == mask->s_addr &&
- state->brd.s_addr == brd->s_addr)
- {
+ if (IPV4_BRD_EQ(state->addr, ia)) {
logger(ifp->ctx, LOG_INFO,
- "%s: removing IP address %s/%d",
- ifp->name, inet_ntoa(state->addr),
- inet_ntocidr(state->mask));
+ "%s: removing IP address %s", ifp->name, ia->saddr);
dhcp_drop(ifp, "EXPIRE");
}
return;
return;
#ifdef IN_IFF_NOTUSEABLE
- if (flags & IN_IFF_NOTUSEABLE)
+ if (ia->flags & IN_IFF_NOTUSEABLE)
return;
-#else
- UNUSED(flags);
#endif
ifo = ifp->options;
free(state->old);
state->old = state->new;
- state->new_len = dhcp_message_new(&state->new, addr, mask);
+ state->new_len = dhcp_message_new(&state->new, &ia->addr, &ia->mask);
if (state->new == NULL)
return;
- state->brd = *brd;
if (ifp->flags & IFF_POINTOPOINT) {
for (i = 1; i < 255; i++)
if (i != DHO_ROUTER && has_option_mask(ifo->dstmask,i))
- dhcp_message_add_addr(state->new, i, *brd);
+ dhcp_message_add_addr(state->new, i, ia->brd);
}
state->reason = "STATIC";
ipv4_buildroutes(ifp->ctx);
if (ifo->options & DHCPCD_INFORM) {
state->state = DHS_INFORM;
state->xid = dhcp_xid(ifp);
- state->lease.server = *brd;
- state->addr = *addr;
- state->mask = *mask;
+ state->lease.server.s_addr = INADDR_ANY;
+ state->addr = ia;
dhcp_inform(ifp);
}
}
int socket;
int raw_fd;
- struct in_addr addr;
- struct in_addr mask;
- struct in_addr brd;
+ struct ipv4_addr *addr;
uint8_t added;
char leasefile[sizeof(LEASEFILE) + IF_NAMESIZE + (IF_SSIDLEN * 4)];
ssize_t dhcp_env(char **, const char *, const struct bootp *, size_t,
const struct interface *);
-void dhcp_handleifa(int, struct interface *,
- const struct in_addr *, const struct in_addr *, const struct in_addr *,
- int);
-
+void dhcp_handleifa(int, struct ipv4_addr *);
void dhcp_drop(struct interface *, const char *);
void dhcp_start(struct interface *);
void dhcp_abort(struct interface *);
int
-if_address(const struct interface *ifp, const struct in_addr *address,
- const struct in_addr *netmask, const struct in_addr *broadcast,
- int action)
+if_address(unsigned char cmd, struct ipv4_addr *ia)
{
int r;
struct in_aliasreq ifra;
(var)->sin_len = sizeof(*(var)); \
(var)->sin_addr = *(addr); \
} while (/*CONSTCOND*/0)
- ADDADDR(&ifra.ifra_addr, address);
- ADDADDR(&ifra.ifra_mask, netmask);
- if (action >= 0 && broadcast)
- ADDADDR(&ifra.ifra_broadaddr, broadcast);
+ ADDADDR(&ifra.ifra_addr, &ia->addr);
+ ADDADDR(&ifra.ifra_mask, &ia->mask);
+ if (cmd == RTM_NEWADDR && ia->brd.s_addr != INADDR_ANY)
+ ADDADDR(&ifra.ifra_broadaddr, &ia->brd);
#undef ADDADDR
r = ioctl(ifp->ctx->pf_inet_fd,
- action < 0 ? SIOCDIFADDR : SIOCAIFADDR, &ifra);
+ cmd == RTM_DELADDR ? SIOCDIFADDR : SIOCAIFADDR, &ifra);
return r;
}
return 0;
}
-#ifdef SIOCGIFAFLAG_IN
int
if_addrflags(const struct in_addr *addr, const struct interface *ifp)
{
+#ifdef SIOCGIFAFLAG_IN
struct ifreq ifr;
struct sockaddr_in *sin;
if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFAFLAG_IN, &ifr) == -1)
return -1;
return ifr.ifr_addrflags;
-}
#else
-int
-if_addrflags(__unused const struct in_addr *addr,
- __unused const struct interface *ifp)
-{
-
- errno = ENOTSUP;
- return 0;
+ UNUSED(ia);
+#endif
}
#endif
#endif /* INET */
#endif
int
-if_address6(const struct ipv6_addr *ia, int action)
+if_address6(unsigned char cmd, const struct ipv6_addr *ia)
{
struct in6_aliasreq ifa;
struct in6_addr mask;
priv = (struct priv *)ia->iface->ctx->priv;
return ioctl(priv->pf_inet6_fd,
- action < 0 ? SIOCDIFADDR_IN6 : SIOCAIFADDR_IN6, &ifa);
+ cmd == RTM_DELADDR ? SIOCDIFADDR_IN6 : SIOCAIFADDR_IN6, &ifa);
}
}
int
-if_address(const struct interface *iface,
- const struct in_addr *address, const struct in_addr *netmask,
- const struct in_addr *broadcast, int action)
+if_address(unsigned char cmd, const struct ipv4_addr *addr)
{
struct nlma nlm;
int retval = 0;
memset(&nlm, 0, sizeof(nlm));
nlm.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
nlm.hdr.nlmsg_flags = NLM_F_REQUEST;
- if (action >= 0) {
+ nlm.hdr.nlmsg_type = cmd;
+ if (cmd == RTM_NEWADDR)
nlm.hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
- nlm.hdr.nlmsg_type = RTM_NEWADDR;
- } else
- nlm.hdr.nlmsg_type = RTM_DELADDR;
- nlm.ifa.ifa_index = iface->index;
+ nlm.ifa.ifa_index = addr->iface->index;
nlm.ifa.ifa_family = AF_INET;
- nlm.ifa.ifa_prefixlen = inet_ntocidr(*netmask);
+ nlm.ifa.ifa_prefixlen = inet_ntocidr(addr->mask);
/* This creates the aliased interface */
add_attr_l(&nlm.hdr, sizeof(nlm), IFA_LABEL,
- iface->alias, (unsigned short)(strlen(iface->alias) + 1));
+ addr->iface->alias,
+ (unsigned short)(strlen(addr->iface->alias) + 1));
add_attr_l(&nlm.hdr, sizeof(nlm), IFA_LOCAL,
- &address->s_addr, sizeof(address->s_addr));
- if (action >= 0 && broadcast)
+ &addr->addr.s_addr, sizeof(addr->addr.s_addr));
+ if (cmd == RTM_NEWADDR)
add_attr_l(&nlm.hdr, sizeof(nlm), IFA_BROADCAST,
- &broadcast->s_addr, sizeof(broadcast->s_addr));
+ &addr->brd.s_addr, sizeof(addr->brd.s_addr));
- if (send_netlink(iface->ctx, NULL, NETLINK_ROUTE, &nlm.hdr, NULL) == -1)
+ if (send_netlink(addr->iface->ctx, NULL,
+ NETLINK_ROUTE, &nlm.hdr, NULL) == -1)
retval = -1;
return retval;
}
#ifdef INET6
int
-if_address6(const struct ipv6_addr *ia, int action)
+if_address6(unsigned char cmd, const struct ipv6_addr *ia)
{
struct nlma nlm;
struct ifa_cacheinfo cinfo;
memset(&nlm, 0, sizeof(nlm));
nlm.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
nlm.hdr.nlmsg_flags = NLM_F_REQUEST;
- if (action >= 0) {
+ nlm.hdr.nlmsg_type = cmd;
+ if (cmd == RTM_NEWADDR)
nlm.hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
- nlm.hdr.nlmsg_type = RTM_NEWADDR;
- } else
- nlm.hdr.nlmsg_type = RTM_DELADDR;
nlm.ifa.ifa_index = ia->iface->index;
nlm.ifa.ifa_family = AF_INET6;
#ifdef IPV6_MANAGETEMPADDR
add_attr_l(&nlm.hdr, sizeof(nlm), IFA_LOCAL,
&ia->addr.s6_addr, sizeof(ia->addr.s6_addr));
- if (action >= 0) {
+ if (cmd == RTM_NEWADDR) {
memset(&cinfo, 0, sizeof(cinfo));
cinfo.ifa_prefered = ia->prefix_pltime;
cinfo.ifa_valid = ia->prefix_vltime;
}
int
-if_address(const struct interface *ifp, const struct in_addr *addr,
- const struct in_addr *mask, const struct in_addr *bcast,
- int action)
+if_address(unsigned char cmd, struct ipv4_addr *ia)
{
- UNUSED(ifp);
- UNUSED(addr);
- UNUSED(mask);
- UNUSED(bcast);
- UNUSED(action);
+ UNUSED(cmd);
+ UNUSED(ia);
errno = ENOTSUP;
return -1;
}
int
-if_addrflags(const struct in_addr *addr, const struct interface *ifp)
+if_addrflags(const struct ipv4_addr *ia)
{
- UNUSED(addr);
- UNUSED(ifp);
+ UNUSED(ia);
errno = ENOTSUP;
return -1;
}
#ifdef INET6
int
-if_address6(const struct ipv6_addr *addr, int action)
+if_address6(unsigned char cmd, const struct ipv6_addr *ia)
{
- UNUSED(addr);
+ UNUSED(cmd);
UNUSED(action);
errno = ENOTSUP;
return -1;
}
int
-if_addrflags6(const struct in6_addr *addr, const struct interface *ifp)
+if_addrflags6(const struct ipv6_addr *ia)
{
- UNUSED(addr);
- UNUSED(ifp);
+ UNUSED(ia);
errno = ENOTSUP;
return -1;
}
ssize_t if_readraw(struct interface *, int, void *, size_t, int *);
void if_closeraw(struct interface *, int);
-int if_address(const struct interface *,
- const struct in_addr *, const struct in_addr *,
- const struct in_addr *, int);
-#define if_addaddress(ifp, addr, net, brd) \
- if_address(ifp, addr, net, brd, 1)
-#define if_deladdress(ifp, addr, net) \
- if_address(ifp, addr, net, NULL, -1)
-
+int if_address(unsigned char, const struct ipv4_addr *);
int if_addrflags(const struct in_addr *, const struct interface *);
int if_route(unsigned char, const struct rt *rt);
#define ip6_use_tempaddr(a) (0)
#endif
-int if_address6(const struct ipv6_addr *, int);
-#define if_addaddress6(a) if_address6(a, 1)
-#define if_deladdress6(a) if_address6(a, -1)
-
+int if_address6(unsigned char, const struct ipv6_addr *);
int if_addrflags6(const struct in6_addr *, const struct interface *);
int if_getlifetime6(struct ipv6_addr *);
/* Prefer DHCP source address if matching */
dstate = D_CSTATE(rt->iface);
- if (dstate &&
- rt->mask.s_addr == dstate->mask.s_addr &&
- rt->dest.s_addr == (dstate->addr.s_addr & dstate->mask.s_addr))
+ if (dstate && dstate->addr &&
+ rt->mask.s_addr == dstate->addr->mask.s_addr &&
+ rt->dest.s_addr ==
+ (dstate->addr->addr.s_addr & dstate->addr->mask.s_addr))
{
- *addr = dstate->addr;
+ *addr = dstate->addr->addr;
return 1;
}
/* Then IPv4LL source address if matching */
istate = IPV4LL_CSTATE(rt->iface);
- if (istate &&
- rt->mask.s_addr == inaddr_llmask.s_addr &&
- rt->dest.s_addr == (istate->addr.s_addr & inaddr_llmask.s_addr))
+ if (istate && istate->addr &&
+ rt->mask.s_addr == istate->addr->mask.s_addr &&
+ rt->dest.s_addr ==
+ (istate->addr->addr.s_addr & istate->addr->mask.s_addr))
{
- *addr = istate->addr;
+ *addr = istate->addr->addr;
return 1;
}
/* If neither match, return DHCP then IPv4LL */
- if (dstate) {
- *addr = dstate->addr;
+ if (dstate && dstate->addr) {
+ *addr = dstate->addr->addr;
return 0;
}
- if (istate) {
- *addr = istate->addr;
+ if (istate && istate->addr) {
+ *addr = istate->addr->addr;
return 0;
}
istate = IPV4LL_CSTATE(ifp);
return ((dstate &&
dstate->added == STATE_ADDED &&
- dstate->addr.s_addr != INADDR_ANY) ||
- (istate && istate->addr.s_addr != INADDR_ANY));
+ dstate->addr != NULL) ||
+ (istate && istate->addr));
}
void
static struct rt_head *
add_subnet_route(struct rt_head *rt, const struct interface *ifp)
{
- const struct dhcp_state *s;
+ const struct dhcp_state *state;
struct rt *r;
if (rt == NULL) /* earlier malloc failed */
return NULL;
- s = D_CSTATE(ifp);
+ state = D_CSTATE(ifp);
/* Don't create a subnet route for these addresses */
- if (s->mask.s_addr == INADDR_ANY)
+ if (state->addr->mask.s_addr == INADDR_ANY)
return rt;
#ifndef BSD
/* BSD adds a route in this instance */
- if (s->mask.s_addr == INADDR_BROADCAST)
+ if (state->addr->mask.s_addr == INADDR_BROADCAST)
return rt;
#endif
ipv4_freeroutes(rt);
return NULL;
}
- r->dest.s_addr = s->addr.s_addr & s->mask.s_addr;
- r->mask.s_addr = s->mask.s_addr;
+ r->dest.s_addr = state->addr->addr.s_addr & state->addr->mask.s_addr;
+ r->mask.s_addr = state->addr->mask.s_addr;
r->gate.s_addr = INADDR_ANY;
r->mtu = dhcp_get_mtu(ifp);
- r->src = s->addr;
+ r->src = state->addr->addr;
TAILQ_INSERT_HEAD(rt, r, next);
return rt;
if (nrt) {
state = D_CSTATE(ifp);
TAILQ_FOREACH(rt, nrt, next) {
- rt->src = state->addr;
+ rt->src = state->addr->addr;
}
}
}
r->dest.s_addr = INADDR_ANY;
r->mask.s_addr = INADDR_ANY;
- r->gate.s_addr = state->brd.s_addr;
+ r->gate = state->addr->brd;
r->mtu = dhcp_get_mtu(ifp);
- r->src = state->addr;
+ r->src = state->addr->addr;
TAILQ_INSERT_HEAD(rt, r, next);
return rt;
}
rtn->mask.s_addr = htonl(INADDR_BROADCAST);
rtn->gate.s_addr = htonl(INADDR_ANY);
rtn->mtu = dhcp_get_mtu(ifp);
- rtn->src = state->addr;
+ rtn->src = state->addr->addr;
TAILQ_INSERT_BEFORE(rtp, rtn, next);
}
return rt;
}
int
-ipv4_deladdr(struct interface *ifp,
- const struct in_addr *addr, const struct in_addr *mask, int keeparp)
+ipv4_deladdr(struct ipv4_addr *addr, int keeparp)
{
- struct dhcp_state *dstate;
+ struct interface *ifp;
int r;
struct ipv4_state *state;
struct ipv4_addr *ap;
struct arp_state *astate;
- uint32_t a, n;
- logger(ifp->ctx, LOG_DEBUG,
- "%s: deleting IP address %s/%d",
- ifp->name, inet_ntoa(*addr), inet_ntocidr(*mask));
+ logger(addr->iface->ctx, LOG_DEBUG,
+ "%s: deleting IP address %s", addr->iface->name, addr->saddr);
- r = if_deladdress(ifp, addr, mask);
+ r = if_address(RTM_DELADDR, addr);
if (r == -1 && errno != EADDRNOTAVAIL && errno != ENXIO &&
errno != ENODEV)
- logger(ifp->ctx, LOG_ERR, "%s: %s: %m", ifp->name, __func__);
+ logger(addr->iface->ctx, LOG_ERR, "%s: %s: %m",
+ addr->iface->name, __func__);
- if (!keeparp && (astate = arp_find(ifp, addr)) != NULL)
+ if (!keeparp && (astate = arp_find(addr->iface, &addr->addr)) != NULL)
arp_free(astate);
- a = addr->s_addr;
- n = mask->s_addr;
- state = IPV4_STATE(ifp);
+ state = IPV4_STATE(addr->iface);
TAILQ_FOREACH(ap, &state->addrs, next) {
- if (ap->addr.s_addr == addr->s_addr &&
- ap->mask.s_addr == mask->s_addr)
- {
+ if (IPV4_MASK_EQ(ap, addr)) {
+ struct dhcp_state *dstate;
+
TAILQ_REMOVE(&state->addrs, ap, next);
free(ap);
+
+ dstate = D_STATE(ifp);
+ if (dstate && dstate->addr == ap) {
+ dstate->added = 0;
+ dstate->addr = NULL;
+ }
break;
}
}
- /* Have to do this last incase the function arguments
- * were these very pointers. */
- dstate = D_STATE(ifp);
- if (dstate && dstate->addr.s_addr == a && dstate->mask.s_addr == n) {
- dstate->added = 0;
- dstate->addr.s_addr = 0;
- dstate->mask.s_addr = 0;
- }
return r;
}
if (ifo->options & DHCPCD_INFORM ||
(ifo->options & DHCPCD_STATIC && ifo->req_addr.s_addr == 0))
return 0;
- r = ipv4_deladdr(ifp, &state->addr, &state->mask, 0);
+ r = ipv4_deladdr(state->addr, 0);
return r;
}
{
struct ipv4_state *state;
struct ipv4_addr *ia;
- char bcast_str[INET_ADDRSTRLEN];
if ((state = ipv4_getstate(ifp)) == NULL) {
logger(ifp->ctx, LOG_ERR, "%s: ipv4_getstate: %m", __func__);
TAILQ_FOREACH_SAFE(ia, &state->addrs, next, ian) {
if (ia->addr.s_addr != addr->s_addr)
- ipv4_deladdr(ifp, &ia->addr, &ia->mask, 0);
+ ipv4_deladdr(ia, 0);
}
}
return NULL;
}
- strlcpy(bcast_str, inet_ntoa(*bcast), sizeof(bcast_str));
- logger(ifp->ctx, LOG_DEBUG, "%s: adding IP address %s/%d broadcast %s",
- ifp->name, inet_ntoa(*addr), inet_ntocidr(*mask), bcast_str);
- if (if_addaddress(ifp, addr, mask, bcast) == -1) {
- if (errno != EEXIST)
- logger(ifp->ctx, LOG_ERR, "%s: if_addaddress: %m",
- __func__);
- free(ia);
- return NULL;
- }
-
ia->iface = ifp;
ia->addr = *addr;
ia->mask = *mask;
#ifdef IN_IFF_TENTATIVE
ia->addr_flags = IN_IFF_TENTATIVE;
#endif
+ snprintf(ia->saddr, sizeof(ia->saddr), "%s/%d",
+ inet_ntoa(*addr), inet_ntocidr(*mask));
+ logger(ifp->ctx, LOG_DEBUG, "%s: adding IP address %s broadcast %s",
+ ifp->name, ia->saddr, inet_ntoa(*bcast));
+ if (if_address(RTM_NEWADDR, ia) == -1) {
+ if (errno != EEXIST)
+ logger(ifp->ctx, LOG_ERR, "%s: if_addaddress: %m",
+ __func__);
+ free(ia);
+ return NULL;
+ }
+
TAILQ_INSERT_TAIL(&state->addrs, ia, next);
return ia;
}
ipv4_daddaddr(struct interface *ifp, const struct dhcp_lease *lease)
{
struct dhcp_state *state;
+ struct ipv4_addr *ia;
- if (ipv4_addaddr(ifp, &lease->addr, &lease->mask, &lease->brd) == NULL)
+ ia = ipv4_addaddr(ifp, &lease->addr, &lease->mask, &lease->brd);
+ if (ia == NULL)
return -1;
state = D_STATE(ifp);
state->added = STATE_ADDED;
-
- state->addr.s_addr = lease->addr.s_addr;
- state->mask.s_addr = lease->mask.s_addr;
-
+ state->addr = ia;
return 0;
}
break; /* We are already the most preferred */
nstate = D_STATE(ifn);
if (nstate && !nstate->added &&
- nstate->lease.addr.s_addr == state->addr.s_addr)
+ state->addr != NULL &&
+ nstate->lease.addr.s_addr == state->addr->addr.s_addr)
{
preferred = 1;
delete_address(ifp);
struct dhcp_state *state = D_STATE(ifp), *nstate;
struct dhcp_lease *lease;
struct if_options *ifo = ifp->options;
- struct ipv4_addr *ap;
+ struct ipv4_addr *ia;
int r;
if (state == NULL)
}
nstate = D_STATE(ifn);
if (nstate && nstate->added &&
- nstate->addr.s_addr == lease->addr.s_addr)
+ nstate->addr &&
+ nstate->addr->addr.s_addr == lease->addr.s_addr)
{
if (r == 0) {
logger(ifp->ctx, LOG_INFO,
ifn->name,
inet_ntoa(lease->addr),
ifp->name);
- ipv4_deladdr(ifn, &nstate->addr, &nstate->mask, 0);
+ ipv4_deladdr(nstate->addr, 0);
break;
}
}
TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
if (ifn == ifp)
continue;
- ap = ipv4_iffindaddr(ifn, &lease->addr, NULL);
- if (ap)
- ipv4_deladdr(ifn, &ap->addr, &ap->mask, 0);
+ ia = ipv4_iffindaddr(ifn, &lease->addr, NULL);
+ if (ia != NULL)
+ ipv4_deladdr(ia, 0);
}
}
/* If the netmask or broadcast is different, re-add the addresss */
- ap = ipv4_iffindaddr(ifp, &lease->addr, NULL);
- if (ap &&
- ap->mask.s_addr == lease->mask.s_addr &&
- ap->brd.s_addr == lease->brd.s_addr)
+ ia = ipv4_iffindaddr(ifp, &lease->addr, NULL);
+ if (ia &&
+ ia->mask.s_addr == lease->mask.s_addr &&
+ ia->brd.s_addr == lease->brd.s_addr)
logger(ifp->ctx, LOG_DEBUG,
- "%s: IP address %s/%d already exists",
- ifp->name, inet_ntoa(lease->addr),
- inet_ntocidr(lease->mask));
+ "%s: IP address %s already exists",
+ ifp->name, ia->saddr);
else {
#if __linux__
/* Linux does not change netmask/broadcast address
* for re-added addresses, so we need to delete the old one
* first. */
- if (ap != NULL)
- ipv4_deladdr(ifp, &ap->addr, &ap->mask, 0);
+ if (ia != NULL)
+ ipv4_deladdr(ia, 0);
#endif
r = ipv4_daddaddr(ifp, lease);
if (r == -1 && errno != EEXIST)
return;
}
-#ifdef IN_IFF_NOTUSEABLE
- ap = ipv4_iffindaddr(ifp, &lease->addr, NULL);
- if (ap == NULL) {
+ ia = ipv4_iffindaddr(ifp, &lease->addr, NULL);
+ if (ia == NULL) {
logger(ifp->ctx, LOG_ERR, "%s: added address vanished",
ifp->name);
return;
- } else if (ap->addr_flags & IN_IFF_NOTUSEABLE)
+ }
+#ifdef IN_IFF_NOTUSEABLE
+ if (ia->addr_flags & IN_IFF_NOTUSEABLE)
return;
#endif
/* Delete the old address if different */
- if (state->addr.s_addr != lease->addr.s_addr &&
- state->addr.s_addr != 0 &&
+ if (state->addr &&
+ state->addr->addr.s_addr != lease->addr.s_addr &&
ipv4_iffindaddr(ifp, &lease->addr, NULL))
delete_address(ifp);
+ state->addr = ia;
state->added = STATE_ADDED;
- state->addr.s_addr = lease->addr.s_addr;
- state->mask.s_addr = lease->mask.s_addr;
/* Find any freshly added routes, such as the subnet route.
* We do this because we cannot rely on recieving the kernel
if (ifo->options & DHCPCD_ARP) {
struct arp_state *astate;
- if ((astate = arp_new(ifp, &state->addr)) != NULL)
+ if ((astate = arp_new(ifp, &state->addr->addr)) != NULL)
arp_announce(astate);
}
if (state->state == DHS_BOUND) {
{
struct interface *ifp;
struct ipv4_state *state;
- struct ipv4_addr *ap;
+ struct ipv4_addr *ia;
if (ifs == NULL)
ifs = ctx->ifaces;
return;
}
- ap = ipv4_iffindaddr(ifp, addr, NULL);
- if (cmd == RTM_NEWADDR) {
- if (ap == NULL) {
- if ((ap = malloc(sizeof(*ap))) == NULL) {
+ ia = ipv4_iffindaddr(ifp, addr, NULL);
+ switch (cmd) {
+ case RTM_NEWADDR:
+ if (ia == NULL) {
+ if ((ia = malloc(sizeof(*ia))) == NULL) {
logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
return;
}
- ap->iface = ifp;
- ap->addr = *addr;
- TAILQ_INSERT_TAIL(&state->addrs, ap, next);
+ ia->iface = ifp;
+ ia->addr = *addr;
+ TAILQ_INSERT_TAIL(&state->addrs, ia, next);
}
- ap->mask = *mask;
+ /* Mask could have changed */
+ ia->mask = *mask;
+ snprintf(ia->saddr, sizeof(ia->saddr), "%s/%d",
+ inet_ntoa(*addr), inet_ntocidr(*mask));
if (brd != NULL)
- ap->brd = *brd;
+ ia->brd = *brd;
else
- ap->brd.s_addr = INADDR_ANY;
- ap->addr_flags = flags;
- } else if (cmd == RTM_DELADDR) {
- if (ap) {
- TAILQ_REMOVE(&state->addrs, ap, next);
- free(ap);
- }
+ ia->brd.s_addr = INADDR_ANY;
+ ia->addr_flags = flags;
+ break;
+ case RTM_DELADDR:
+ if (ia == NULL)
+ return;
+ TAILQ_REMOVE(&state->addrs, ia, next);
+ break;
+ default:
+ return;
}
- arp_handleifa(cmd, ifp, addr, flags);
- dhcp_handleifa(cmd, ifp, addr, mask, brd, flags);
+ arp_handleifa(cmd, ia);
+ dhcp_handleifa(cmd, ia);
+
+ if (cmd == RTM_DELADDR)
+ free(ia);
}
void
ipv4_free(struct interface *ifp)
{
struct ipv4_state *state;
- struct ipv4_addr *addr;
+ struct ipv4_addr *ia;
if (ifp) {
state = IPV4_STATE(ifp);
if (state) {
- while ((addr = TAILQ_FIRST(&state->addrs))) {
- TAILQ_REMOVE(&state->addrs, addr, next);
- free(addr);
+ while ((ia = TAILQ_FIRST(&state->addrs))) {
+ TAILQ_REMOVE(&state->addrs, ia, next);
+ free(ia);
}
ipv4_freerts(&state->routes);
#ifdef BSD
struct in_addr brd;
struct interface *iface;
int addr_flags;
+ char saddr[INET_ADDRSTRLEN + 3];
};
TAILQ_HEAD(ipv4_addrhead, ipv4_addr);
+#define IPV4_ADDR_EQ(a1, a2) ((a1) && (a1)->addr.s_addr == (a2)->addr.s_addr)
+#define IPV4_MASK1_EQ(a1, a2) ((a1) && (a1)->mask.s_addr == (a2)->mask.s_addr)
+#define IPV4_MASK_EQ(a1, a2) (IPV4_ADDR_EQ(a1, a2) && IPV4_MASK1_EQ(a1, a2))
+#define IPV4_BRD1_EQ(a1, a2) ((a1) && (a1)->brd.s_addr == (a2)->brd.s_addr)
+#define IPV4_BRD_EQ(a1, a2) (IPV4_MASK_EQ(a1, a2) && IPV4_BRD1_EQ(a1, a2))
+
struct ipv4_state {
struct ipv4_addrhead addrs;
struct rt_head routes;
#define STATE_FAKE 0x02
void ipv4_buildroutes(struct dhcpcd_ctx *);
-int ipv4_deladdr(struct interface *, const struct in_addr *,
- const struct in_addr *, int);
+int ipv4_deladdr(struct ipv4_addr *, int);
int ipv4_preferanother(struct interface *);
struct ipv4_addr *ipv4_addaddr(struct interface *,
const struct in_addr *, const struct in_addr *, const struct in_addr *);
/*
* dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
+ * Copyright (c) 2006-2016 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
#include "ipv4ll.h"
#include "script.h"
-const struct in_addr inaddr_llmask = { HTONL(LINKLOCAL_MASK) };
-const struct in_addr inaddr_llbcast = { HTONL(LINKLOCAL_BRDC) };
+static const struct in_addr inaddr_llmask = { HTONL(LINKLOCAL_MASK) };
+static const struct in_addr inaddr_llbcast = { HTONL(LINKLOCAL_BCAST) };
static in_addr_t
-ipv4ll_pick_addr(const struct arp_state *astate)
+ipv4ll_pickaddr(struct arp_state *astate)
{
struct in_addr addr;
struct ipv4ll_state *istate;
} while (ipv4_findaddr(astate->iface->ctx, &addr) != NULL);
/* Restore the original random state */
- setstate(astate->iface->ctx->randomstate);
-
+ setstate(istate->arp->iface->ctx->randomstate);
return addr.s_addr;
}
assert(ifp != NULL);
if ((state = IPV4LL_CSTATE(ifp)) == NULL ||
- state->addr.s_addr == INADDR_ANY)
+ state->addr == NULL)
return NULL;
if ((rt = calloc(1, sizeof(*rt))) == NULL) {
return NULL;
}
rt->iface = ifp;
- rt->dest.s_addr = state->addr.s_addr & inaddr_llmask.s_addr;
- rt->mask = inaddr_llmask;
+ rt->dest.s_addr = state->addr->addr.s_addr & state->addr->mask.s_addr;
+ rt->mask.s_addr = state->addr->mask.s_addr;
rt->gate.s_addr = INADDR_ANY;
- rt->src = state->addr;
+ rt->src = state->addr->addr;
return rt;
}
assert(ifp != NULL);
if ((state = IPV4LL_CSTATE(ifp)) == NULL ||
- state->addr.s_addr == INADDR_ANY)
+ state->addr == NULL)
return NULL;
if ((rt = calloc(1, sizeof(*rt))) == NULL) {
rt->dest.s_addr = INADDR_ANY;
rt->mask.s_addr = INADDR_ANY;
rt->gate.s_addr = INADDR_ANY;
- rt->src = state->addr;
+ rt->src = state->addr->addr;
return rt;
}
/* Emulate a DHCP environment */
if (asprintf(&env[0], "%s%sip_address=%s",
- prefix, pf, inet_ntoa(state->addr)) == -1)
+ prefix, pf, inet_ntoa(state->addr->addr)) == -1)
return -1;
if (asprintf(&env[1], "%s%ssubnet_mask=%s",
- prefix, pf, inet_ntoa(inaddr_llmask)) == -1)
+ prefix, pf, inet_ntoa(state->addr->mask)) == -1)
return -1;
if (asprintf(&env[2], "%s%ssubnet_cidr=%d",
- prefix, pf, inet_ntocidr(inaddr_llmask)) == -1)
+ prefix, pf, inet_ntocidr(state->addr->mask)) == -1)
return -1;
if (asprintf(&env[3], "%s%sbroadcast_address=%s",
- prefix, pf, inet_ntoa(inaddr_llbcast)) == -1)
+ prefix, pf, inet_ntoa(state->addr->brd)) == -1)
return -1;
- netnum.s_addr = state->addr.s_addr & inaddr_llmask.s_addr;
+ netnum.s_addr = state->addr->addr.s_addr & state->addr->mask.s_addr;
if (asprintf(&env[4], "%s%snetwork_number=%s",
prefix, pf, inet_ntoa(netnum)) == -1)
return -1;
ifp->name, inet_ntoa(astate->addr));
#endif
test:
- state->addr = astate->addr;
+ state->addr = ia;
if (ifp->ctx->options & DHCPCD_TEST) {
script_runreason(ifp, "TEST");
eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS);
ifp = astate->iface;
state = IPV4LL_STATE(ifp);
assert(state != NULL);
+ assert(state->addr != NULL);
fail = 0;
/* RFC 3927 2.2.1, Probe Conflict Detection */
fail = astate->addr.s_addr;
/* RFC 3927 2.5, Conflict Defense */
- if (IN_LINKLOCAL(ntohl(state->addr.s_addr)) &&
- amsg && amsg->sip.s_addr == state->addr.s_addr)
- fail = state->addr.s_addr;
+ if (IN_LINKLOCAL(ntohl(state->addr->addr.s_addr)) &&
+ amsg && amsg->sip.s_addr == state->addr->addr.s_addr)
+ fail = state->addr->addr.s_addr;
if (fail == 0)
return;
astate->failed.s_addr = fail;
arp_report_conflicted(astate, amsg);
- if (astate->failed.s_addr == state->addr.s_addr) {
+ if (astate->failed.s_addr == state->addr->addr.s_addr) {
struct timespec now, defend;
/* RFC 3927 Section 2.5 says a defence should
if (timespeccmp(&defend, &now, >))
logger(ifp->ctx, LOG_WARNING,
"%s: IPv4LL %d second defence failed for %s",
- ifp->name, DEFEND_INTERVAL,
- inet_ntoa(state->addr));
+ ifp->name, DEFEND_INTERVAL, state->addr->saddr);
else if (arp_request(ifp,
- state->addr.s_addr, state->addr.s_addr) == -1)
+ state->addr->addr.s_addr, state->addr->addr.s_addr) == -1)
logger(ifp->ctx, LOG_ERR,
"%s: arp_request: %m", __func__);
else {
logger(ifp->ctx, LOG_DEBUG,
"%s: defended IPv4LL address %s",
- ifp->name, inet_ntoa(state->addr));
+ ifp->name, state->addr->saddr);
state->defend = now;
return;
}
- ipv4_deladdr(ifp, &state->addr, &inaddr_llmask, 1);
+ ipv4_deladdr(state->addr, 1);
state->down = 1;
+ state->addr = NULL;
script_runreason(ifp, "IPV4LL");
- state->addr.s_addr = INADDR_ANY;
}
arp_cancel(astate);
logger(ifp->ctx, LOG_ERR,
"%s: failed to acquire an IPv4LL address",
ifp->name);
- astate->addr.s_addr = ipv4ll_pick_addr(astate);
+ astate->addr.s_addr = ipv4ll_pickaddr(astate);
eloop_timeout_add_sec(ifp->ctx->eloop,
state->conflicts >= MAX_CONFLICTS ?
RATE_LIMIT_INTERVAL : PROBE_WAIT,
syslog(LOG_ERR, "%s: calloc %m", __func__);
return;
}
-
- state->addr.s_addr = INADDR_ANY;
}
if (state->arp != NULL)
return;
}
logger(ifp->ctx, LOG_INFO, "%s: using IPv4LL address %s",
- ifp->name, inet_ntoa(astate->addr));
+ ifp->name, ia->saddr);
#endif
ipv4ll_probed(astate);
return;
logger(ifp->ctx, LOG_INFO, "%s: probing for an IPv4LL address",
ifp->name);
- astate->addr.s_addr = ipv4ll_pick_addr(astate);
+ astate->addr.s_addr = ipv4ll_pickaddr(astate);
#ifdef IN_IFF_TENTATIVE
ipv4ll_probed(astate);
#else
if (drop && (ifp->options->options & DHCPCD_NODROP) != DHCPCD_NODROP) {
struct ipv4_state *istate;
- if (state && state->addr.s_addr != INADDR_ANY) {
- ipv4_deladdr(ifp, &state->addr, &inaddr_llmask, 1);
- state->addr.s_addr = INADDR_ANY;
+ if (state && state->addr != NULL) {
+ ipv4_deladdr(state->addr, 1);
+ state->addr = NULL;
dropped = 1;
}
TAILQ_FOREACH_SAFE(ia, &istate->addrs, next, ian) {
if (IN_LINKLOCAL(ntohl(ia->addr.s_addr))) {
- ipv4_deladdr(ifp, &ia->addr,
- &ia->mask, 0);
+ ipv4_deladdr(ia, 0);
dropped = 1;
}
}
/*
* dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
+ * Copyright (c) 2006-2016 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
#ifdef INET
#include "arp.h"
-extern const struct in_addr inaddr_llmask;
-extern const struct in_addr inaddr_llbcast;
-
#define LINKLOCAL_ADDR 0xa9fe0000
#define LINKLOCAL_MASK IN_CLASSB_NET
-#define LINKLOCAL_BRDC (LINKLOCAL_ADDR | ~LINKLOCAL_MASK)
+#define LINKLOCAL_BCAST (LINKLOCAL_ADDR | ~LINKLOCAL_MASK)
#ifndef IN_LINKLOCAL
# define IN_LINKLOCAL(addr) ((addr & IN_CLASSB_NET) == LINKLOCAL_ADDR)
#endif
struct ipv4ll_state {
- struct in_addr addr;
+ struct ipv4_addr *addr;
struct arp_state *arp;
unsigned int conflicts;
struct timespec defend;
#define IPV4LL_CSTATE(ifp) \
((const struct ipv4ll_state *)(ifp)->if_data[IF_DATA_IPV4LL])
#define IPV4LL_STATE_RUNNING(ifp) \
- (IPV4LL_CSTATE((ifp)) && !IPV4LL_CSTATE((ifp))->down && \
- IN_LINKLOCAL(ntohl(IPV4LL_CSTATE((ifp))->addr.s_addr)))
+ (IPV4LL_CSTATE((ifp)) && !IPV4LL_CSTATE((ifp))->down && \
+ (IPV4LL_CSTATE((ifp))->addr != NULL))
struct rt* ipv4ll_subnet_route(const struct interface *);
struct rt* ipv4ll_default_route(const struct interface *);
logger(ia->iface->ctx, LOG_INFO, "%s: deleting address %s",
ia->iface->name, ia->saddr);
- if (if_deladdress6(ia) == -1 &&
+ if (if_address6(RTM_DELADDR, ia) == -1 &&
errno != EADDRNOTAVAIL && errno != ENXIO && errno != ENODEV)
- logger(ia->iface->ctx, LOG_ERR, "if_deladdress6: :%m");
+ logger(ia->iface->ctx, LOG_ERR, "if_address6: :%m");
/* NOREJECT is set if we delegated exactly the prefix to another
* address.
#endif
}
- if (if_addaddress6(ap) == -1) {
+ if (if_address6(RTM_NEWADDR, ap) == -1) {
logger(ap->iface->ctx, LOG_ERR, "if_addaddress6: %m");
/* Restore real pltime and vltime */
ap->prefix_pltime = pltime;
apf->iface->name,
ap->saddr,
ap->iface->name);
- if (if_deladdress6(apf) == -1 &&
+ if (if_address6(RTM_DELADDR, apf) == -1 &&
errno != EADDRNOTAVAIL && errno != ENXIO)
logger(apf->iface->ctx, LOG_ERR,
- "if_deladdress6: %m");
+ "if_address6: %m");
apf->flags &=
~(IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED);
} else if (apf)
}
logger(ifp->ctx, LOG_INFO, "%s: deleting address %s",
ifp->name, ap->saddr);
- if (if_deladdress6(ap) == -1 &&
+ if (if_address6(RTM_DELADDR, ap) == -1 &&
errno != EADDRNOTAVAIL && errno != ENXIO)
- logger(ifp->ctx, LOG_ERR, "if_deladdress6: %m");
+ logger(ifp->ctx, LOG_ERR, "if_address6: %m");
dadcounter = ap->dadcounter;
if (ipv6_makestableprivate(&ap->addr,
&ap->prefix, ap->prefix_len,
ra = 1;
#endif
#ifdef INET
- else if (istate && istate->addr.s_addr != INADDR_ANY)
+ else if (istate && istate->addr != NULL)
ipv4ll = 1;
else
dhcp = 1;