Skip to content

Commit 2ac064c

Browse files
authored
Merge pull request FDio#31 from TetsuyaMurakami/ietf105-hackathon
Fix FDio#21
2 parents ad4849d + d8a6e0d commit 2ac064c

File tree

7 files changed

+690
-57
lines changed

7 files changed

+690
-57
lines changed

extras/ietf105/runner.py

Lines changed: 127 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,128 @@ def test_tmap_ipv6(self):
638638
for p in c4.pg_read_packets():
639639
p.show2()
640640

641+
def test_gtp4(self):
642+
# TESTS:
643+
# trace add af-packet-input 10
644+
# pg interface on c1 172.20.0.1
645+
# pg interface on c4 B::1/120
646+
647+
self.start_containers()
648+
649+
c1 = self.containers.get(self.get_name(self.instance_names[0]))
650+
c2 = self.containers.get(self.get_name(self.instance_names[1]))
651+
c3 = self.containers.get(self.get_name(self.instance_names[2]))
652+
c4 = self.containers.get(self.get_name(self.instance_names[-1]))
653+
654+
c1.pg_create_interface4(local_ip="172.16.0.1/30", remote_ip="172.16.0.2/30",
655+
local_mac="aa:bb:cc:dd:ee:01", remote_mac="aa:bb:cc:dd:ee:02")
656+
c4.pg_create_interface4(local_ip="1.0.0.2/30", remote_ip="1.0.0.1",
657+
local_mac="aa:bb:cc:dd:ee:11", remote_mac="aa:bb:cc:dd:ee:22")
658+
659+
c1.vppctl_exec("set sr encaps source addr A1::1")
660+
c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
661+
c1.vppctl_exec("sr localsid prefix ::ffff:ac14:0001/128 behavior end.m.gtp4.d D4::/32 v6src_prefix C1::/64")
662+
663+
c2.vppctl_exec("sr localsid address D2:: behavior end")
664+
665+
c3.vppctl_exec("sr localsid address D3:: behavior end")
666+
667+
c4.vppctl_exec("sr localsid prefix D4::/32 behavior end.m.gtp4.e v4src_position 64")
668+
669+
#c1.set_ipv6_route("eth1", "A1::2", "D2::/128")
670+
c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
671+
c2.set_ipv6_route("eth1", "A1::1", "C::/120")
672+
c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
673+
c3.set_ipv6_route("eth1", "A2::1", "C::/120")
674+
c4.set_ip_pgroute("pg0", "1.0.0.1", "172.20.0.1/32")
675+
676+
p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01")/
677+
IP(src="172.20.0.2", dst="172.20.0.1")/
678+
UDP(sport=2152, dport=2152)/
679+
GTP_U_Header(gtp_type="g_pdu", teid=200)/
680+
IP(src="172.99.0.1", dst="172.99.0.2")/
681+
ICMP())
682+
683+
print("Sending packet on {}:".format(c1.name))
684+
p.show2()
685+
686+
c1.enable_trace(10)
687+
c4.enable_trace(10)
688+
689+
c4.pg_start_capture()
690+
691+
c1.pg_create_stream(p)
692+
c1.pg_enable()
693+
694+
# timeout (sleep) if needed
695+
print("Sleeping")
696+
time.sleep(5)
697+
698+
print("Receiving packet on {}:".format(c4.name))
699+
for p in c4.pg_read_packets():
700+
p.show2()
701+
702+
def test_gtp4_ipv6(self):
703+
# TESTS:
704+
# trace add af-packet-input 10
705+
# pg interface on c1 172.20.0.1
706+
# pg interface on c4 B::1/120
707+
708+
self.start_containers()
709+
710+
711+
c1 = self.containers.get(self.get_name(self.instance_names[0]))
712+
c2 = self.containers.get(self.get_name(self.instance_names[1]))
713+
c3 = self.containers.get(self.get_name(self.instance_names[2]))
714+
c4 = self.containers.get(self.get_name(self.instance_names[-1]))
715+
716+
c1.pg_create_interface4(local_ip="172.16.0.1/30", remote_ip="172.16.0.2/30",
717+
local_mac="aa:bb:cc:dd:ee:01", remote_mac="aa:bb:cc:dd:ee:02")
718+
c4.pg_create_interface4(local_ip="1.0.0.2/30", remote_ip="1.0.0.1",
719+
local_mac="aa:bb:cc:dd:ee:11", remote_mac="aa:bb:cc:dd:ee:22")
720+
721+
c1.vppctl_exec("set sr encaps source addr A1::1")
722+
c1.vppctl_exec("sr policy add bsid D4:: next D2:: next D3::")
723+
c1.vppctl_exec("sr localsid prefix ::ffff:ac14:0001/128 behavior end.m.gtp4.d D4::/32 v6src_prefix C1::/64")
724+
725+
c2.vppctl_exec("sr localsid address D2:: behavior end")
726+
727+
c3.vppctl_exec("sr localsid address D3:: behavior end")
728+
729+
c4.vppctl_exec("sr localsid prefix D4::/32 behavior end.m.gtp4.e v4src_position 64")
730+
731+
c2.set_ipv6_route("eth2", "A2::2", "D3::/128")
732+
c2.set_ipv6_route("eth1", "A1::1", "C::/120")
733+
c3.set_ipv6_route("eth2", "A3::2", "D4::/32")
734+
c3.set_ipv6_route("eth1", "A2::1", "C::/120")
735+
c4.set_ip_pgroute("pg0", "1.0.0.1", "172.20.0.1/32")
736+
737+
p = (Ether(src="aa:bb:cc:dd:ee:02", dst="aa:bb:cc:dd:ee:01")/
738+
IP(src="172.20.0.2", dst="172.20.0.1")/
739+
UDP(sport=2152, dport=2152)/
740+
GTP_U_Header(gtp_type="g_pdu", teid=200)/
741+
IPv6(src="2001::1", dst="2002::1")/
742+
ICMPv6EchoRequest())
743+
744+
print("Sending packet on {}:".format(c1.name))
745+
p.show2()
746+
747+
c1.enable_trace(10)
748+
c4.enable_trace(10)
749+
750+
c4.pg_start_capture()
751+
752+
c1.pg_create_stream(p)
753+
c1.pg_enable()
754+
755+
# timeout (sleep) if needed
756+
print("Sleeping")
757+
time.sleep(5)
758+
759+
print("Receiving packet on {}:".format(c4.name))
760+
for p in c4.pg_read_packets():
761+
p.show2()
762+
641763
def test_gtp6_drop_in(self):
642764
# TESTS:
643765
# trace add af-packet-input 10
@@ -995,7 +1117,7 @@ def get_args():
9951117
help="Test related commands.")
9961118

