Skip to content

Commit

Permalink
Merge pull request FDio#31 from TetsuyaMurakami/ietf105-hackathon
Browse files Browse the repository at this point in the history
  • Loading branch information
matsusato3 authored Jul 17, 2019
2 parents ad4849d + d8a6e0d commit 2ac064c
Show file tree
Hide file tree
Showing 7 changed files with 690 additions and 57 deletions.
128 changes: 127 additions & 1 deletion extras/ietf105/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,128 @@ def test_tmap_ipv6(self):
for p in c4.pg_read_packets():
p.show2()

def test_gtp4(self):
# TESTS:
# trace add af-packet-input 10
# pg interface on c1 172.20.0.1
# pg interface on c4 B::1/120

self.start_containers()

c1 = self.containers.get(self.get_name(self.instance_names[0]))
c2 = self.containers.get(self.get_name(self.instance_names[1]))
c3 = self.containers.get(self.get_name(self.instance_names[2]))
c4 = self.containers.get(self.get_name(self.instance_names[-1]))

c1.pg_create_interface4(local_ip="172.16.0.1/30", remote_ip="172.16.0.2/30",
local_mac="aa:bb:cc:dd:ee:01", remote_mac="aa:bb:cc:dd:ee:02")
c4.pg_create_interface4(local_ip="1.0.0.2/30", remote_ip="1.0.0.1",
local_mac="aa:bb:cc:dd:ee:11", remote_mac="aa:bb:cc:dd:ee:22")

c1.vppctl_exec("set sr encaps source addr A1::1")
c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
c1.vppctl_exec("sr localsid prefix ::ffff:ac14:0001/128 behavior end.m.gtp4.d D4::/32 v6src_prefix C1::/64")

c2.vppctl_exec("sr localsid address D2:: behavior end")

c3.vppctl_exec("sr localsid address D3:: behavior end")

c4.vppctl_exec("sr localsid prefix D4::/32 behavior end.m.gtp4.e v4src_position 64")

#c1.set_ipv6_route("eth1", "A1::2", "D2::/128")
c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
c2.set_ipv6_route("eth1", "A1::1", "C::/120")
c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
c3.set_ipv6_route("eth1", "A2::1", "C::/120")
c4.set_ip_pgroute("pg0", "1.0.0.1", "172.20.0.1/32")

p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01")/
IP(src="172.20.0.2", dst="172.20.0.1")/
UDP(sport=2152, dport=2152)/
GTP_U_Header(gtp_type="g_pdu", teid=200)/
IP(src="172.99.0.1", dst="172.99.0.2")/
ICMP())

print("Sending packet on {}:".format(c1.name))
p.show2()

c1.enable_trace(10)
c4.enable_trace(10)

c4.pg_start_capture()

c1.pg_create_stream(p)
c1.pg_enable()

# timeout (sleep) if needed
print("Sleeping")
time.sleep(5)

print("Receiving packet on {}:".format(c4.name))
for p in c4.pg_read_packets():
p.show2()

def test_gtp4_ipv6(self):
# TESTS:
# trace add af-packet-input 10
# pg interface on c1 172.20.0.1
# pg interface on c4 B::1/120

self.start_containers()


c1 = self.containers.get(self.get_name(self.instance_names[0]))
c2 = self.containers.get(self.get_name(self.instance_names[1]))
c3 = self.containers.get(self.get_name(self.instance_names[2]))
c4 = self.containers.get(self.get_name(self.instance_names[-1]))

c1.pg_create_interface4(local_ip="172.16.0.1/30", remote_ip="172.16.0.2/30",
local_mac="aa:bb:cc:dd:ee:01", remote_mac="aa:bb:cc:dd:ee:02")
c4.pg_create_interface4(local_ip="1.0.0.2/30", remote_ip="1.0.0.1",
local_mac="aa:bb:cc:dd:ee:11", remote_mac="aa:bb:cc:dd:ee:22")

c1.vppctl_exec("set sr encaps source addr A1::1")
c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
c1.vppctl_exec("sr localsid prefix ::ffff:ac14:0001/128 behavior end.m.gtp4.d D4::/32 v6src_prefix C1::/64")

c2.vppctl_exec("sr localsid address D2:: behavior end")

c3.vppctl_exec("sr localsid address D3:: behavior end")

c4.vppctl_exec("sr localsid prefix D4::/32 behavior end.m.gtp4.e v4src_position 64")

c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
c2.set_ipv6_route("eth1", "A1::1", "C::/120")
c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
c3.set_ipv6_route("eth1", "A2::1", "C::/120")
c4.set_ip_pgroute("pg0", "1.0.0.1", "172.20.0.1/32")

