X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fodhcpd.git;a=blobdiff_plain;f=src%2Fodhcpd.c;h=ed96178ba48de3140833d49524a7463343536987;hp=f259239c7848104ff177fd5ff2ed7c387fe2672d;hb=fa57225cb62b43adffc37a50c3dbd3fa7d225b0b;hpb=df5042974622d72ce2424de8ef532941ac4f7fc9;ds=sidebyside diff --git a/src/odhcpd.c b/src/odhcpd.c index f259239..ed96178 100644 --- a/src/odhcpd.c +++ b/src/odhcpd.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -62,8 +63,8 @@ static void print_usage(const char *app) { printf( "== %s Usage ==\n\n" - " -h, --help Print this help\n" - " -l level Specify log level 0..7 (default %d)\n", + " -h, --help Print this help\n" + " -l level Specify log level 0..7 (default %d)\n", app, LOG_WARNING ); } @@ -94,7 +95,7 @@ int main(int argc, char **argv) ioctl_sock = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); - if (!(rtnl_socket = odhcpd_create_nl_socket(NETLINK_ROUTE, 0))) { + if (!(rtnl_socket = odhcpd_create_nl_socket(NETLINK_ROUTE))) { syslog(LOG_ERR, "Unable to open nl socket: %s", strerror(errno)); return 2; } @@ -122,7 +123,7 @@ int main(int argc, char **argv) return 0; } -struct nl_sock *odhcpd_create_nl_socket(int protocol, int groups) +struct nl_sock *odhcpd_create_nl_socket(int protocol) { struct nl_sock *nl_sock; @@ -130,9 +131,6 @@ struct nl_sock *odhcpd_create_nl_socket(int protocol, int groups) if (!nl_sock) goto err; - if (groups) - nl_join_groups(nl_sock, groups); - if (nl_connect(nl_sock, protocol) < 0) goto err; @@ -356,9 +354,9 @@ int odhcpd_get_linklocal_interface_address(int ifindex, struct in6_addr *lladdr) return status; } -int odhcpd_setup_route(const struct in6_addr *addr, int prefixlen, +int odhcpd_setup_route(const struct in6_addr *addr, const int prefixlen, const struct interface *iface, const struct in6_addr *gw, - uint32_t metric, bool add) + const uint32_t metric, const bool add) { struct nl_msg *msg; struct rtmsg rtm = { @@ -395,6 +393,37 @@ int odhcpd_setup_route(const struct in6_addr *addr, int prefixlen, return nl_wait_for_ack(rtnl_socket); } +int odhcpd_setup_proxy_neigh(const struct in6_addr *addr, + const struct interface *iface, const bool add) +{ + struct nl_msg *msg; + struct ndmsg ndm = { + .ndm_family = AF_INET6, + .ndm_flags = NTF_PROXY, + .ndm_ifindex = iface->ifindex, + }; + int ret = 0, flags = NLM_F_REQUEST; + + if (add) + flags |= NLM_F_REPLACE | NLM_F_CREATE; + + msg = nlmsg_alloc_simple(add ? RTM_NEWNEIGH : RTM_DELNEIGH, flags); + if (!msg) + return -1; + + nlmsg_append(msg, &ndm, sizeof(ndm), 0); + + nla_put(msg, NDA_DST, sizeof(*addr), addr); + + ret = nl_send_auto_complete(rtnl_socket, msg); + nlmsg_free(msg); + + if (ret < 0) + return ret; + + return nl_wait_for_ack(rtnl_socket); +} + struct interface* odhcpd_get_interface_by_index(int ifindex) { struct interface *iface; @@ -447,7 +476,12 @@ static void odhcpd_receive_packets(struct uloop_fd *u, _unused unsigned int even getsockopt(u->fd, SOL_SOCKET, SO_ERROR, &ret, &ret_len); u->error = false; if (e->handle_error) - e->handle_error(ret); + e->handle_error(e, ret); + } + + if (e->recv_msgs) { + e->recv_msgs(e); + return; } while (true) { @@ -532,6 +566,12 @@ int odhcpd_register(struct odhcpd_event *event) ((event->handle_error) ? ULOOP_ERROR_CB : 0)); } +int odhcpd_deregister(struct odhcpd_event *event) +{ + event->uloop.cb = NULL; + return uloop_fd_delete(&event->uloop); +} + void odhcpd_process(struct odhcpd_event *event) { odhcpd_receive_packets(&event->uloop, 0);