summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@gnumonks.org>2014-03-20 16:23:18 +0100
committerPablo Neira Ayuso <pablo@gnumonks.org>2014-03-20 16:47:00 +0100
commit892ec8664c6d722cbe9862c26a0870c558f66873 (patch)
treec27705aed5eb5c7660a655205b2df205d96d15c8
parent477960379075bb5069926b6f3eba9e19edc635c0 (diff)
gtp-rtnl: add gtp_dev_config function
This function allows us to set the gtp0 device configuration the route to encapsulate all traffic that is addressed to the MS from the GGSN
-rw-r--r--libgtnl/include/libgtpnl/gtpnl.h3
-rw-r--r--libgtnl/src/gtp-rtnl.c50
-rw-r--r--libgtnl/src/libgtpnl.map1
3 files changed, 52 insertions, 2 deletions
diff --git a/libgtnl/include/libgtpnl/gtpnl.h b/libgtnl/include/libgtpnl/gtpnl.h
index e27dec4..c4faf6c 100644
--- a/libgtnl/include/libgtpnl/gtpnl.h
+++ b/libgtnl/include/libgtpnl/gtpnl.h
@@ -14,8 +14,11 @@ int genl_socket_talk(struct mnl_socket *nl, struct nlmsghdr *nlh, uint32_t seq,
void *data);
int genl_lookup_family(struct mnl_socket *nl, const char *family);
+struct in_addr;
+
int gtp_dev_create(const char *gtp_ifname, const char *real_ifname,
int fd0, int fd1);
+int gtp_dev_config(const char *iface, struct in_addr *net, uint32_t prefix);
int gtp_dev_destroy(const char *gtp_ifname);
struct gtp_tunnel;
diff --git a/libgtnl/src/gtp-rtnl.c b/libgtnl/src/gtp-rtnl.c
index 7481ced..6ecea08 100644
--- a/libgtnl/src/gtp-rtnl.c
+++ b/libgtnl/src/gtp-rtnl.c
@@ -8,10 +8,11 @@
#include <net/if.h>
#include <linux/if_link.h>
#include <linux/rtnetlink.h>
-
#include <libgtpnl/gtpnl.h>
-
#include <linux/gtp_nl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <time.h>
#include "internal.h"
@@ -129,3 +130,48 @@ int gtp_dev_destroy(const char *gtp_ifname)
return gtp_dev_talk(nlh, seq);
}
EXPORT_SYMBOL(gtp_dev_destroy);
+
+int gtp_dev_config(const char *ifname, struct in_addr *dst, uint32_t prefix)
+{
+ struct mnl_socket *nl;
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+ struct nlmsghdr *nlh;
+ struct rtmsg *rtm;
+ int iface, ret;
+
+ iface = if_nametoindex(ifname);
+ if (iface == 0) {
+ perror("if_nametoindex");
+ return -1;
+ }
+
+ nlh = mnl_nlmsg_put_header(buf);
+ nlh->nlmsg_type = RTM_NEWROUTE;
+ nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK;
+ nlh->nlmsg_seq = time(NULL);
+
+ rtm = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtmsg));
+ rtm->rtm_family = AF_INET;
+ rtm->rtm_dst_len = prefix;
+ rtm->rtm_src_len = 0;
+ rtm->rtm_tos = 0;
+ rtm->rtm_protocol = RTPROT_STATIC;
+ rtm->rtm_table = RT_TABLE_MAIN;
+ rtm->rtm_type = RTN_UNICAST;
+ rtm->rtm_scope = RT_SCOPE_UNIVERSE;
+ rtm->rtm_flags = 0;
+
+ mnl_attr_put_u32(nlh, RTA_DST, dst->s_addr);
+ mnl_attr_put_u32(nlh, RTA_OIF, iface);
+
+ nl = rtnl_open();
+ if (nl == NULL)
+ return -1;
+
+ ret = rtnl_talk(nl, nlh);
+
+ mnl_socket_close(nl);
+
+ return ret;
+}
+EXPORT_SYMBOL(gtp_dev_config);
diff --git a/libgtnl/src/libgtpnl.map b/libgtnl/src/libgtpnl.map
index 2e80543..6e69ef8 100644
--- a/libgtnl/src/libgtpnl.map
+++ b/libgtnl/src/libgtpnl.map
@@ -6,6 +6,7 @@ global:
genl_lookup_family;
gtp_dev_create;
+ gtp_dev_config;
gtp_dev_destroy;
gtp_add_tunnel;