X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2Fvip6-autod.c;h=1b60aa0d79fa0611b2ccfc74c3d1a6dd0657a26e;hb=5f167675beabb9f55df5fe8a579f87763764cb08;hp=0906612c9d16912e73541fc9941d95c236c87b01;hpb=d6218374134c27be203417ae594c214ffaa4a238;p=util-vserver.git diff --git a/src/vip6-autod.c b/src/vip6-autod.c index 0906612..1b60aa0 100644 --- a/src/vip6-autod.c +++ b/src/vip6-autod.c @@ -1,5 +1,5 @@ /* - * $Id$ + * $Id: vip6-autod.c,v 1.4 2007/07/30 14:59:11 dhozac Exp $ * Copyright (c) 2007 The Trustees of Princeton University * Author: Daniel Hokka Zakrisson * @@ -7,6 +7,10 @@ * version 2 or later. */ +#ifdef HAVE_CONFIG_H +# include +#endif + #include #include #include @@ -21,6 +25,7 @@ #include #include #include +#include #include /* not defined for gcc -ansi */ @@ -29,9 +34,8 @@ typedef int64_t __s64; #include #include -typedef unsigned int nid_t; -typedef unsigned int xid_t; #include +#include "pathconfig.h" #define HAS_ADDRESS 0x01 #define HAS_PREFIX 0x02 @@ -101,27 +105,33 @@ static int add_address_to_interface(int ifindex, struct in6_addr *address, int p return err; } -static int add_nid_to_list(struct prefix_list *i, nid_t nid) +static int add_nid_to_list(struct nid_list **l, nid_t nid) { struct nid_list *n; + for (n = *l; n; n = n->next) { + if (n->nid == nid) + return 0; + } n = calloc(1, sizeof(struct nid_list)); if (!n) return -1; n->nid = nid; - n->next = i->nids; - i->nids = n; - return 0; + n->next = *l; + *l = n; + return 1; } static void cleanup_prefix(struct prefix_list *i) { - struct nid_list *n; + struct nid_list *n, *p = NULL; for (n = i->nids; n; n = n->next) { struct rtnl_addr *rta; struct nl_addr *nl; struct in6_addr a; + if (p) + free(p); memcpy(&a, &i->address.addr, sizeof(a)); rta = rtnl_addr_alloc(); nl = nl_addr_build(AF_INET6, &a, sizeof(a)); @@ -136,7 +146,11 @@ static void cleanup_prefix(struct prefix_list *i) nl_addr_destroy(nl); rtnl_addr_free(rta); + + p = n; } + if (p) + free(p); } static void do_slices_autoconf(struct prefix_list *head) @@ -146,6 +160,7 @@ static void do_slices_autoconf(struct prefix_list *head) nid_t nid; struct vc_net_nx addr; struct prefix_list *i; + struct nid_list *current = NULL, *n; if ((dp = opendir("/proc/virtnet")) == NULL) return; @@ -154,13 +169,15 @@ static void do_slices_autoconf(struct prefix_list *head) continue; nid = strtoul(de->d_name, NULL, 10); - addr.type = vcNET_IPV6; - addr.count = -1; + addr.type = vcNET_IPV6A; + addr.count = 0; if (vc_net_remove(nid, &addr) == -1) { - perror("vc_net_remove"); + syslog(LOG_ERR, "vc_net_remove(%u): %s", nid, strerror(errno)); continue; } + add_nid_to_list(¤t, nid); + for (i = head->next; i;) { /* expired */ if (i->mask & HAS_PREFIX && i->prefix.valid_until < time(NULL)) { @@ -168,7 +185,7 @@ static void do_slices_autoconf(struct prefix_list *head) char buf[64]; inet_ntop(AF_INET6, &i->address.addr, buf, sizeof(buf)); - printf("Address %s timed out.\n", buf); + syslog(LOG_NOTICE, "Address %s timed out", buf); if (i->next) i->next->prev = i->prev; @@ -185,22 +202,23 @@ static void do_slices_autoconf(struct prefix_list *head) if (i->mask != (HAS_ADDRESS|HAS_PREFIX)) goto next; + addr.type = vcNET_IPV6; addr.count = 1; addr.mask[0] = i->prefix.prefix_len; memcpy(addr.ip, &i->address.addr, sizeof(struct in6_addr)); - addr.ip[2] = htonl((ntohl(addr.ip[2]) & 0xffffff00) | ((nid & 0x7f00) >> 7)); - addr.ip[3] = htonl((ntohl(addr.ip[3]) & 0x00ffffff) | ((nid & 0xff) << 25)); + addr.ip[2] = htonl((ntohl(addr.ip[2]) & 0xffffff00) | ((nid & 0x7f80) >> 7)); + addr.ip[3] = htonl((ntohl(addr.ip[3]) & 0x00ffffff) | ((nid & 0x7f) << 25)); if (vc_net_add(nid, &addr) == -1) { - perror("vc_net_add"); - exit(1); + syslog(LOG_ERR, "vc_net_add(%u): %s", nid, strerror(errno)); + goto next; } if (add_address_to_interface(i->ifindex, (struct in6_addr *) addr.ip, i->prefix.prefix_len) == -1) { - perror("add_address_to_interface"); - exit(1); + syslog(LOG_ERR, "add_address_to_interface: %s", strerror(errno)); + goto next; } - if (add_nid_to_list(i, nid) == -1) { - perror("add_nid_to_list"); - exit(1); + if (add_nid_to_list(&i->nids, nid) == -1) { + syslog(LOG_ERR, "add_nid_to_list: %s", strerror(errno)); + goto next; } next: i = i->next; @@ -307,7 +325,7 @@ int handle_valid_msg(struct nl_msg *msg, void *arg) struct nlattr *tb[PREFIX_MAX+1]; if (nlmsg_parse(nlh, sizeof(struct prefixmsg), tb, PREFIX_MAX, prefix_policy) < 0) { - printf("Failed to parse prefixmsg.\n"); + syslog(LOG_ERR, "Failed to parse prefixmsg"); return -1; } @@ -325,7 +343,7 @@ int handle_valid_msg(struct nl_msg *msg, void *arg) struct nlattr *tb[IFA_MAX+1]; if (nlmsg_parse(nlh, sizeof(struct ifaddrmsg), tb, IFA_MAX, addr_policy) < 0) { - printf("Failed to parse ifaddrmsg.\n"); + syslog(LOG_ERR, "Failed to parse ifaddrmsg"); return -1; } @@ -345,7 +363,7 @@ int handle_valid_msg(struct nl_msg *msg, void *arg) int handle_error_msg(struct sockaddr_nl *source, struct nlmsgerr *err, void *arg) { - perror("Got an error"); + syslog(LOG_ERR, "%s", strerror(err->error)); return 0; } @@ -365,12 +383,23 @@ void signal_handler(int signal) } } +static int write_pidfile(const char *filename) +{ + FILE *fp; + fp = fopen(filename, "w"); + if (!fp) + return -1; + fprintf(fp, "%d\n", getpid()); + fclose(fp); + return 0; +} + int main(int argc, char *argv[]) { struct nl_cb *cbs; - head.prev = head.next = NULL; - signal(SIGUSR1, signal_handler); + + openlog("vip6-autod", LOG_PERROR, LOG_DAEMON); handle = nl_handle_alloc_nondefault(NL_CB_VERBOSE); cbs = nl_handle_get_cb(handle); @@ -381,12 +410,21 @@ int main(int argc, char *argv[]) nl_join_groups(handle, RTMGRP_IPV6_PREFIX|RTMGRP_IPV6_IFADDR); if (nl_connect(handle, NETLINK_ROUTE) == -1) { - perror("nl_connect"); + syslog(LOG_CRIT, "nl_connect: %s", strerror(errno)); exit(1); } + if (daemon(0, 0) == -1) + return -1; + + /* XXX .. here is a hack */ + write_pidfile(DEFAULT_PKGSTATEDIR "/../vip6-autod.pid"); + + signal(SIGUSR1, signal_handler); + while (nl_recvmsgs(handle, cbs) > 0); nl_close(handle); + closelog(); return 0; }