9971119
p3.add_argument("op", choices=[
998-
"ping", "srv6", "tmap", "tmap_ipv6", "gtp6_drop_in", "gtp6_drop_in_ipv6", "gtp6", "gtp6_ipv6"])
1120+
"ping", "srv6", "tmap", "tmap_ipv6", "gtp4", "gtp4_ipv6", "gtp6_drop_in", "gtp6_drop_in_ipv6", "gtp6", "gtp6_ipv6"])
9991121

10001122
args = parser.parse_args()
10011123
if not hasattr(args, "op") or not args.op:
@@ -1042,6 +1164,10 @@ def main(op=None, prefix=None, verbose=None, image=None, index=None, command=Non
10421164
program.test_tmap()
10431165
elif op == 'tmap_ipv6':
10441166
program.test_tmap_ipv6()
1167+
elif op == 'gtp4':
1168+
program.test_gtp4()
1169+
elif op == 'gtp4_ipv6':
1170+
program.test_gtp4_ipv6()
10451171
elif op == 'gtp6_drop_in':
10461172
program.test_gtp6_drop_in()
10471173
elif op == 'gtp6_drop_in_ipv6':

src/plugins/srv6-mobile/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
add_vpp_plugin(srv6mobile
1515
SOURCES
1616
gtp4_e.c
17+
gtp4_d.c
1718
gtp6_e.c
1819
gtp6_d.c
1920
gtp6_d_di.c

src/plugins/srv6-mobile/gtp4_d.c

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
/*
2+
* srv6_end_m_gtp4_d.c
3+
*
4+
* Copyright (c) 2019 Cisco and/or its affiliates.
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at:
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#include <vnet/vnet.h>
19+
#include <vnet/adj/adj.h>
20+
#include <vnet/plugin/plugin.h>
21+
#include <vpp/app/version.h>
22+
#include <srv6-mobile/mobile.h>
23+
24+
srv6_end_main_v4_decap_t srv6_end_main_v4_decap;
25+
26+
static void
27+
clb_dpo_lock_srv6_end_m_gtp4_d (dpo_id_t * dpo)
28+
{
29+
}
30+
31+
static void
32+
clb_dpo_unlock_srv6_end_m_gtp4_d (dpo_id_t * dpo)
33+
{
34+
}
35+
36+
static u8 *
37+
clb_dpo_format_srv6_end_m_gtp4_d (u8 * s, va_list * args)
38+
{
39+
index_t index = va_arg (*args, index_t);
40+
CLIB_UNUSED (u32 indent) = va_arg (*args, u32);
41+
42+
return (format (s, "SR: dynamic_proxy_index:[%u]", index));
43+
}
44+
45+
const static dpo_vft_t dpo_vft = {
46+
.dv_lock = clb_dpo_lock_srv6_end_m_gtp4_d,
47+
.dv_unlock = clb_dpo_unlock_srv6_end_m_gtp4_d,
48+
.dv_format = clb_dpo_format_srv6_end_m_gtp4_d,
49+
};
50+
51+
const static char *const srv6_end_m_gtp4_d_nodes[] = {
52+
"srv6-end-m-gtp4-d",
53+
NULL,
54+
};
55+
56+
const static char *const *const dpo_nodes[DPO_PROTO_NUM] = {
57+
[DPO_PROTO_IP4] = srv6_end_m_gtp4_d_nodes,
58+
};
59+
60+
static u8 fn_name[] = "SRv6-End.M.GTP4.D-plugin";
61+
static u8 keyword_str[] = "end.m.gtp4.d";
62+
static u8 def_str[] = "Endpoint function with dencapsulation for IPv6/GTP tunnel";
63+
static u8 param_str[] = "<sr-prefix>/<sr-prefixlen> v6src_prefix <v6src_prefix>/<prefixlen>";
64+
65+
static u8 *
66+
clb_format_srv6_end_m_gtp4_d (u8 * s, va_list * args)
67+
{
68+
srv6_end_gtp4_param_t *ls_mem = va_arg (*args, void *);
69+
70+
s = format (s, "SRv6 End gtp4.d\n\t");
71+
72+
s = format (s, "SR Prefix: %U/%d, ", format_ip6_address, &ls_mem->sr_prefix, ls_mem->sr_prefixlen);
73+
74+
s = format (s, "v6src Prefix: %U/%d\n", format_ip6_address, &ls_mem->v6src_prefix, ls_mem->v6src_prefixlen);
75+
76+
return s;
77+
}
78+
79+
static uword
80+
clb_unformat_srv6_end_m_gtp4_d (unformat_input_t * input, va_list * args)
81+
{
82+
void **plugin_mem_p = va_arg (*args, void **);
83+
srv6_end_gtp4_param_t *ls_mem;
84+
ip6_address_t sr_prefix;
85+
u32 sr_prefixlen;
86+
ip6_address_t v6src_prefix;
87+
u32 v6src_prefixlen;
88+
89+
if (!unformat (input, "end.m.gtp4.d %U/%d v6src_prefix %U/%d",
90+
unformat_ip6_address, &sr_prefix, &sr_prefixlen,
91+
unformat_ip6_address, &v6src_prefix, &v6src_prefixlen))
92+
{
93+
return 0;
94+
}
95+
96+
ls_mem = clib_mem_alloc_aligned_at_offset (sizeof *ls_mem, 0, 0, 1);
97+
clib_memset (ls_mem, 0, sizeof *ls_mem);
98+
*plugin_mem_p = ls_mem;
99+
100+
ls_mem->sr_prefix = sr_prefix;
101+
ls_mem->sr_prefixlen = sr_prefixlen;
102+
103+
ls_mem->v6src_prefix = v6src_prefix;
104+
ls_mem->v6src_prefixlen = v6src_prefixlen;
105+
106+
return 1;
107+
}
108+
109+
static int
110+
clb_creation_srv6_end_m_gtp4_d (ip6_sr_localsid_t * localsid)
111+
{
112+
return 0;
113+
}
114+
115+
static int
116+
clb_removal_srv6_end_m_gtp4_d (ip6_sr_localsid_t * localsid)
117+
{
118+
srv6_end_gtp4_param_t *ls_mem;
119+
120+
ls_mem = localsid->plugin_mem;
121+
122+
clib_mem_free (ls_mem);
123+
124+
return 0;
125+
}
126+
127+
static clib_error_t *
128+
srv6_end_m_gtp4_d_init (vlib_main_t * vm)
129+
{
130+
srv6_end_main_v4_decap_t *sm = &srv6_end_main_v4_decap;
131+
ip6_header_t *ip6;
132+
dpo_type_t dpo_type;
133+
vlib_node_t *node;
134+
u32 rc;
135+
136+
sm->vlib_main = vm;
137+
sm->vnet_main = vnet_get_main ();
138+
139+
node = vlib_get_node_by_name (vm, (u8 *) "srv6-end-m-gtp4-d");
140+
sm->end_m_gtp4_d_node_index = node->index;
141+
142+
node = vlib_get_node_by_name (vm, (u8 *) "error-drop");
143+
sm->error_node_index = node->index;
144+
145+
ip6 = &sm->cache_hdr;
146+
147+
clib_memset_u8 (ip6, 0, sizeof(ip6_header_t));
148+
149+
// IPv6 header (default)
150+
ip6->ip_version_traffic_class_and_flow_label = 0x60;
151+
ip6->hop_limit = 64;
152+
ip6->protocol = IP_PROTOCOL_IPV6;
153+
154+
dpo_type = dpo_register_new_type (&dpo_vft, dpo_nodes);
155+
156+
rc = sr_localsid_register_function (vm,
157+
fn_name,
158+
keyword_str,
159+
def_str,
160+
param_str,
161+
128, //prefix len
162+
&dpo_type,
163+
clb_format_srv6_end_m_gtp4_d,
164+
clb_unformat_srv6_end_m_gtp4_d,
165+
clb_creation_srv6_end_m_gtp4_d,
166+
clb_removal_srv6_end_m_gtp4_d);
167+
if (rc < 0)
168+
clib_error_return (0, "SRv6 Endpoint GTP4.D LocalSID function"
169+
"couldn't be registered");
170+
return 0;
171+
}
172+
173+
/* *INDENT-OFF* */
174+
VNET_FEATURE_INIT (srv6_end_m_gtp4_d, static) =
175+
{
176+
.arc_name = "ip4-unicast",
177+
.node_name = "srv6-end-m-gtp4-d",
178+
.runs_before = 0,
179+
};
180+
181+
VLIB_INIT_FUNCTION (srv6_end_m_gtp4_d_init);
182+
/* *INDENT-ON* */
183+
184+
/*
185+
* fd.io coding-style-patch-verification: ON
186+
*
187+
* Local Variables:
188+
* eval: (c-set-style "gnu")
189+
* End:
190+
*/

src/plugins/srv6-mobile/gtp4_e.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ clb_format_srv6_end_m_gtp4_e (u8 * s, va_list * args)
6969

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

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

7474
return s;
7575
}
@@ -79,17 +79,17 @@ clb_unformat_srv6_end_m_gtp4_e (unformat_input_t * input, va_list * args)
7979
{
8080
void **plugin_mem_p = va_arg (*args, void **);
8181
srv6_end_gtp4_param_t *ls_mem;
82-
u32 local_prefixlen;
82+
u32 v4src_position;
8383

8484
if (!unformat (input, "end.m.gtp4.e v4src_position %d",
85-
&local_prefixlen))
85+
&v4src_position))
8686
return 0;
8787

8888
ls_mem = clib_mem_alloc_aligned_at_offset (sizeof *ls_mem, 0, 0, 1);
8989
clib_memset (ls_mem, 0, sizeof *ls_mem);
9090
*plugin_mem_p = ls_mem;
9191

92-
ls_mem->local_prefixlen = local_prefixlen;
92+
ls_mem->v4src_position = v4src_position;
9393

9494
return 1;
9595
}

0 commit comments

Comments
 (0)