X-Git-Url: http://git.openwrt.org/?p=project%2Fodhcpd.git;a=blobdiff_plain;f=src%2Fodhcpd.c;h=2b0ea985c1c308c428af73cd352f0580b3289640;hp=f259239c7848104ff177fd5ff2ed7c387fe2672d;hb=ac70d28ed6ec96e6911cdf56b903f5c5ee3e67c5;hpb=df5042974622d72ce2424de8ef532941ac4f7fc9;ds=sidebyside diff --git a/src/odhcpd.c b/src/odhcpd.c index f259239..2b0ea98 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) {