From 623097d32e26f51aca72bcd75979c187f656b4ff Mon Sep 17 00:00:00 2001
From: "Hamid Jafarian (hm.t.)" <hamid@pdnsoft.com>
Date: Thu, 12 Jul 2012 15:26:20 +0430
Subject: [PATCH] Ability to compile iproute2 as shared library
This is a try with minimum changes to compile iproute2 as shared
library.
Some functions would be used when we compile iproute2 as
shared library has been defined in "ip.c".
Also NICs caching strategy has been changed because, when we use
"libiproute2.so", system NIC list may change, so we should
re-cache all NICs at each call to NIC manipulation functions.
Also some call of "exit(*)" changed to "return *".
HOWTO Make: # export LIBIPROUTE2_SO=y; make
---
ip/Makefile | 13 ++++++++++++-
ip/ip.c | 40 ++++++++++++++++++++++++++++++++++++++++
ip/iproute.c | 2 +-
lib/Makefile | 3 +++
lib/ll_map.c | 25 ++++++++++++++++++++++++-
lib/utils.c | 7 ++++---
6 files changed, 84 insertions(+), 6 deletions(-)
@@ -13,14 +13,25 @@ ifeq ($(IP_CONFIG_SETNS),y)
CFLAGS += -DHAVE_SETNS
endif
+ifeq ($(LIBIPROUTE2_SO), y))
+ CFLAGS += -fPIC -DLIBIPROUTE2_SO
+endif
+
ALLOBJ=$(IPOBJ) $(RTMONOBJ)
SCRIPTS=ifcfg rtpr routel routef
-TARGETS=ip rtmon
+
+ifeq ($(LIBIPROUTE2_SO), y)
+ TARGETS=libiproute2.so rtmon
+else
+ TARGETS=ip rtmon
+endif
all: $(TARGETS) $(SCRIPTS)
ip: $(IPOBJ) $(LIBNETLINK)
+libiproute2.so: $(IPOBJ) $(LIBNETLINK)
+ $(CC) $(CFLAGS) -shared $(IPOBJ) $(LIBNETLINK) -o $(@)
rtmon: $(RTMONOBJ)
@@ -87,6 +87,44 @@ static const struct cmd {
{ 0 }
};
+#ifdef LIBIPROUTE2_SO
+int do_ipinit()
+{
+
+ if (rtnl_open(&rth, 0) < 0)
+ return 1;
+ _SL_="\n";
+ return 0;
+}
+
+int do_ipfini()
+{
+ rtnl_close(&rth);
+ return 0;
+}
+
+void do_ipflushloop(int loop)
+{
+ max_flush_loops = loop;
+}
+
+int do_ipfamily(char *family)
+{
+ if (strcmp(family, "inet") == 0)
+ preferred_family = AF_INET;
+ else if (strcmp(family, "inet6") == 0)
+ preferred_family = AF_INET6;
+ else if (strcmp(family, "dnet") == 0)
+ preferred_family = AF_DECnet;
+ else if (strcmp(family, "link") == 0)
+ preferred_family = AF_PACKET;
+ else if (strcmp(family, "ipx") == 0)
+ preferred_family = AF_IPX;
+ else return -1;
+ return 0;
+}
+#endif //#ifdef LIBIPROUTE2_SO
+
static int do_cmd(const char *argv0, int argc, char **argv)
{
const struct cmd *c;
@@ -101,6 +139,7 @@ static int do_cmd(const char *argv0, int argc, char **argv)
return EXIT_FAILURE;
}
+#ifndef LIBIPROUTE2_SO
static int batch(const char *name)
{
char *line = NULL;
@@ -264,3 +303,4 @@ int main(int argc, char **argv)
rtnl_close(&rth);
usage();
}
+#endif //#ifndef LIBIPROUTE2_SO
@@ -1012,7 +1012,7 @@ int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
req.r.rtm_family = AF_INET;
if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0)
- exit(2);
+ return 2;
return 0;
}
@@ -1,4 +1,7 @@
CFLAGS += -fPIC
+ifeq ($(LIBIPROUTE2_SO), y))
+ CFLAGS += -DLIBIPROUTE2_SO
+endif
UTILOBJ=utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o inet_proto.o
@@ -172,15 +172,18 @@ unsigned ll_name_to_index(const char *name)
if (name == NULL)
return 0;
-
+#ifndef LIBIPROUTE2_SO
if (icache && strcmp(name, ncache) == 0)
return icache;
+#endif
for (i=0; i<IDXMAP_SIZE; i++) {
for (im = idx_head[i]; im; im = im->idx_next) {
if (strcmp(im->name, name) == 0) {
+#ifndef LIBIPROUTE2_SO
icache = im->index;
strcpy(ncache, name);
+#endif
return im->index;
}
}
@@ -192,12 +195,32 @@ unsigned ll_name_to_index(const char *name)
return idx;
}
+#ifdef LIBIPROUTE2_SO
+int ll_free_map()
+{
+ int i;
+ struct ll_cache *im, *imt;
+ for (i=0; i<IDXMAP_SIZE; i++) {
+ for (im = idx_head[i]; im; im = imt) {
+ imt = im->idx_next;
+ free(im);
+ }
+ idx_head[i] = NULL;
+ }
+ return 0;
+}
+#endif
+
int ll_init_map(struct rtnl_handle *rth)
{
static int initialized;
+#ifdef LIBIPROUTE2_SO
+ ll_free_map();
+#else
if (initialized)
return 0;
+#endif
if (rtnl_wilddump_request(rth, AF_UNSPEC, RTM_GETLINK) < 0) {
perror("Cannot send dump request");
@@ -330,6 +330,7 @@ int get_prefix_1(inet_prefix *dst, char *arg, int family)
int err;
unsigned plen;
char *slash;
+ char *addr = arg;
memset(dst, 0, sizeof(*dst));
@@ -346,9 +347,9 @@ int get_prefix_1(inet_prefix *dst, char *arg, int family)
slash = strchr(arg, '/');
if (slash)
- *slash = 0;
+ addr = strndup(arg, slash - arg);
- err = get_addr_1(dst, arg, family);
+ err = get_addr_1(dst, addr, family);
if (err == 0) {
switch(dst->family) {
case AF_INET6:
@@ -373,7 +374,7 @@ int get_prefix_1(inet_prefix *dst, char *arg, int family)
}
done:
if (slash)
- *slash = '/';
+ free(addr);
return err;
}
--
1.7.6.4