allow to specify the interface name for the GTP device

We can use this to specify 'gtp0' from openggsn, so we make sure that
it always uses the same tunnel device on creation. If it already exists,
it will return EEXIST. This is used to skip the problem of lacking
NLM_F_ECHO in the rtnetlink link interface that allows us to know the
name of the gtp device that has been dynamically allocated from the
kernel.

And, finally, I don't find any use case for having more than one tunnel
device when integrating this with openggsn.

This patch also adjusts tools/gtp-link-add.c which needs some care, since
it is not yet using any of the library functions. This tools are likely
to be useful for troubleshooting and debugging.
This commit is contained in:
Pablo Neira Ayuso 2014-02-24 11:38:52 +01:00
parent 5747406dbb
commit 1783c7cda4
3 changed files with 20 additions and 9 deletions

View File

@ -14,8 +14,9 @@ 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);
int gtp_dev_create(const char *ifname, int fd0, int fd1);
int gtp_dev_destroy(const char *ifname);
int gtp_dev_create(const char *gtp_ifname, const char *real_ifname,
int fd0, int fd1);
int gtp_dev_destroy(const char *gtp_ifname);
struct gtp_tunnel;

View File

@ -72,7 +72,8 @@ err:
return -1;
}
int gtp_dev_create(const char *ifname, int fd0, int fd1)
int gtp_dev_create(const char *gtp_ifname, const char *real_ifname,
int fd0, int fd1)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
@ -80,13 +81,15 @@ int gtp_dev_create(const char *ifname, int fd0, int fd1)
unsigned int seq = time(NULL);
struct nlattr *nest, *nest2;
nlh = gtp_put_nlmsg(buf, RTM_NEWLINK, NLM_F_CREATE | NLM_F_ACK, seq);
nlh = gtp_put_nlmsg(buf, RTM_NEWLINK,
NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK, seq);
ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifm));
ifm->ifi_family = AF_INET;
ifm->ifi_change |= IFF_UP;
ifm->ifi_flags |= IFF_UP;
mnl_attr_put_u32(nlh, IFLA_LINK, if_nametoindex(ifname));
mnl_attr_put_u32(nlh, IFLA_LINK, if_nametoindex(real_ifname));
mnl_attr_put_str(nlh, IFLA_IFNAME, gtp_ifname);
nest = mnl_attr_nest_start(nlh, IFLA_LINKINFO);
mnl_attr_put_str(nlh, IFLA_INFO_KIND, "gtp");
nest2 = mnl_attr_nest_start(nlh, IFLA_INFO_DATA);
@ -100,7 +103,7 @@ int gtp_dev_create(const char *ifname, int fd0, int fd1)
}
EXPORT_SYMBOL(gtp_dev_create);
int gtp_dev_destroy(const char *ifname)
int gtp_dev_destroy(const char *gtp_ifname)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
@ -112,7 +115,7 @@ int gtp_dev_destroy(const char *ifname)
ifm->ifi_family = AF_INET;
ifm->ifi_change |= IFF_UP;
ifm->ifi_flags &= ~IFF_UP;
ifm->ifi_index = if_nametoindex(ifname);
ifm->ifi_index = if_nametoindex(gtp_ifname);
return gtp_dev_talk(nlh, seq);
}

View File

@ -28,18 +28,25 @@ int main(int argc, char *argv[])
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = RTM_NEWLINK;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL |NLM_F_ACK;
nlh->nlmsg_seq = seq = time(NULL);
ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifm));
ifm->ifi_family = AF_INET;
ifm->ifi_change |= IFF_UP;
ifm->ifi_flags |= IFF_UP;
fprintf(stderr, "WARNING: attaching dummy socket descriptors. Use "
"this command for testing purposes only.\n"):
int fd1 = socket(AF_INET, SOCK_DGRAM, 0);
int fd2 = socket(AF_INET, SOCK_DGRAM, 0);
mnl_attr_put_u32(nlh, IFLA_LINK, if_nametoindex(argv[1]));
mnl_attr_put_str(nlh, IFLA_IFNAME, "gtp0");
nest = mnl_attr_nest_start(nlh, IFLA_LINKINFO);
mnl_attr_put_str(nlh, IFLA_INFO_KIND, "gtp");
nest2 = mnl_attr_nest_start(nlh, IFLA_INFO_DATA);
mnl_attr_put_u32(nlh, IFLA_GTP_LOCAL_ADDR_IPV4, 0);
mnl_attr_put_u32(nlh, IFLA_GTP_FD0, fd1);
mnl_attr_put_u32(nlh, IFLA_GTP_FD1, fd2);
mnl_attr_put_u32(nlh, IFLA_GTP_HASHSIZE, 131072);
mnl_attr_nest_end(nlh, nest2);
mnl_attr_nest_end(nlh, nest);