summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQiuwen Lu <[email protected]>2020-09-25 10:32:21 +0800
committerQiuwen Lu <[email protected]>2020-09-25 10:32:21 +0800
commitdb786dde8c5c06974de6a270b07c095fc458bc54 (patch)
tree1726a4428e5bf800d65d7331242979bfb3f90324
parent22287cc07341fb17f36bd88e553eba09dac660c4 (diff)
为pdump工具增加写入PPI头部的功能,将VLAN标志写入保留字段。
-rw-r--r--tools/tcpdump/pdump.c129
1 files changed, 123 insertions, 6 deletions
diff --git a/tools/tcpdump/pdump.c b/tools/tcpdump/pdump.c
index 9e114de..c968115 100644
--- a/tools/tcpdump/pdump.c
+++ b/tools/tcpdump/pdump.c
@@ -72,6 +72,7 @@
#define CMD_LINE_OPT_DUMPFILE_PATH "dumpfile-path"
#define CMD_LINE_OPT_DUMPFILE_COUNT "dumpfile-count"
#define CMD_LINE_OPT_BPF_RULE "bpf-rule"
+#define CMD_LINE_OPT_USE_PPI_HEADER "use-ppi-header"
#define VDEV_PCAP "net_pcap_%s_%d,tx_pcap=%s"
#define VDEV_IFACE "net_pcap_%s_%d,tx_iface=%s"
@@ -175,6 +176,20 @@ struct parse_val
uint64_t val;
};
+struct ppi_packetheader
+{
+ uint8_t pph_version; // Version. Currently 0
+ uint8_t pph_flags; // Flags.
+ uint16_t pph_len; // Length of entire message, including this header and TLV payload.
+ uint32_t pph_dlt; // libpcap Data Link Type of the captured packet data.
+};
+
+struct ppi_fieldheader
+{
+ uint16_t pfh_type; // Type
+ uint16_t pfh_datalen; // Length of data
+};
+
int num_tuples;
volatile uint8_t quit_signal;
static char server_socket_path[PATH_MAX];
@@ -187,6 +202,7 @@ static struct bpf_program bpf_prog;
static pcap_dumper_t *pcap_dumper = NULL;
static char str_bpf_expr[4096] = {};
static bool is_str_bpf_expr_set = false;
+static bool is_use_ppi_header = false;
/**< display usage */
static void
@@ -207,7 +223,8 @@ pdump_usage(const char *prgname)
"[--dumpfile-path=<dumpfile>]"
"default:dumpfile.pcap\n"
"[--bpf-rule=<bpf-rule>]"
- "default:<None>\n",
+ "default:<None>\n"
+ "[--use-ppi-header]",
prgname);
}
@@ -401,6 +418,7 @@ launch_args_parse(int argc, char **argv, char *prgname)
{"dumpfile-path", 1, 0, 0},
{"dumpfile-count", 1, 0, 0},
{"bpf-rule", 1, 0, 0},
+ {"use-ppi-header", 0, 0, 0},
{NULL, 0, 0, 0}};
if (argc == 1)
@@ -468,6 +486,13 @@ launch_args_parse(int argc, char **argv, char *prgname)
snprintf(str_bpf_expr, sizeof(str_bpf_expr), "%s", optarg);
}
+ if (!strncmp(long_option[option_index].name,
+ CMD_LINE_OPT_USE_PPI_HEADER,
+ sizeof(CMD_LINE_OPT_USE_PPI_HEADER)))
+ {
+ is_use_ppi_header = true;
+ }
+
break;
default:
@@ -508,6 +533,75 @@ disable_pdump(struct pdump_tuples *pt)
rte_pdump_disable(pt->port, pt->queue, pt->dir);
}
+static char ppi_packet_buffer[128 * 1024 * 1024];
+
+struct pfh_data
+{
+ uint16_t vlan_tci;
+ uint16_t vlan_tci_outer;
+};
+
+static int ppi_packet_encap(char *buf, unsigned buflen, struct rte_mbuf *mbuf, const char *pkt, unsigned int pktlen)
+{
+ char *buf_to_write = buf;
+ unsigned int write_len = 0;
+
+ /* SECTION A */
+ struct ppi_packetheader *ppi_hdr = (struct ppi_packetheader *)buf_to_write;
+ /* PPI version must be zero */
+ ppi_hdr->pph_version = 0;
+ /* Flags is zero, non-aligned */
+ ppi_hdr->pph_flags = 0;
+ /* Length of entire message, including this header and TLV payload */
+ ppi_hdr->pph_len = sizeof(struct ppi_packetheader) + sizeof(struct ppi_fieldheader) + sizeof(struct pfh_data);
+ /* DLT */
+ ppi_hdr->pph_dlt = DLT_EN10MB;
+
+ buf_to_write += sizeof(struct ppi_packetheader);
+ write_len += sizeof(struct ppi_packetheader);
+
+ /* SECTION B */
+ struct ppi_fieldheader *field_hdr = (struct ppi_fieldheader *)buf_to_write;
+ field_hdr->pfh_type = 30000;
+ field_hdr->pfh_datalen = sizeof(struct pfh_data);
+
+ buf_to_write += sizeof(struct ppi_fieldheader);
+ write_len += sizeof(struct ppi_fieldheader);
+
+ /* SECTION C */
+ struct pfh_data *phf_data = (struct pfh_data *)buf_to_write;
+
+ if (mbuf->ol_flags & PKT_RX_VLAN ||
+ mbuf->tx_offload & PKT_TX_VLAN_PKT)
+ {
+ phf_data->vlan_tci = mbuf->vlan_tci;
+ }
+ else
+ {
+ phf_data->vlan_tci = 0;
+ }
+
+ if (mbuf->ol_flags & PKT_RX_QINQ ||
+ mbuf->tx_offload & PKT_TX_QINQ_PKT)
+ {
+ phf_data->vlan_tci_outer = mbuf->vlan_tci_outer;
+ }
+ else
+ {
+ phf_data->vlan_tci_outer = 0;
+ }
+
+ buf_to_write += sizeof(struct pfh_data);
+ write_len += sizeof(struct pfh_data);
+
+ /* SECTION D */
+ rte_memcpy(buf_to_write, pkt, pktlen);
+ buf_to_write += pktlen;
+ write_len += pktlen;
+
+ return write_len;
+}
+
static inline void
pdump_rxtx(struct rte_ring *ring, uint16_t vdev_id, struct pdump_stats *stats)
{
@@ -531,11 +625,26 @@ pdump_rxtx(struct rte_ring *ring, uint16_t vdev_id, struct pdump_stats *stats)
struct pcap_pkthdr pcap_pkthdr;
gettimeofday(&pcap_pkthdr.ts, NULL);
- pcap_pkthdr.caplen = pkt_len;
- pcap_pkthdr.len = pkt_len;
+ const char *to_write_ptr = NULL;
+
+ if (is_use_ppi_header)
+ {
+ int ppi_pktlen = ppi_packet_encap(ppi_packet_buffer, sizeof(ppi_packet_buffer),
+ rxtx_bufs[i], pkt_ptr, pkt_len);
+
+ pcap_pkthdr.caplen = ppi_pktlen;
+ pcap_pkthdr.len = ppi_pktlen;
+ to_write_ptr = ppi_packet_buffer;
+ }
+ else
+ {
+ pcap_pkthdr.caplen = pkt_len;
+ pcap_pkthdr.len = pkt_len;
+ to_write_ptr = pkt_ptr;
+ }
/* 写DUMPFILE */
- pcap_dump((u_char *)pcap_dumper, &pcap_pkthdr, (const u_char *)pkt_ptr);
+ pcap_dump((u_char *)pcap_dumper, &pcap_pkthdr, (const u_char *)to_write_ptr);
stats->tx_pkts += 1;
}
@@ -836,7 +945,15 @@ dump_packets(void)
static inline void create_pcap_dumper()
{
- pcap_handle_dead = pcap_open_dead(DLT_EN10MB, 65535);
+ if (is_use_ppi_header)
+ {
+ pcap_handle_dead = pcap_open_dead(DLT_PPI, 65535);
+ }
+ else
+ {
+ pcap_handle_dead = pcap_open_dead(DLT_EN10MB, 65535);
+ }
+
if (pcap_handle_dead == NULL)
{
cleanup_pdump_resources();
@@ -852,7 +969,7 @@ static inline void create_pcap_dumper()
if (is_str_bpf_expr_set)
{
- int ret = pcap_compile(pcap_handle_dead, &bpf_prog, str_bpf_expr, 1, PCAP_NETMASK_UNKNOWN);
+ int ret = pcap_compile_nopcap(65535, DLT_EN10MB, &bpf_prog, str_bpf_expr, 1, PCAP_NETMASK_UNKNOWN);
if (ret < 0)
{
cleanup_pdump_resources();