static int parse_mode(const char *mode)
{
if (!strcmp(mode, "disabled"))
- return RELAYD_DISABLED;
+ return MODE_DISABLED;
else if (!strcmp(mode, "server"))
- return RELAYD_SERVER;
+ return MODE_SERVER;
else if (!strcmp(mode, "relay"))
- return RELAYD_RELAY;
+ return MODE_RELAY;
else if (!strcmp(mode, "hybrid"))
- return RELAYD_HYBRID;
+ return MODE_HYBRID;
else
return -1;
}
iface->dhcpv4_start.s_addr = htonl(blobmsg_get_u32(c));
if (config.main_dhcpv4 && config.legacy)
- iface->dhcpv4 = RELAYD_SERVER;
+ iface->dhcpv4 = MODE_SERVER;
}
if ((c = tb[IFACE_ATTR_LIMIT]))
if (i->master)
continue;
- if (i->dhcpv6 == RELAYD_HYBRID || i->dhcpv6 == RELAYD_RELAY)
+ if (i->dhcpv6 == MODE_HYBRID || i->dhcpv6 == MODE_RELAY)
any_dhcpv6_slave = true;
- if (i->ra == RELAYD_HYBRID || i->ra == RELAYD_RELAY)
+ if (i->ra == MODE_HYBRID || i->ra == MODE_RELAY)
any_ra_slave = true;
- if (i->ndp == RELAYD_HYBRID || i->ndp == RELAYD_RELAY)
+ if (i->ndp == MODE_HYBRID || i->ndp == MODE_RELAY)
any_ndp_slave = true;
}
if (!i->master)
continue;
- enum odhcpd_mode hybrid_mode = RELAYD_DISABLED;
+ enum odhcpd_mode hybrid_mode = MODE_DISABLED;
#ifdef WITH_UBUS
if (!ubus_has_prefix(i->name, i->ifname))
- hybrid_mode = RELAYD_RELAY;
+ hybrid_mode = MODE_RELAY;
#endif
- if (i->dhcpv6 == RELAYD_HYBRID)
+ if (i->dhcpv6 == MODE_HYBRID)
i->dhcpv6 = hybrid_mode;
- if (i->dhcpv6 == RELAYD_RELAY && !any_dhcpv6_slave)
- i->dhcpv6 = RELAYD_DISABLED;
+ if (i->dhcpv6 == MODE_RELAY && !any_dhcpv6_slave)
+ i->dhcpv6 = MODE_DISABLED;
- if (i->ra == RELAYD_HYBRID)
+ if (i->ra == MODE_HYBRID)
i->ra = hybrid_mode;
- if (i->ra == RELAYD_RELAY && !any_ra_slave)
- i->ra = RELAYD_DISABLED;
+ if (i->ra == MODE_RELAY && !any_ra_slave)
+ i->ra = MODE_DISABLED;
- if (i->ndp == RELAYD_HYBRID)
+ if (i->ndp == MODE_HYBRID)
i->ndp = hybrid_mode;
- if (i->ndp == RELAYD_RELAY && !any_ndp_slave)
- i->ndp = RELAYD_DISABLED;
+ if (i->ndp == MODE_RELAY && !any_ndp_slave)
+ i->ndp = MODE_DISABLED;
- if (i->dhcpv6 == RELAYD_RELAY || i->ra == RELAYD_RELAY || i->ndp == RELAYD_RELAY)
+ if (i->dhcpv6 == MODE_RELAY || i->ra == MODE_RELAY || i->ndp == MODE_RELAY)
master = i;
}
list_for_each_entry_safe(i, n, &interfaces, head) {
if (i->inuse) {
/* Resolve hybrid mode */
- if (i->dhcpv6 == RELAYD_HYBRID)
- i->dhcpv6 = (master && master->dhcpv6 == RELAYD_RELAY) ?
- RELAYD_RELAY : RELAYD_SERVER;
-
- if (i->ra == RELAYD_HYBRID)
- i->ra = (master && master->ra == RELAYD_RELAY) ?
- RELAYD_RELAY : RELAYD_SERVER;
-
- if (i->ndp == RELAYD_HYBRID)
- i->ndp = (master && master->ndp == RELAYD_RELAY) ?
- RELAYD_RELAY : RELAYD_DISABLED;
-
- setup_router_interface(i, !i->ignore || i->ra != RELAYD_DISABLED);
- setup_dhcpv6_interface(i, !i->ignore || i->dhcpv6 != RELAYD_DISABLED);
- setup_ndp_interface(i, !i->ignore || i->ndp != RELAYD_DISABLED);
- setup_dhcpv4_interface(i, !i->ignore || i->dhcpv4 != RELAYD_DISABLED);
+ if (i->dhcpv6 == MODE_HYBRID)
+ i->dhcpv6 = (master && master->dhcpv6 == MODE_RELAY) ?
+ MODE_RELAY : MODE_SERVER;
+
+ if (i->ra == MODE_HYBRID)
+ i->ra = (master && master->ra == MODE_RELAY) ?
+ MODE_RELAY : MODE_SERVER;
+
+ if (i->ndp == MODE_HYBRID)
+ i->ndp = (master && master->ndp == MODE_RELAY) ?
+ MODE_RELAY : MODE_DISABLED;
+
+ setup_router_interface(i, !i->ignore || i->ra != MODE_DISABLED);
+ setup_dhcpv6_interface(i, !i->ignore || i->dhcpv6 != MODE_DISABLED);
+ setup_ndp_interface(i, !i->ignore || i->ndp != MODE_DISABLED);
+ setup_dhcpv4_interface(i, !i->ignore || i->dhcpv4 != MODE_DISABLED);
} else
close_interface(i);
}
}
}
- if (enable && iface->dhcpv6 == RELAYD_SERVER) {
+ if (enable && iface->dhcpv6 == MODE_SERVER) {
if (!iface->ia_assignments.next)
INIT_LIST_HEAD(&iface->ia_assignments);
ctxt.buf_len = sizeof(leasebuf);
list_for_each_entry(ctxt.iface, &interfaces, head) {
- if (ctxt.iface->dhcpv6 != RELAYD_SERVER &&
- ctxt.iface->dhcpv4 != RELAYD_SERVER)
+ if (ctxt.iface->dhcpv6 != MODE_SERVER &&
+ ctxt.iface->dhcpv4 != MODE_SERVER)
continue;
- if (ctxt.iface->dhcpv6 == RELAYD_SERVER &&
+ if (ctxt.iface->dhcpv6 == MODE_SERVER &&
ctxt.iface->ia_assignments.next) {
list_for_each_entry(ctxt.c, &ctxt.iface->ia_assignments, head) {
if (!(ctxt.c->flags & OAF_BOUND) || ctxt.c->managed_size < 0)
}
}
- if (ctxt.iface->dhcpv4 == RELAYD_SERVER &&
+ if (ctxt.iface->dhcpv4 == MODE_SERVER &&
ctxt.iface->dhcpv4_assignments.next) {
struct dhcpv4_assignment *c;
list_for_each_entry(c, &ctxt.iface->dhcpv4_assignments, head) {
void dhcpv6_ia_preupdate(struct interface *iface)
{
- if (iface->dhcpv6 != RELAYD_SERVER)
+ if (iface->dhcpv6 != MODE_SERVER)
return;
struct dhcpv6_assignment *c, *border = list_last_entry(
void dhcpv6_ia_postupdate(struct interface *iface)
{
- if (iface->dhcpv6 != RELAYD_SERVER)
+ if (iface->dhcpv6 != MODE_SERVER)
return;
time_t now = odhcpd_time();
time_t now = odhcpd_time();
struct interface *iface;
list_for_each_entry(iface, &interfaces, head) {
- if (iface->dhcpv6 != RELAYD_SERVER || iface->ia_assignments.next == NULL)
+ if (iface->dhcpv6 != MODE_SERVER || iface->ia_assignments.next == NULL)
continue;
struct dhcpv6_assignment *a, *n;
struct ipv6_mreq server = {ALL_DHCPV6_SERVERS, iface->ifindex};
setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &relay, sizeof(relay));
- if (iface->dhcpv6 == RELAYD_SERVER)
+ if (iface->dhcpv6 == MODE_SERVER)
setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &server, sizeof(server));
iface->dhcpv6_event.uloop.fd = sock;
static void handle_dhcpv6(void *addr, void *data, size_t len,
struct interface *iface, void *dest_addr)
{
- if (iface->dhcpv6 == RELAYD_SERVER) {
+ if (iface->dhcpv6 == MODE_SERVER) {
handle_client_request(addr, data, len, iface, dest_addr);
- } else if (iface->dhcpv6 == RELAYD_RELAY) {
+ } else if (iface->dhcpv6 == MODE_RELAY) {
if (iface->master)
relay_server_response(data, len);
else
{
struct interface *master = odhcpd_get_master_interface();
const struct dhcpv6_relay_header *h = data;
- if (!master || master->dhcpv6 != RELAYD_RELAY ||
+ if (!master || master->dhcpv6 != MODE_RELAY ||
h->msg_type == DHCPV6_MSG_RELAY_REPL ||
h->msg_type == DHCPV6_MSG_RECONFIGURE ||
h->msg_type == DHCPV6_MSG_REPLY ||
close(iface->ndp_event.uloop.fd);
iface->ndp_event.uloop.fd = -1;
- if (!enable || iface->ndp != RELAYD_RELAY)
+ if (!enable || iface->ndp != MODE_RELAY)
if (write(procfd, "0\n", 2) < 0) {}
dump_neigh = true;
}
- if (enable && iface->ndp == RELAYD_RELAY) {
+ if (enable && iface->ndp == MODE_RELAY) {
if (write(procfd, "1\n", 2) < 0) {}
int sock = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, htons(ETH_P_IPV6));
// Don't process solicit messages on non relay interfaces
// Don't forward any non-DAD solicitation for external ifaces
// TODO: check if we should even forward DADs for them
- if (iface->ndp != RELAYD_RELAY || (iface->external && !ns_is_dad))
+ if (iface->ndp != MODE_RELAY || (iface->external && !ns_is_dad))
return;
if (len < sizeof(*ip6) + sizeof(*req))
struct interface *c;
list_for_each_entry(c, &interfaces, head)
- if (iface != c && c->ndp == RELAYD_RELAY &&
+ if (iface != c && c->ndp == MODE_RELAY &&
(ns_is_dad || !c->external))
ping6(&req->nd_ns_target, c);
}
inet_ntop(AF_INET6, addr, ipbuf, sizeof(ipbuf));
list_for_each_entry(c, &interfaces, head) {
- if (iface == c || (c->ndp != RELAYD_RELAY && !add))
+ if (iface == c || (c->ndp != MODE_RELAY && !add))
continue;
- bool neigh_add = (c->ndp == RELAYD_RELAY ? add : false);
+ bool neigh_add = (c->ndp == MODE_RELAY ? add : false);
if (odhcpd_setup_proxy_neigh(addr, c, neigh_add))
syslog(LOG_DEBUG, "Failed to %s proxy neighbour entry %s%%%s",
check_addr6_updates(iface);
- if (iface->ndp != RELAYD_RELAY)
+ if (iface->ndp != MODE_RELAY)
break;
/* handle the relay logic below */
return NL_SKIP;
iface = odhcpd_get_interface_by_index(ndm->ndm_ifindex);
- if (!iface || iface->ndp != RELAYD_RELAY)
+ if (!iface || iface->ndp != MODE_RELAY)
return (iface ? NL_OK : NL_SKIP);
nlmsg_parse(hdr, sizeof(*ndm), nla, __NDA_MAX - 1, NULL);
{
struct odhcpd_event *e = container_of(u, struct odhcpd_event, uloop);
- uint8_t data_buf[RELAYD_BUFFER_SIZE], cmsg_buf[128];
+ uint8_t data_buf[8192], cmsg_buf[128];
union {
struct sockaddr_in6 in6;
struct sockaddr_in in;
#define ND_OPT_RECURSIVE_DNS 25
#define ND_OPT_DNS_SEARCH 31
-#define RELAYD_BUFFER_SIZE 8192
-
#define INFINITE_VALID(x) ((x) == 0)
#define _unused __attribute__((unused))
};
enum odhcpd_mode {
- RELAYD_DISABLED,
- RELAYD_SERVER,
- RELAYD_RELAY,
- RELAYD_HYBRID
+ MODE_DISABLED,
+ MODE_SERVER,
+ MODE_RELAY,
+ MODE_HYBRID
};
} else {
void *mreq = &all_routers;
- if (iface->ra == RELAYD_RELAY && iface->master) {
+ if (iface->ra == MODE_RELAY && iface->master) {
mreq = &all_nodes;
forward_router_solicitation(iface);
- } else if (iface->ra == RELAYD_SERVER && !iface->master) {
+ } else if (iface->ra == MODE_SERVER && !iface->master) {
iface->timer_rs.cb = trigger_router_advert;
uloop_timeout_set(&iface->timer_rs, 1000);
}
- if (iface->ra == RELAYD_RELAY || (iface->ra == RELAYD_SERVER && !iface->master))
+ if (iface->ra == MODE_RELAY || (iface->ra == MODE_SERVER && !iface->master))
setsockopt(router_event.uloop.fd, IPPROTO_IPV6,
IPV6_ADD_MEMBERSHIP, mreq, sizeof(all_nodes));
}
{
struct interface *iface;
list_for_each_entry(iface, &interfaces, head)
- if (iface->ra == RELAYD_SERVER && !iface->master)
+ if (iface->ra == MODE_SERVER && !iface->master)
uloop_timeout_set(&iface->timer_rs, 1000);
}
if (!router_icmpv6_valid(addr, data, len))
return;
- if ((iface->ra == RELAYD_SERVER && !iface->master)) { // Server mode
+ if ((iface->ra == MODE_SERVER && !iface->master)) { // Server mode
if (hdr->icmp6_type == ND_ROUTER_SOLICIT)
send_router_advert(iface, &from->sin6_addr);
- } else if (iface->ra == RELAYD_RELAY) { // Relay mode
+ } else if (iface->ra == MODE_RELAY) { // Relay mode
if (hdr->icmp6_type == ND_ROUTER_ADVERT && iface->master)
forward_router_advertisement(data, len);
else if (hdr->icmp6_type == ND_ROUTER_SOLICIT && !iface->master)
struct interface *iface;
list_for_each_entry(iface, &interfaces, head) {
- if (iface->ra != RELAYD_RELAY || iface->master)
+ if (iface->ra != MODE_RELAY || iface->master)
continue;
// Fixup source hardware address option
a = blobmsg_open_table(&b, "device");
list_for_each_entry(iface, &interfaces, head) {
- if (iface->dhcpv4 != RELAYD_SERVER || iface->dhcpv4_assignments.next == NULL)
+ if (iface->dhcpv4 != MODE_SERVER || iface->dhcpv4_assignments.next == NULL)
continue;
void *i = blobmsg_open_table(&b, iface->ifname);
a = blobmsg_open_table(&b, "device");
list_for_each_entry(iface, &interfaces, head) {
- if (iface->dhcpv6 != RELAYD_SERVER || iface->ia_assignments.next == NULL)
+ if (iface->dhcpv6 != MODE_SERVER || iface->ia_assignments.next == NULL)
continue;
void *i = blobmsg_open_table(&b, iface->ifname);