diff options
author | Pablo Neira Ayuso <pablo@gnumonks.org> | 2014-03-20 16:23:18 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@gnumonks.org> | 2014-03-20 16:47:00 +0100 |
commit | 892ec8664c6d722cbe9862c26a0870c558f66873 (patch) | |
tree | c27705aed5eb5c7660a655205b2df205d96d15c8 | |
parent | 477960379075bb5069926b6f3eba9e19edc635c0 (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.h | 3 | ||||
-rw-r--r-- | libgtnl/src/gtp-rtnl.c | 50 | ||||
-rw-r--r-- | libgtnl/src/libgtpnl.map | 1 |
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; |