diff options
author | Harald Welte <laforge@gnumonks.org> | 2017-03-15 18:03:42 +0100 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2017-03-15 21:05:50 +0100 |
commit | 24f2f694a3be96155c07baea7f493088fc1d1b24 (patch) | |
tree | 9125f97a2118497c6c764960844f8b662c05e2c7 | |
parent | fab15163721616e44a60c1342cda32d4e9d02762 (diff) |
Add support for SGSN role via IFLA_GTP_ROLE
This patch corresponds to a Linux kernel patch extending the kernel GTP
to also cover the SGSN role, not just the GGSN role. In order to keep
the API/behavior compatible, gtp_dev_create() will continue to create
GGSN-side tunnels, while a new gtp_dev_create_sgsn() is introduced to
create SGSN-side tunnels.
Signed-off-by: Harald Welte <laforge@gnumonks.org>
-rw-r--r-- | include/libgtpnl/gtpnl.h | 1 | ||||
-rw-r--r-- | include/linux/if_link.h | 7 | ||||
-rw-r--r-- | src/gtp-rtnl.c | 16 | ||||
-rw-r--r-- | src/libgtpnl.map | 1 | ||||
-rw-r--r-- | tools/gtp-link.c | 12 |
5 files changed, 33 insertions, 4 deletions
diff --git a/include/libgtpnl/gtpnl.h b/include/libgtpnl/gtpnl.h index 49ba03d..33bb275 100644 --- a/include/libgtpnl/gtpnl.h +++ b/include/libgtpnl/gtpnl.h @@ -17,6 +17,7 @@ int genl_lookup_family(struct mnl_socket *nl, const char *family); struct in_addr; int gtp_dev_create(int dest_ns, const char *gtp_ifname, int fd0, int fd1); +int gtp_dev_create_sgsn(int dest_ns, const char *gtp_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); diff --git a/include/linux/if_link.h b/include/linux/if_link.h index a3f53c9..c66ebbd 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h @@ -518,11 +518,18 @@ enum { #define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1) /* GTP section */ + +enum ifla_gtp_role { + GTP_ROLE_GGSN = 0, + GTP_ROLE_SGSN, +}; + enum { IFLA_GTP_UNSPEC, IFLA_GTP_FD0, IFLA_GTP_FD1, IFLA_GTP_PDP_HASHSIZE, + IFLA_GTP_ROLE, __IFLA_GTP_MAX, }; #define IFLA_GTP_MAX (__IFLA_GTP_MAX - 1) diff --git a/src/gtp-rtnl.c b/src/gtp-rtnl.c index 6bfec65..1dfd125 100644 --- a/src/gtp-rtnl.c +++ b/src/gtp-rtnl.c @@ -105,7 +105,8 @@ static int gtp_dev_talk(struct nlmsghdr *nlh, uint32_t seq) return ret; } -int gtp_dev_create(int dest_ns, const char *gtp_ifname, int fd0, int fd1) +static int _gtp_dev_create(int dest_ns, const char *gtp_ifname, int fd0, + int fd1, enum ifla_gtp_role role) { char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; @@ -129,13 +130,26 @@ int gtp_dev_create(int dest_ns, const char *gtp_ifname, int fd0, int fd1) mnl_attr_put_u32(nlh, IFLA_GTP_FD0, fd0); mnl_attr_put_u32(nlh, IFLA_GTP_FD1, fd1); mnl_attr_put_u32(nlh, IFLA_GTP_PDP_HASHSIZE, 131072); + if (role != GTP_ROLE_GGSN) + mnl_attr_put_u32(nlh, IFLA_GTP_ROLE, role); mnl_attr_nest_end(nlh, nest2); mnl_attr_nest_end(nlh, nest); return gtp_dev_talk(nlh, seq); } + +int gtp_dev_create(int dest_ns, const char *gtp_ifname, int fd0, int fd1) +{ + return _gtp_dev_create(dest_ns, gtp_ifname, fd0, fd1, GTP_ROLE_GGSN); +} EXPORT_SYMBOL(gtp_dev_create); +int gtp_dev_create_sgsn(int dest_ns, const char *gtp_ifname, int fd0, int fd1) +{ + return _gtp_dev_create(dest_ns, gtp_ifname, fd0, fd1, GTP_ROLE_SGSN); +} +EXPORT_SYMBOL(gtp_dev_create_sgsn); + int gtp_dev_destroy(const char *gtp_ifname) { char buf[MNL_SOCKET_BUFFER_SIZE]; diff --git a/src/libgtpnl.map b/src/libgtpnl.map index 9ca83c7..9ce465d 100644 --- a/src/libgtpnl.map +++ b/src/libgtpnl.map @@ -6,6 +6,7 @@ global: genl_lookup_family; gtp_dev_create; + gtp_dev_create_sgsn; gtp_dev_config; gtp_dev_destroy; diff --git a/tools/gtp-link.c b/tools/gtp-link.c index 97dfa45..8367c6e 100644 --- a/tools/gtp-link.c +++ b/tools/gtp-link.c @@ -43,9 +43,9 @@ int main(int argc, char *argv[]) { char buf[MNL_SOCKET_BUFFER_SIZE]; - int ret; + int ret, sgsn_mode = 0; - if (argc != 3) { + if (argc < 3) { printf("Usage: %s <add|del> <device>\n", argv[0]); exit(EXIT_FAILURE); } @@ -58,6 +58,9 @@ int main(int argc, char *argv[]) return 0; } + if (argc > 3 && !strcmp(argv[3], "--sgsn")) + sgsn_mode = 1; + int fd1 = socket(AF_INET, SOCK_DGRAM, 0); int fd2 = socket(AF_INET, SOCK_DGRAM, 0); struct sockaddr_in sockaddr_fd1 = { @@ -86,7 +89,10 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } - ret = gtp_dev_create(-1, argv[2], fd1, fd2); + if (sgsn_mode) + ret = gtp_dev_create_sgsn(-1, argv[2], fd1, fd2); + else + ret = gtp_dev_create(-1, argv[2], fd1, fd2); if (ret < 0) { perror("cannot create GTP device\n"); exit(EXIT_FAILURE); |