git://git.onelab.eu
/
util-vserver.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge 0.30.214.
[util-vserver.git]
/
src
/
vip6-autod.c
diff --git
a/src/vip6-autod.c
b/src/vip6-autod.c
index
63e9368
..
2d48dcd
100644
(file)
--- a/
src/vip6-autod.c
+++ b/
src/vip6-autod.c
@@
-1,5
+1,5
@@
/*
/*
- * $Id: vip6-autod.c,v 1.
2 2007/07/26 19:00:23
dhozac Exp $
+ * $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 <daniel@hozac.com>
*
* Copyright (c) 2007 The Trustees of Princeton University
* Author: Daniel Hokka Zakrisson <daniel@hozac.com>
*
@@
-7,6
+7,10
@@
* version 2 or later.
*/
* version 2 or later.
*/
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@
-21,17
+25,17
@@
#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <ctype.h>
#include <errno.h>
#include <signal.h>
+#include <syslog.h>
#include <asm/types.h>
/* not defined for gcc -ansi */
#include <asm/types.h>
/* not defined for gcc -ansi */
-typedef u
int64_t
__u64;
-typedef
int64_t
__s64;
+typedef u
nsigned long long
__u64;
+typedef
signed long long
__s64;
#include <netlink/netlink.h>
#include <netlink/route/addr.h>
#include <netlink/netlink.h>
#include <netlink/route/addr.h>
-typedef unsigned int nid_t;
-typedef unsigned int xid_t;
#include <vserver.h>
#include <vserver.h>
+#include "pathconfig.h"
#define HAS_ADDRESS 0x01
#define HAS_PREFIX 0x02
#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;
}
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;
{
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 = 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)
{
}
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;
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));
memcpy(&a, &i->address.addr, sizeof(a));
rta = rtnl_addr_alloc();
nl = nl_addr_build(AF_INET6, &a, sizeof(a));
@@
-136,7
+146,23
@@
static void cleanup_prefix(struct prefix_list *i)
nl_addr_destroy(nl);
rtnl_addr_free(rta);
nl_addr_destroy(nl);
rtnl_addr_free(rta);
+
+ p = n;
}
}
+ if (p)
+ free(p);
+}
+
+static inline void free_nid_list(struct nid_list *head)
+{
+ struct nid_list *p;
+ for (p = NULL; head; head = head->next) {
+ if (p)
+ free(p);
+ p = head;
+ }
+ if (p)
+ free(p);
}
static void do_slices_autoconf(struct prefix_list *head)
}
static void do_slices_autoconf(struct prefix_list *head)
@@
-146,6
+172,8
@@
static void do_slices_autoconf(struct prefix_list *head)
nid_t nid;
struct vc_net_nx addr;
struct prefix_list *i;
nid_t nid;
struct vc_net_nx addr;
struct prefix_list *i;
+ struct nid_list *current = NULL, *n;
+ static struct nid_list *previous = NULL;
if ((dp = opendir("/proc/virtnet")) == NULL)
return;
if ((dp = opendir("/proc/virtnet")) == NULL)
return;
@@
-157,10
+185,12
@@
static void do_slices_autoconf(struct prefix_list *head)
addr.type = vcNET_IPV6A;
addr.count = 0;
if (vc_net_remove(nid, &addr) == -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;
}
continue;
}
+ add_nid_to_list(¤t, nid);
+
for (i = head->next; i;) {
/* expired */
if (i->mask & HAS_PREFIX && i->prefix.valid_until < time(NULL)) {
for (i = head->next; i;) {
/* expired */
if (i->mask & HAS_PREFIX && i->prefix.valid_until < time(NULL)) {
@@
-168,7
+198,7
@@
static void do_slices_autoconf(struct prefix_list *head)
char buf[64];
inet_ntop(AF_INET6, &i->address.addr, buf, sizeof(buf));
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;
if (i->next)
i->next->prev = i->prev;
@@
-185,28
+215,32
@@
static void do_slices_autoconf(struct prefix_list *head)
if (i->mask != (HAS_ADDRESS|HAS_PREFIX))
goto next;
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.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 & 0x7f
0
0) >> 7));
- addr.ip[3] = htonl((ntohl(addr.ip[3]) & 0x00ffffff) | ((nid & 0x
f
f) << 25));
+ addr.ip[2] = htonl((ntohl(addr.ip[2]) & 0xffffff00) | ((nid & 0x7f
8
0) >> 7));
+ addr.ip[3] = htonl((ntohl(addr.ip[3]) & 0x00ffffff) | ((nid & 0x
7
f) << 25));
if (vc_net_add(nid, &addr) == -1) {
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) {
}
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;
}
}
closedir(dp);
}
next:
i = i->next;
}
}
closedir(dp);
+
+ free_nid_list(previous);
+ previous = current;
}
static int add_prefix(struct prefix_list *head, struct prefixmsg *msg,
}
static int add_prefix(struct prefix_list *head, struct prefixmsg *msg,
@@
-307,7
+341,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) {
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;
}
return -1;
}
@@
-325,7
+359,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) {
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;
}
return -1;
}
@@
-345,7
+379,7
@@
int handle_valid_msg(struct nl_msg *msg, void *arg)
int handle_error_msg(struct sockaddr_nl *source, struct nlmsgerr *err,
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;
}
return 0;
}
@@
-365,12
+399,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;
int main(int argc, char *argv[])
{
struct nl_cb *cbs;
-
head.prev = head.next = NULL;
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);
handle = nl_handle_alloc_nondefault(NL_CB_VERBOSE);
cbs = nl_handle_get_cb(handle);
@@
-381,12
+426,21
@@
int main(int argc, char *argv[])
nl_join_groups(handle, RTMGRP_IPV6_PREFIX|RTMGRP_IPV6_IFADDR);
if (nl_connect(handle, NETLINK_ROUTE) == -1) {
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);
}
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);
while (nl_recvmsgs(handle, cbs) > 0);
nl_close(handle);
+ closelog();
return 0;
}
return 0;
}