Commit a8516ff8 authored by Lionel Gauthier's avatar Lionel Gauthier

No need for this module, done in GTPUAH


git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7420 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 3228402a
This diff is collapsed.
How to build
------------
1. Extract the files in a location of your choice. The
Files will be extracted in a directory called gtpu.
2. cd <gtpu_dir>/gtpu.
3. make
If make is successful, the binary files (libxt_GTPU.so and xt_GTPU.ko)
will be created in the Bin folder.
How to install
--------------
There is no "make install" as that will be difficult to support all
possible Linux distro. The cmd.sh file demonstrates how to install
the two binary files in the system.
In case of problem:
- check you got the last release of the library (see README),
- contact the mailing list (see README),
- check the bugtracker for known bugs (see README).
Documentation
-------------
Please have a look at the "Architecture" section in the README.
####################################################################################
# Makefile for iptables extension for the GTPU target and GTPu klm
#
# Copyright (c) 2010-2011 Polaris Networks
# Author: Pradip Biswas <pradip_biswas@polarisnetworks.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
####################################################################################
export BIN_DIR ?= $(shell pwd)/Bin
KVERSION = $(shell uname -r)
KVERSION_LAST_DIGIT = $(shell echo ${KVERSION} | cut -d "." -f 3 | cut -d "-" -f 1)
obj-m = xt_GTPURH.o
EXTRA_CFLAGS += -DKVERSION=$(KVERSION_LAST_DIGIT)
all: xtlib
echo "Building for Kernel Version: $(KVERSION_LAST_DIGIT)"
make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
chmod 777 xt_GTPURH.ko
mv xt_GTPURH.ko $(BIN_DIR)/
clean: libclean
make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
################################################################################
# The next section is used by libxt_GTPURH
################################################################################
XT_IPTABLES_VERSION = $(shell /sbin/iptables -V | cut -d " " -f 2 | cut -b 2-)
IPT_FIRST_NUM = $(shell echo ${XT_IPTABLES_VERSION} | cut -d "." -f 1 | cut -d "-" -f 1)
IPT_SECOND_NUM = $(shell echo ${XT_IPTABLES_VERSION} | cut -d "." -f 2 | cut -d "-" -f 1)
IPT_THIRD_NUM = $(shell echo ${XT_IPTABLES_VERSION} | cut -d "." -f 3 | cut -d "-" -f 1)
IPTVERSION = $(IPT_FIRST_NUM)$(IPT_SECOND_NUM)$(IPT_THIRD_NUM)
IPTABLES_VERSION_STRING = \"$(IPT_FIRST_NUM).$(IPT_SECOND_NUM).$(IPT_THIRD_NUM)\"
LIB_CC := gcc
ifeq ($(IPTVERSION), 135)
LIB_LD := ld
else
LIB_LD := gcc
endif
LIB_CFLAGS := -fPIC -Wall -MMD -D_LARGEFILE_SOURCE=1 -D_LARGE_FILES -D_FILE_OFFSET_BITS=64 \
-D_REENTRANT -pipe -DXTABLES_LIBDIR=\"/usr/local/libexec/xtables\" -DXTABLES_INTERNAL \
-D_INIT=libxt_GTPURH_init -DPIC -fPIC -O2 \
-DIPTVERSION=$(IPTVERSION) \
-DIPTABLES_VERSION_STRING=$(IPTABLES_VERSION_STRING)
XT_TARGET := xt_GTPURH
XT_LIBNAME := lib$(XT_TARGET).so
XT_BUILD_DIR = $(BIN_DIR)/$(XT_TARGET)
# Get the system distribution type
IsDebian=$(shell /bin/cat /proc/version | grep -i -e ubuntu -e debian)
IsRedHat=$(shell /bin/cat /proc/version | grep -i -e centos -e "red hat" -e suse -e fedora)
# Change the ipq library name for 64-bit Debian-based distributions
ifeq ($(X86_64),x86_64)
ifneq ($(strip $(IsDebian)),)
LIB_IPQ=_pic
endif
endif
INCLUDE_DIR = -I. \
-I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include \
-I/usr/lib64/glib-2.0/include
XT_SOURCES = libxt_GTPURH.c
XT_OBJECTS := $(addprefix $(XT_BUILD_DIR)/, $(notdir $(XT_SOURCES:.c=.o)))
xtlib: XT
XT: DF = $(XT_BUILD_DIR)/$(*F)
XT: $(XT_BUILD_DIR) $(BIN_DIR)/$(XT_LIBNAME)
-include $(addprefix $(XT_BUILD_DIR)/, $(notdir $(XT_SOURCES:.c=.P)))
$(XT_BUILD_DIR):
@echo Build Directory is $@
@if [ ! -d $(BIN_DIR) ]; then mkdir $(BIN_DIR); fi
@if [ ! -d $@ ]; then mkdir $@; fi
$(BIN_DIR)/$(XT_LIBNAME): $(XT_OBJECTS)
@echo Linking $@
@$(LIB_LD) -shared $(XT_OBJECTS) -o $@
$(XT_BUILD_DIR)/%.o : %.c
@echo "Building GTPuRH ext for version $(IPTVERSION) $(IPTABLES_VERSION_STRING)"
@echo Compiling $<
@$(LIB_CC) $(LIB_CFLAGS) -MF $(DF).d $(INCLUDE_DIR) -o $@ -c $<
@cp $(DF).d $(DF).P; \
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $(DF).d >> $(DF).P; \
rm -f $(DF).d
libclean:
@rm -rf $(BIN_DIR)/$(XT_LIBNAME) $(XT_BUILD_DIR)
Introduction
------------
This piece of software implementes GPRS Tunneling Protocol (GTP) for user plane.
The software has two components - one is the extension of iptables that
run in user-space. The other is the counterpart of the iptables extension
that runs in kernel space.
License
-------
The project is licensed under GPL2+, see the COPYING and AUTHORS files for more
details.
Architecture
------------
The GTPu tunneling is handled in two parts. The first part is the user-space
iptables target extension library (let's call it libxt). The second
part is the GTPu kernel loadable module (let's call it gtpu). The way it
is, once the user configures a GTPu tunnel attributes using iptables, the klm
is loaded by the kernel automatically and handles the IP packets according to
the GTPu tunnel attributes set by the user.
The user can set the action to be taken on a matching IP packet. The action can be
either of "add", "remove" or "transport" .
A GTPu tunnel has the following attributes:
- own IP address
- own GTPu tunnel id
- peer's IP address
- peer's GTPu tunnel id
The GTPU target is designed to work only on mangle table. Also, the user is
expected to add GTPU target to the PREROUTING chain, as the GTPU target will
modify the original IP packet before it is routed.
Once the user creates the rule in iptables, the matching IP packets go through
the gtpu klm, which acts upon the IP packet according to the action set by the
user. The action "Add" means the klm will add a GTPu header to the IP packet.
"Remove" will remove the GTPu header from the IP packet and "Transport" will
do a Remove first followed by an "Add" on the IP packet.
For example, consider the following command:
iptables -t mangle -A PREROUTING -d 10.10.10.1 -j GTPU --own-ip 192.168.0.98 --own-tun 100 --peer-ip 192.168.0.109 --peer-tun 101 --action add
This command will configure the system to add a GTPu header to any IP packet destined to 10.10.10.1.
The source IP address outer IP will be 192.168.0.109, the dest IP will be 192.168.0.98 and
the destination GTP tunnel id will be 101.
Similarly, consider the following command:
iptables -t mangle -A PREROUTING -s 192.168.0.109 -d 192.168.0.98 -p udp --dport 2152 -j GTPU --action remove
This command will process all the GTPu packets coming from 192.168.0.109 to 192.168.0.98 to
strip the GTPu header and forward the inner IP packet to the kernel's routing engine.
Files
---------
There are two source C files and one header file:
- libxt_GTPU.c : source file for iptables GTPU extension library (libxt)
- xt_GTPU.c : source file for gtpu kernel loadable module (klm)
- xt_GTPU.h : common header file, shared between the libxt and the klm
- Makefile : Makefile to build both the libxt and the klm
- cmd.sh : sample cmd file to show how the binaries can be used
See the INSTALL file to learn how to build the binaries.
References
----------
3GPP TS 29.281 General Packet Radio System (GPRS)
Tunnelling Protocol User Plane (GTP-u)
Authors
-------
Pradip Biswas <pradip_biswas@polarisnetworks.net>
Known issues in GTPU v1.0
-------------------------
1. Does not implement the "Transport" action.
2. Does not handle segmented GTPu packets.
# Clear the iptables mangle table
iptables -t mangle -F
# Remove GTPU KLM
rmmod xt_GTPU
# Insert the GTPU KLM
insmod ./Bin/xt_GTPU.ko
# Copy the userland iptables extenstion library
if [ -d /lib/xtables ]; then
/bin/cp -f ./Bin/libxt_GTPU.so /lib/xtables/
fi
if [ -d /lib/iptables ]; then
/bin/cp -f ./Bin/libxt_GTPU.so /lib/iptables/libipt_GTPU.so
fi
# Some sample commands for demonstration
iptables -t mangle -A PREROUTING -d 10.10.10.1 -j GTPU --own-ip 192.168.0.98 --own-tun 100 --peer-ip 192.168.0.109 --peer-tun 101 --action add
iptables -t mangle -A PREROUTING -s 192.168.0.109 -d 192.168.0.98 -p udp --dport 2152 -j GTPU --action remove
/* Shared library add-on to iptables for the GTPURH target
*
* Copyright (c) 2010-2011 Polaris Networks
* Author: Pradip Biswas <pradip_biswas@polarisnetworks.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <getopt.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/netfilter.h>
#include "xt_GTPURH.h"
#if (IPTVERSION <= 135)
#include <iptables.h>
#elif (IPTVERSION > 135)
#include <xtables.h>
#endif
#if (IPTVERSION <= 135)
#define GTPURH_PARAM_BAD_VALUE 0
#define GTPURH_PARAM_ONLY_ONCE 1
#define XT_GTPURH_VERSION IPTABLES_VERSION_STRING
#define gtpurh_strtoui(s,v,m,M) !string_to_number(s,m,M,v)
#define gtpurh_exit_error exit_error
#elif (IPTVERSION > 135) && (IPTVERSION <= 141)
#define GTPURH_PARAM_BAD_VALUE P_BAD_VALUE
#define GTPURH_PARAM_ONLY_ONCE P_ONLY_ONCE
#define XT_GTPURH_VERSION XTABLES_VERSION
#define gtpurh_param_act param_act
#define gtpurh_strtoui(s,v,m,M) !string_to_number(s,m,M,v)
#define gtpurh_exit_error exit_error
#elif (IPTVERSION > 141)
#define GTPURH_PARAM_BAD_VALUE XTF_BAD_VALUE
#define GTPURH_PARAM_ONLY_ONCE XTF_ONLY_ONCE
#define XT_GTPURH_VERSION XTABLES_VERSION
#define gtpurh_param_act xtables_param_act
#define gtpurh_strtoui(s,v,m,M) xtables_strtoui(s,NULL,v,m,M)
#define gtpurh_exit_error xtables_error
#endif
enum {
PARAM_LADDR = 1 << 0,
PARAM_LTUN = 1 << 1,
PARAM_RADDR = 1 << 2,
PARAM_RTUN = 1 << 3,
PARAM_ACTION = 1 << 4,
};
static void GTPURH_help(void)
{
printf(
"GTPUAH target options\n"
" --action value Set action <value: remove>\n"
" --own-ip value Set own IP address\n"
" --own-tun value Set own tunnel id <value: 1-2^31>\n"
" --peer-ip value Set peer IP address\n"
" --peer-tun value Set peer tunnel id <value: 1-2^31>\n");
}
#if (IPTVERSION <= 135)
/* Stolen from iptables v1.4.7 code */
void gtpurh_param_act(unsigned int status, const char *p1, ...)
{
const char *p2, *p3;
va_list args;
int b;
va_start(args, p1);
switch (status) {
case GTPURH_PARAM_ONLY_ONCE:
p2 = va_arg(args, const char *);
b = va_arg(args, unsigned int);
if (!b)
return;
exit_error(PARAMETER_PROBLEM,
"%s: \"%s\" option may only be specified once",
p1, p2);
break;
case GTPURH_PARAM_BAD_VALUE:
p2 = va_arg(args, const char *);
p3 = va_arg(args, const char *);
exit_error(PARAMETER_PROBLEM,
"%s: Bad value for \"%s\" option: \"%s\"",
p1, p2, p3);
break;
default:
exit_error(status, "%s", "Unknown error");
break;
}
va_end(args);
}
#endif
static void parse_gtpurh_addr(const char *s, struct xt_gtpurh_target_info *info, int flag)
{
in_addr_t addr;
if ((addr = inet_addr(s)) == -1) {
switch (flag) {
case PARAM_LADDR:
gtpurh_param_act(GTPURH_PARAM_BAD_VALUE, "GTPURH", "--own-ip", s);
break;
case PARAM_RADDR:
gtpurh_param_act(GTPURH_PARAM_BAD_VALUE, "GTPURH", "--peer-ip", s);
break;
}
}
switch (flag) {
case PARAM_LADDR:
info->laddr = addr;
break;
case PARAM_RADDR:
info->raddr = addr;
break;
}
}
static void parse_gtpurh_tunid(char *s, struct xt_gtpurh_target_info *info, int flag)
{
unsigned int value;
if (!gtpurh_strtoui(s, &value, 0, UINT32_MAX)) {
switch (flag) {
case PARAM_LTUN:
gtpurh_param_act(GTPURH_PARAM_BAD_VALUE, "GTPURH", "--own-tun", s);
break;
case PARAM_RTUN:
gtpurh_param_act(GTPURH_PARAM_BAD_VALUE, "GTPURH", "--peer-tun", s);
break;
}
}
switch (flag) {
case PARAM_LTUN:
info->ltun = value;
break;
case PARAM_RTUN:
info->rtun = value;
break;
}
}
static void parse_gtpurh_action(char *s, struct xt_gtpurh_target_info *info, unsigned int *flags)
{
if (!strcmp(s, "remove")) {
info->action = PARAM_GTPURH_ACTION_REM;
*flags |= PARAM_GTPURH_ACTION_REM;
} else {
gtpurh_param_act(GTPURH_PARAM_BAD_VALUE, "GTPURH", "--action", s);
}
}
#if (IPTVERSION <= 135)
static int
GTPURH_parse(int c, char **argv, int invert, unsigned int *flags,
const struct ipt_entry *entry,
struct ipt_entry_target **target)
#else
static int
GTPURH_parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_target **target)
#endif
{
struct xt_gtpurh_target_info *info = (struct xt_gtpurh_target_info *) (*target)->data;
switch (c) {
case '1':
gtpurh_param_act(GTPURH_PARAM_ONLY_ONCE, "GTPURH", "--own-ip", *flags & PARAM_LADDR);
parse_gtpurh_addr(optarg, info, PARAM_LADDR);
*flags |= PARAM_LADDR;
return 1;
case '2':
gtpurh_param_act(GTPURH_PARAM_ONLY_ONCE, "GTPURH", "--own-tun", *flags & PARAM_LTUN);
parse_gtpurh_tunid(optarg, info, PARAM_LTUN);
*flags |= PARAM_LTUN;
return 1;
case '3':
gtpurh_param_act(GTPURH_PARAM_ONLY_ONCE, "GTPURH", "--peer-ip", *flags & PARAM_RADDR);
parse_gtpurh_addr(optarg, info, PARAM_RADDR);
*flags |= PARAM_RADDR;
return 1;
case '4':
gtpurh_param_act(GTPURH_PARAM_ONLY_ONCE, "GTPURH", "--peer-tun", *flags & PARAM_RTUN);
parse_gtpurh_tunid(optarg, info, PARAM_RTUN);
*flags |= PARAM_RTUN;
return 1;
case '5':
gtpurh_param_act(GTPURH_PARAM_ONLY_ONCE, "GTPURH", "--action", *flags & PARAM_ACTION);
parse_gtpurh_action(optarg, info, flags);
*flags |= PARAM_ACTION;
return 1;
}
return 1;
}
static void GTPURH_check(unsigned int flags)
{
if (!(flags & PARAM_ACTION)) {
gtpurh_exit_error(PARAMETER_PROBLEM, "GTPURH: You must specify action");
}
if (!(flags & PARAM_LADDR)) {
gtpurh_exit_error(PARAMETER_PROBLEM, "GTPURH: You must specify local addr");
}
if (!(flags & PARAM_LTUN)) {
gtpurh_exit_error(PARAMETER_PROBLEM, "GTPURH: You must specify local tunnel id");
}
if (!(flags & PARAM_RADDR)) {
gtpurh_exit_error(PARAMETER_PROBLEM, "GTPURH: You must specify remote addr");
}
if (!(flags & PARAM_RTUN)) {
gtpurh_exit_error(PARAMETER_PROBLEM, "GTPURH: You must specify remote tunnel id");
}
}
static void convert_action_to_string(int action, char *actionstr)
{
switch(action) {
case PARAM_GTPURH_ACTION_REM:
sprintf (actionstr, "remove");
break;
default :
sprintf (actionstr, "unspecified!!!");
break;
}
}
#if (IPTVERSION <= 135)
static void
GTPURH_print(const struct ipt_ip *ip,
const struct ipt_entry_target *target,
int numeric)
#else
static void
GTPURH_print(const void *ip,
const struct xt_entry_target *target,
int numeric)
#endif
{
const struct xt_gtpurh_target_info *info =
(struct xt_gtpurh_target_info *) target->data;
char laddr[64], raddr[64], actionstr[32];
convert_action_to_string(info->action, actionstr);
if (info->action == PARAM_GTPURH_ACTION_REM) {
printf("GTPURH action: %s", actionstr);
return;
}
}
static struct option GTPURH_opts[] = {
{ "own-ip", 1, NULL, '1' },
{ "own-tun", 1, NULL, '2' },
{ "peer-ip", 1, NULL, '3' },
{ "peer-tun", 1, NULL, '4' },
{ "action", 1, NULL, '5' },
{ .name = NULL }
};
#if (IPTVERSION <= 135)
static struct iptables_target gtpurh_tg_reg = {
#else
static struct xtables_target gtpurh_tg_reg = {
#endif
.name = "GTPURH",
.version = XT_GTPURH_VERSION,
#if (IPTVERSION > 135)
.family = NFPROTO_IPV4,
#endif
.size = XT_ALIGN(sizeof(struct xt_gtpurh_target_info)),
.userspacesize = XT_ALIGN(sizeof(struct xt_gtpurh_target_info)),
.help = GTPURH_help,
.parse = GTPURH_parse,
.final_check = GTPURH_check,
.print = GTPURH_print,
.extra_opts = GTPURH_opts,
};
void _init(void)
{
#if (IPTVERSION <= 135)
register_target(&gtpurh_tg_reg);
#else
xtables_register_target(&gtpurh_tg_reg);
#endif
}
This diff is collapsed.
/* Shared header file for iptables extension for the GTPU target and GTPu KLM
*
* Copyright (c) 2010-2011 Polaris Networks
* Author: Pradip Biswas <pradip_biswas@polarisnetworks.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
enum xt_gtpurh_mode_ {
PARAM_GTPURH_ACTION_REM = 1 << 9,
};
struct xt_gtpurh_target_info {
u_int32_t laddr __attribute__((aligned(8)));
u_int32_t raddr __attribute__((aligned(8)));
u_int32_t ltun __attribute__((aligned(8)));
u_int32_t rtun __attribute__((aligned(8)));
u_int32_t action __attribute__((aligned(8)));
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment