}
static void
-desc_route(const char *cmd, const struct rt *rt, const char *ifname)
+desc_route(const char *cmd, const struct rt *rt)
{
char addr[sizeof("000.000.000.000") + 1];
+ const char *ifname = rt->iface->name;
strlcpy(addr, inet_ntoa(rt->dest), sizeof(addr));
if (rt->gate.s_addr == INADDR_ANY)
f = find_route(routes, rt, &l, NULL);
if (f == NULL)
return 0;
- desc_route("removing", f, f->iface->name);
+ desc_route("removing", f);
if (l)
l->next = f->next;
else
}
static int
-n_route(struct rt *rt, const struct interface *iface)
+n_route(struct rt *rt)
{
/* Don't set default routes if not asked to */
if (rt->dest.s_addr == 0 &&
rt->net.s_addr == 0 &&
- !(iface->state->options->options & DHCPCD_GATEWAY))
+ !(rt->iface->state->options->options & DHCPCD_GATEWAY))
return -1;
- desc_route("adding", rt, iface->name);
- if (!add_route(iface, &rt->dest, &rt->net, &rt->gate, iface->metric))
+ desc_route("adding", rt);
+ if (!add_route(rt))
return 0;
if (errno == EEXIST) {
/* Pretend we added the subnet route */
- if (rt->dest.s_addr == (iface->addr.s_addr & iface->net.s_addr) &&
- rt->net.s_addr == iface->net.s_addr &&
+ if (rt->dest.s_addr ==
+ (rt->iface->addr.s_addr & rt->iface->net.s_addr) &&
+ rt->net.s_addr == rt->iface->net.s_addr &&
rt->gate.s_addr == 0)
return 0;
else
return -1;
}
- syslog(LOG_ERR, "%s: add_route: %m", iface->name);
+ syslog(LOG_ERR, "%s: add_route: %m", rt->iface->name);
return -1;
}
static int
-c_route(struct rt *ort, struct rt *nrt, const struct interface *iface)
+c_route(struct rt *ort, struct rt *nrt)
{
/* Don't set default routes if not asked to */
if (nrt->dest.s_addr == 0 &&
nrt->net.s_addr == 0 &&
- !(iface->state->options->options & DHCPCD_GATEWAY))
+ !(nrt->iface->state->options->options & DHCPCD_GATEWAY))
return -1;
- desc_route("changing", nrt, iface->name);
+ desc_route("changing", nrt);
/* We delete and add the route so that we can change metric.
* This also has the nice side effect of flushing ARP entries so
* we don't have to do that manually. */
- del_route(ort->iface, &ort->dest, &ort->net, &ort->gate, ort->metric);
- if (!add_route(iface, &nrt->dest, &nrt->net, &nrt->gate, nrt->metric))
+ del_route(ort);
+ if (!add_route(nrt))
return 0;
- syslog(LOG_ERR, "%s: add_route: %m", iface->name);
+ syslog(LOG_ERR, "%s: add_route: %m", nrt->iface->name);
return -1;
}
static int
-d_route(struct rt *rt, const struct interface *iface, int metric)
+d_route(struct rt *rt)
{
int retval;
- desc_route("deleting", rt, iface->name);
- retval = del_route(iface, &rt->dest, &rt->net, &rt->gate, metric);
+ desc_route("deleting", rt);
+ retval = del_route(rt);
if (retval != 0 && errno != ENOENT && errno != ESRCH)
- syslog(LOG_ERR,"%s: del_route: %m", iface->name);
+ syslog(LOG_ERR,"%s: del_route: %m", rt->iface->name);
return retval;
}
rt->gate.s_addr != or->gate.s_addr ||
rt->metric != or->metric)
{
- if (c_route(or, rt, ifp) != 0)
+ if (c_route(or, rt) != 0)
continue;
}
if (rtl != NULL)
routes = or->next;
free(or);
} else {
- if (n_route(rt, ifp) != 0)
+ if (n_route(rt) != 0)
continue;
}
if (dnr == rt)
/* Remove old routes we used to manage */
for (rt = routes; rt; rt = rt->next) {
if (find_route(nrs, rt, NULL, NULL) == NULL)
- d_route(rt, rt->iface, rt->iface->metric);
+ d_route(rt);
}
free_routes(routes);
rt = get_subnet_route(dhcp);
if (rt != NULL) {
rt->iface = iface;
+ rt->metric = 0;
if (!find_route(routes, rt, NULL, NULL))
- del_route(iface, &rt->dest, &rt->net, &rt->gate, 0);
+ del_route(rt);
free(rt);
}
/* ARGSUSED4 */
int
-if_route(const struct interface *iface, const struct in_addr *dest,
- const struct in_addr *net, const struct in_addr *gate,
- _unused int metric, int action)
+if_route(const struct rt *rt, int action)
{
union sockunion {
struct sockaddr sa;
rtm.hdr.rtm_type = RTM_DELETE;
rtm.hdr.rtm_flags = RTF_UP;
/* None interface subnet routes are static. */
- if (gate->s_addr != INADDR_ANY ||
- net->s_addr != iface->net.s_addr ||
- dest->s_addr != (iface->addr.s_addr & iface->net.s_addr))
+ if (rt->gate.s_addr != INADDR_ANY ||
+ rt->net.s_addr != rt->iface->net.s_addr ||
+ rt->dest.s_addr != (rt->iface->addr.s_addr & rt->iface->net.s_addr))
rtm.hdr.rtm_flags |= RTF_STATIC;
rtm.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY;
- if (dest->s_addr == gate->s_addr && net->s_addr == INADDR_BROADCAST)
+ if (rt->dest.s_addr == rt->gate.s_addr &&
+ rt->net.s_addr == INADDR_BROADCAST)
rtm.hdr.rtm_flags |= RTF_HOST;
else {
rtm.hdr.rtm_addrs |= RTA_NETMASK;
rtm.hdr.rtm_addrs |= RTA_IFA;
}
- ADDADDR(dest);
+ ADDADDR(&rt->dest);
if (rtm.hdr.rtm_flags & RTF_HOST ||
!(rtm.hdr.rtm_flags & RTF_STATIC))
{
/* Make us a link layer socket for the host gateway */
memset(&su, 0, sizeof(su));
su.sdl.sdl_len = sizeof(struct sockaddr_dl);
- link_addr(iface->name, &su.sdl);
+ link_addr(rt->iface->name, &su.sdl);
ADDSU(su);
} else
- ADDADDR(gate);
+ ADDADDR(&rt->gate);
if (rtm.hdr.rtm_addrs & RTA_NETMASK)
- ADDADDR(net);
+ ADDADDR(&rt->net);
if (rtm.hdr.rtm_addrs & RTA_IFA)
- ADDADDR(&iface->addr);
+ ADDADDR(&rt->iface->addr);
rtm.hdr.rtm_msglen = l = bp - (char *)&rtm;
if (write(r_fd, &rtm, l) == -1)
}
int
-if_route(const struct interface *iface,
- const struct in_addr *destination, const struct in_addr *netmask,
- const struct in_addr *gateway, int metric, int action)
+if_route(const struct rt *rt, int action)
{
struct nlmr *nlm;
unsigned int ifindex;
int retval = 0;
- if (!(ifindex = if_nametoindex(iface->name))) {
+ if (!(ifindex = if_nametoindex(rt->iface->name))) {
errno = ENODEV;
return -1;
}
else {
nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
/* We only change route metrics for kernel routes */
- if (destination->s_addr ==
- (iface->addr.s_addr & iface->net.s_addr) &&
- netmask->s_addr == iface->net.s_addr)
+ if (rt->dest.s_addr ==
+ (rt->iface->addr.s_addr & rt->iface->net.s_addr) &&
+ rt->net.s_addr == rt->iface->net.s_addr)
nlm->rt.rtm_protocol = RTPROT_KERNEL;
else
nlm->rt.rtm_protocol = RTPROT_BOOT;
- if (gateway->s_addr == INADDR_ANY ||
- (gateway->s_addr == destination->s_addr &&
- netmask->s_addr == INADDR_BROADCAST))
+ if (rt->gate.s_addr == INADDR_ANY ||
+ (rt->gate.s_addr == rt->dest.s_addr &&
+ rt->net.s_addr == INADDR_BROADCAST))
nlm->rt.rtm_scope = RT_SCOPE_LINK;
else
nlm->rt.rtm_scope = RT_SCOPE_UNIVERSE;
nlm->rt.rtm_type = RTN_UNICAST;
}
- nlm->rt.rtm_dst_len = inet_ntocidr(*netmask);
+ nlm->rt.rtm_dst_len = inet_ntocidr(&rt->net);
add_attr_l(&nlm->hdr, sizeof(*nlm), RTA_DST,
- &destination->s_addr, sizeof(destination->s_addr));
+ &rt->dest.s_addr, sizeof(rt->dest.s_addr));
if (nlm->rt.rtm_protocol == RTPROT_KERNEL) {
add_attr_l(&nlm->hdr, sizeof(*nlm), RTA_PREFSRC,
- &iface->addr.s_addr, sizeof(iface->addr.s_addr));
+ &rt->iface->addr.s_addr, sizeof(rt->iface->addr.s_addr));
}
/* If destination == gateway then don't add the gateway */
- if (destination->s_addr != gateway->s_addr ||
- netmask->s_addr != INADDR_BROADCAST)
+ if (rt->dest.s_addr != rt->gate.s_addr ||
+ rt->net.s_addr != INADDR_BROADCAST)
add_attr_l(&nlm->hdr, sizeof(*nlm), RTA_GATEWAY,
- &gateway->s_addr, sizeof(gateway->s_addr));
+ &rt->gate.s_addr, sizeof(rt->gate.s_addr));
add_attr_32(&nlm->hdr, sizeof(*nlm), RTA_OIF, ifindex);
- add_attr_32(&nlm->hdr, sizeof(*nlm), RTA_PRIORITY, metric);
+ add_attr_32(&nlm->hdr, sizeof(*nlm), RTA_PRIORITY, rt->metric);
if (send_netlink(&nlm->hdr) == -1)
retval = -1;
#define get_address(iface, addr, net, dst) \
do_address(iface, addr, net, dst, 1)
-int if_route(const struct interface *, const struct in_addr *,
- const struct in_addr *, const struct in_addr *, int, int);
-#define add_route(iface, dest, mask, gate, metric) \
- if_route(iface, dest, mask, gate, metric, 1)
-#define change_route(iface, dest, mask, gate, metric) \
- if_route(iface, dest, mask, gate, metric, 0)
-#define del_route(iface, dest, mask, gate, metric) \
- if_route(iface, dest, mask, gate, metric, -1)
-#define del_src_route(iface, dest, mask, gate, metric) \
- if_route(iface, dest, mask, gate, metric, -2)
+int if_route(const struct rt *rt, int);
+#define add_route(rt) if_route(rt, 1)
+#define change_route(rt) if_route(rt, 0)
+#define del_route(rt) if_route(rt, -1)
+#define del_src_route(rt) if_route(rt, -2);
void free_routes(struct rt *);
int open_udp_socket(struct interface *);