Skip to content

Commit

Permalink
Datapath Probe Cli and Document (#5554)
Browse files Browse the repository at this point in the history
Signed-off-by: Saurabh Mehra <saurabhmehra@fb.com>
  • Loading branch information
saurabhm3hra committed Mar 24, 2021
1 parent d5572e3 commit f5e97cd
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 1 deletion.
3 changes: 2 additions & 1 deletion docs/docusaurus/sidebars.json
Expand Up @@ -108,7 +108,8 @@
"howtos/header_enrichment.md"
],
"Debugging Tools": [
"debugging_tools/show_tech"
"debugging_tools/show_tech",
"debugging_tools/dp_probe_cli"
],
"Federation Gateway": [
{
Expand Down
47 changes: 47 additions & 0 deletions docs/readmes/debugging_tools/dp_probe_cli.md
@@ -0,0 +1,47 @@
---
id: dp_probe_cli
title: Data Path Probe Cli Command
hide_title: true
---
# dp_probe_cli

## Overview:

This command helps an operator to probe the Datapath to the UE.


### Usage

```
# On your GW host, run the following command
$ dp_probe_cli.py -i <IMSI>
$ dp_probe_cli.py -i 1010000051011
IMSI: 1010000051011, IP: 192.168.128.15
Running: sudo ovs-appctl ofproto/trace gtp_br0 tcp,in_port=local,ip_dst=192.168.128.15,ip_src=8.8.8.8,tcp_src=80,tcp_dst=3372
Datapath Actions: set(tunnel(tun_id=0x1000308,dst=10.0.2.240,ttl=64,tp_dst=2152,flags(df|key))),pop_eth,2
# You can also supply the followin options
# -I <External IP Address>
# -P <External Port>
# -UP <UE Port>
# -p <Protocol tcp/udp/icmp>
$ dp_probe_cli.py -i 1010000051016 -I 4.2.2.2 -p tcp -P 8080 -UP 3172
IMSI: 1010000051016, IP: 192.168.128.14
Running: sudo ovs-appctl ofproto/trace gtp_br0 tcp,in_port=local,ip_dst=192.168.128.14,ip_src=4.2.2.2,tcp_src=8080,tcp_dst=3172
Datapath Actions: set(tunnel(tun_id=0x1000208,dst=10.0.2.240,ttl=64,tp_dst=2152,flags(df|key))),pop_eth,2
```



### What is this command doing?

This command is a wrapper around *ovs-appctl ofproto/trace* which simulates the Datapath of the packet.


### How to read the Output?

Based on the *IMSI* supplied to this command:
- If the UE is not connected, the command will output ***UE is not connected***
- If the UE is connected, it prints the *IP Address* of the UE and the Datapath Actions based on the ovs-appctl ofproto/trace
140 changes: 140 additions & 0 deletions lte/gateway/python/scripts/dp_probe_cli.py
@@ -0,0 +1,140 @@
#!/usr/bin/env python3

"""
Copyright 2020 The Magma Authors.
This source code is licensed under the BSD-style license found in the
LICENSE file in the root directory of this source tree.
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.
"""

import argparse
import re
import subprocess

from lte.protos.mconfig import mconfigs_pb2
from magma.common.service import MagmaService

def create_parser():
"""
Creates the argparse parser with all the arguments.
"""
parser = argparse.ArgumentParser(
description="CLI wrapper around ovs-appctl ofproto/trace.\n"
"To display the Datapath actions of the supplied IMSI",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument("-i", "--imsi", help="IMSI of the subscriber")
parser.add_argument("-I", "--ip", help="External IP")
parser.add_argument("-P", "--port", help="External Port")
parser.add_argument("-UP", "--ue_port", help="UE Port")
parser.add_argument("-p", "--protocol", help="Portocol (i.e. tcp, udp, icmp)")

return parser


def find_ue_ip(imsi: str):
"""
Finds the UE IP address corresponding to the IMSI
"""
cmd = ["mobility_cli.py", "get_subscriber_table"]
output = subprocess.check_output(cmd)
output_str = str(output, "utf-8").strip()
pattern = "IMSI.*?" + imsi + ".*?([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})"
match = re.search(pattern, output_str)
if match:
return match.group(1)
else:
return "NA"


def output_datapath_actions(
ue_ip: str, external_ip: str, external_port: str, ue_port: str, protocol: str
):
"""
Returns the Output of Datapath Actions based as per the supplied UE IP
"""
service = MagmaService("pipelined", mconfigs_pb2.PipelineD())
if service.mconfig.nat_enabled:
in_port = "local"
else:
in_port = "patch-up"

cmd = ["sudo", "ovs-appctl", "ofproto/trace", "gtp_br0"]

cmd_append = (
protocol + ",in_port=" + in_port + ",ip_dst=" + ue_ip + ",ip_src=" + external_ip
)

if protocol != "icmp":
cmd_append += (
","
+ protocol
+ "_src="
+ external_port
+ ","
+ protocol
+ "_dst="
+ ue_port
)

cmd.append(cmd_append)

print("Running: " + " ".join(cmd))
output = subprocess.check_output(cmd)
output_str = str(output, "utf-8").strip()
pattern = "Datapath\sactions:(.*)"
match = re.search(pattern, output_str)
if match:
return match.group(1).strip()
else:
return "NA"


def get_options(args):
external_ip = args.ip if args.ip else "8.8.8.8"
external_port = args.port if args.port else "80"
ue_port = args.ue_port if args.ue_port else "3372"
protocol = args.protocol if args.protocol else "tcp"

return {
"external_ip": external_ip,
"external_port": external_port,
"ue_port": ue_port,
"protocol": protocol,
}


def main():
parser = create_parser()
# Parse the args
args = parser.parse_args()
if not args.imsi:
parser.print_usage()
exit(1)
ue_ip = find_ue_ip(args.imsi)
if ue_ip == "NA":
print("UE is not connected")
exit(1)

print("IMSI: " + args.imsi + ", IP: " + ue_ip)

input_options = get_options(args)
dp_actions = output_datapath_actions(
ue_ip,
input_options["external_ip"],
input_options["external_port"],
input_options["ue_port"],
input_options["protocol"],
)

print("Datapath Actions: " + dp_actions)


if __name__ == "__main__":
main()

0 comments on commit f5e97cd

Please sign in to comment.