p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01")/
IP(src="172.20.0.2", dst="172.20.0.1")/
UDP(sport=2152, dport=2152)/
GTP_U_Header(gtp_type="g_pdu", teid=200)/
IPv6(src="2001::1", dst="2002::1")/
ICMPv6EchoRequest())

print("Sending packet on {}:".format(c1.name))
p.show2()

c1.enable_trace(10)
c4.enable_trace(10)

c4.pg_start_capture()

c1.pg_create_stream(p)
c1.pg_enable()

# timeout (sleep) if needed
print("Sleeping")
time.sleep(5)

print("Receiving packet on {}:".format(c4.name))
for p in c4.pg_read_packets():
p.show2()

def test_gtp6_drop_in(self):
# TESTS:
# trace add af-packet-input 10
Expand Down Expand Up @@ -995,7 +1117,7 @@ def get_args():
help="Test related commands.")

p3.add_argument("op", choices=[
"ping", "srv6", "tmap", "tmap_ipv6", "gtp6_drop_in", "gtp6_drop_in_ipv6", "gtp6", "gtp6_ipv6"])
"ping", "srv6", "tmap", "tmap_ipv6", "gtp4", "gtp4_ipv6", "gtp6_drop_in", "gtp6_drop_in_ipv6", "gtp6", "gtp6_ipv6"])

