blob: 2cd43ef000dd1c38a20cb9e68ef065aca2c8777a [file] [log] [blame]
Pablo Neira Ayuso14506662014-02-20 18:43:15 +01001#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <string.h>
5#include <time.h>
6
7#include <libmnl/libmnl.h>
8#include <net/if.h>
9#include <linux/if_link.h>
10#include <linux/rtnetlink.h>
11
12#include <libgtpnl/gtpnl.h>
13
14#include <linux/gtp_nl.h>
15
16#include "internal.h"
17
18int gtp_dev_create(const char *ifname)
19{
20 struct mnl_socket *nl;
21 char buf[MNL_SOCKET_BUFFER_SIZE];
22 struct nlmsghdr *nlh;
23 struct ifinfomsg *ifm;
24 int ret;
25 unsigned int seq, portid;
26 struct nlattr *nest, *nest2;
27
28 nlh = mnl_nlmsg_put_header(buf);
29 nlh->nlmsg_type = RTM_NEWLINK;
30 nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK;
31 nlh->nlmsg_seq = seq = time(NULL);
32 ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifm));
33 ifm->ifi_family = AF_INET;
34 ifm->ifi_change |= IFF_UP;
35 ifm->ifi_flags |= IFF_UP;
36
37 mnl_attr_put_u32(nlh, IFLA_LINK, if_nametoindex(ifname));
38 nest = mnl_attr_nest_start(nlh, IFLA_LINKINFO);
39 mnl_attr_put_str(nlh, IFLA_INFO_KIND, "gtp");
40 nest2 = mnl_attr_nest_start(nlh, IFLA_INFO_DATA);
41 mnl_attr_put_u32(nlh, IFLA_GTP_LOCAL_ADDR_IPV4, 0);
42 mnl_attr_put_u32(nlh, IFLA_GTP_HASHSIZE, 131072);
43 mnl_attr_nest_end(nlh, nest2);
44 mnl_attr_nest_end(nlh, nest);
45
46 nl = mnl_socket_open(NETLINK_ROUTE);
47 if (nl == NULL) {
48 perror("mnl_socket_open");
49 return -1;
50 }
51
52 if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
53 perror("mnl_socket_bind");
54 return -1;
55 }
56 portid = mnl_socket_get_portid(nl);
57
58 mnl_nlmsg_fprintf(stdout, nlh, nlh->nlmsg_len,
59 sizeof(struct ifinfomsg));
60
61 if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
62 perror("mnl_socket_send");
63 return -1;
64 }
65
66 ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
67 if (ret == -1) {
68 perror("read");
69 return -1;
70 }
71
72 ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);
73 if (ret == -1){
74 perror("callback");
75 return -1;
76 }
77
78 mnl_socket_close(nl);
79
80 return 0;
81}
82EXPORT_SYMBOL(gtp_dev_create);