args = parser.parse_args()
if not hasattr(args, "op") or not args.op:
Expand Down Expand Up @@ -1042,6 +1164,10 @@ def main(op=None, prefix=None, verbose=None, image=None, index=None, command=Non
program.test_tmap()
elif op == 'tmap_ipv6':
program.test_tmap_ipv6()
elif op == 'gtp4':
program.test_gtp4()
elif op == 'gtp4_ipv6':
program.test_gtp4_ipv6()
elif op == 'gtp6_drop_in':
program.test_gtp6_drop_in()
elif op == 'gtp6_drop_in_ipv6':
Expand Down
1 change: 1 addition & 0 deletions src/plugins/srv6-mobile/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
add_vpp_plugin(srv6mobile
SOURCES
gtp4_e.c
gtp4_d.c
gtp6_e.c
gtp6_d.c
gtp6_d_di.c
Expand Down
190 changes: 190 additions & 0 deletions src/plugins/srv6-mobile/gtp4_d.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
/*
* srv6_end_m_gtp4_d.c
*
* Copyright (c) 2019 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <vnet/vnet.h>
#include <vnet/adj/adj.h>
#include <vnet/plugin/plugin.h>
#include <vpp/app/version.h>
#include <srv6-mobile/mobile.h>

srv6_end_main_v4_decap_t srv6_end_main_v4_decap;

static void
clb_dpo_lock_srv6_end_m_gtp4_d (dpo_id_t * dpo)
{
}

static void
clb_dpo_unlock_srv6_end_m_gtp4_d (dpo_id_t * dpo)
{
}

static u8 *
clb_dpo_format_srv6_end_m_gtp4_d (u8 * s, va_list * args)
{
index_t index = va_arg (*args, index_t);
CLIB_UNUSED (u32 indent) = va_arg (*args, u32);

return (format (s, "SR: dynamic_proxy_index:[%u]", index));
}

const static dpo_vft_t dpo_vft = {
.dv_lock = clb_dpo_lock_srv6_end_m_gtp4_d,
.dv_unlock = clb_dpo_unlock_srv6_end_m_gtp4_d,
.dv_format = clb_dpo_format_srv6_end_m_gtp4_d,
};

const static char *const srv6_end_m_gtp4_d_nodes[] = {
"srv6-end-m-gtp4-d",
NULL,
};

const static char *const *const dpo_nodes[DPO_PROTO_NUM] = {
[DPO_PROTO_IP4] = srv6_end_m_gtp4_d_nodes,
};

static u8 fn_name[] = "SRv6-End.M.GTP4.D-plugin";
static u8 keyword_str[] = "end.m.gtp4.d";
static u8 def_str[] = "Endpoint function with dencapsulation for IPv6/GTP tunnel";
static u8 param_str[] = "<sr-prefix>/<sr-prefixlen> v6src_prefix <v6src_prefix>/<prefixlen>";

static u8 *
clb_format_srv6_end_m_gtp4_d (u8 * s, va_list * args)
{
srv6_end_gtp4_param_t *ls_mem = va_arg (*args, void *);

s = format (s, "SRv6 End gtp4.d\n\t");

s = format (s, "SR Prefix: %U/%d, ", format_ip6_address, &ls_mem->sr_prefix, ls_mem->sr_prefixlen);

s = format (s, "v6src Prefix: %U/%d\n", format_ip6_address, &ls_mem->v6src_prefix, ls_mem->v6src_prefixlen);

return s;
}

static uword
clb_unformat_srv6_end_m_gtp4_d (unformat_input_t * input, va_list * args)
{
void **plugin_mem_p = va_arg (*args, void **);
srv6_end_gtp4_param_t *ls_mem;
ip6_address_t sr_prefix;
u32 sr_prefixlen;
ip6_address_t v6src_prefix;
u32 v6src_prefixlen;

if (!unformat (input, "end.m.gtp4.d %U/%d v6src_prefix %U/%d",
unformat_ip6_address, &sr_prefix, &sr_prefixlen,
unformat_ip6_address, &v6src_prefix, &v6src_prefixlen))
{
return 0;
}

ls_mem = clib_mem_alloc_aligned_at_offset (sizeof *ls_mem, 0, 0, 1);
clib_memset (ls_mem, 0, sizeof *ls_mem);
*plugin_mem_p = ls_mem;

ls_mem->sr_prefix = sr_prefix;
ls_mem->sr_prefixlen = sr_prefixlen;

ls_mem->v6src_prefix = v6src_prefix;
ls_mem->v6src_prefixlen = v6src_prefixlen;

return 1;
}

static int
clb_creation_srv6_end_m_gtp4_d (ip6_sr_localsid_t * localsid)
{
return 0;
}

static int
clb_removal_srv6_end_m_gtp4_d (ip6_sr_localsid_t * localsid)
{
srv6_end_gtp4_param_t *ls_mem;

ls_mem = localsid->plugin_mem;

clib_mem_free (ls_mem);

return 0;
}

static clib_error_t *
srv6_end_m_gtp4_d_init (vlib_main_t * vm)
{
srv6_end_main_v4_decap_t *sm = &srv6_end_main_v4_decap;
ip6_header_t *ip6;
dpo_type_t dpo_type;
vlib_node_t *node;
u32 rc;

sm->vlib_main = vm;
sm->vnet_main = vnet_get_main ();

node = vlib_get_node_by_name (vm, (u8 *) "srv6-end-m-gtp4-d");
sm->end_m_gtp4_d_node_index = node->index;

node = vlib_get_node_by_name (vm, (u8 *) "error-drop");
sm->error_node_index = node->index;

ip6 = &sm->cache_hdr;

clib_memset_u8 (ip6, 0, sizeof(ip6_header_t));

// IPv6 header (default)
ip6->ip_version_traffic_class_and_flow_label = 0x60;
ip6->hop_limit = 64;
ip6->protocol = IP_PROTOCOL_IPV6;

dpo_type = dpo_register_new_type (&dpo_vft, dpo_nodes);

rc = sr_localsid_register_function (vm,
fn_name,
keyword_str,
def_str,
param_str,
128, //prefix len
&dpo_type,
clb_format_srv6_end_m_gtp4_d,
clb_unformat_srv6_end_m_gtp4_d,
clb_creation_srv6_end_m_gtp4_d,
clb_removal_srv6_end_m_gtp4_d);
if (rc < 0)
clib_error_return (0, "SRv6 Endpoint GTP4.D LocalSID function"
"couldn't be registered");
return 0;
}

/* *INDENT-OFF* */
VNET_FEATURE_INIT (srv6_end_m_gtp4_d, static) =
{
.arc_name = "ip4-unicast",
.node_name = "srv6-end-m-gtp4-d",
.runs_before = 0,
};

VLIB_INIT_FUNCTION (srv6_end_m_gtp4_d_init);
/* *INDENT-ON* */

/*
* fd.io coding-style-patch-verification: ON
*
* Local Variables:
* eval: (c-set-style "gnu")
* End:
*/
8 changes: 4 additions & 4 deletions src/plugins/srv6-mobile/gtp4_e.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ clb_format_srv6_end_m_gtp4_e (u8 * s, va_list * args)

s = format (s, "SRv6 End gtp4.e\n\t");

s = format (s, "IPv4 address position: %d\n", ls_mem->local_prefixlen);
s = format (s, "IPv4 address position: %d\n", ls_mem->v4src_position);

return s;
}
Expand All @@ -79,17 +79,17 @@ clb_unformat_srv6_end_m_gtp4_e (unformat_input_t * input, va_list * args)
{
void **plugin_mem_p = va_arg (*args, void **);
srv6_end_gtp4_param_t *ls_mem;
u32 local_prefixlen;
u32 v4src_position;

if (!unformat (input, "end.m.gtp4.e v4src_position %d",
&local_prefixlen))
&v4src_position))
return 0;

ls_mem = clib_mem_alloc_aligned_at_offset (sizeof *ls_mem, 0, 0, 1);
clib_memset (ls_mem, 0, sizeof *ls_mem);
*plugin_mem_p = ls_mem;

ls_mem->local_prefixlen = local_prefixlen;
ls_mem->v4src_position = v4src_position;

return 1;
}
Expand Down
Loading

0 comments on commit 2ac064c

Please sign in to comment.