NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
telemetry_export_netflow_sample.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021 NVIDIA CORPORATION AND AFFILIATES. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, are permitted
5  * provided that the following conditions are met:
6  * * Redistributions of source code must retain the above copyright notice, this list of
7  * conditions and the following disclaimer.
8  * * Redistributions in binary form must reproduce the above copyright notice, this list of
9  * conditions and the following disclaimer in the documentation and/or other materials
10  * provided with the distribution.
11  * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
12  * to endorse or promote products derived from this software without specific prior written
13  * permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
21  * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  */
25 
26 #include <stdbool.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <arpa/inet.h>
30 #include <linux/types.h>
31 
32 #include <doca_log.h>
34 
35 DOCA_LOG_REGISTER(TELEMETRY_EXPORTER::NETFLOW);
36 
37 #define DOCA_TELEMETRY_EXPORTER_NETFLOW_EXAMPLE_SOURCE_ID 111 /* Source ID for DOCA Telemetry Netflow example */
38 #define DOCA_TELEMETRY_EXPORTER_NETFLOW_EXAMPLE_EVENTS_BATCH_SIZE 100 /* Number of records in a single batch */
39 #define DOCA_TELEMETRY_EXPORTER_NETFLOW_EXAMPLE_EVENTS_NOF_BATCHES 10 /* Number of batches to send */
40 
41 /* DOCA Telemetry Netflow example struct */
43  __be32 src_addr_v4; /* Source IPV4 Address */
44  __be32 dst_addr_v4; /* Destination IPV4 Address */
45  struct in6_addr src_addr_v6; /* Source IPV6 Address */
46  struct in6_addr dst_addr_v6; /* Destination IPV6 Address */
47  __be32 next_hop_v4; /* Next hop router's IPV4 Address */
48  struct in6_addr next_hop_v6; /* Next hop router's IPV6 Address */
49  __be16 input; /* Input interface index */
50  __be16 output; /* Output interface index */
51  __be16 src_port; /* TCP/UDP source port number or equivalent */
52  __be16 dst_port; /* TCP/UDP destination port number or equivalent */
53  uint8_t tcp_flags; /* Cumulative OR of tcp flags */
54  uint8_t protocol; /* IP protocol type (for example, TCP = 6;UDP = 17) */
55  uint8_t tos; /* IP Type-of-Service */
56  __be16 src_as; /* Originating AS of source address */
57  __be16 dst_as; /* Originating AS of destination address */
58  uint8_t src_mask; /* Source address prefix mask bits */
59  uint8_t dst_mask; /* Destination address prefix mask bits */
60  __be32 d_pkts; /* Packets sent in Duration */
61  __be32 d_octets; /* Octets sent in Duration */
62  __be32 first; /* SysUptime at start of flow */
63  __be32 last; /* And of last packet of flow */
64  __be64 flow_id; /* This identifies a transaction within a connection */
66  /* Name associated with a classification*/
67 } __attribute__((packed));
68 
69 /* Template for DOCA Telemetry Netflow Example */
70 static struct doca_telemetry_exporter_netflow_template *example_template;
71 
72 /*
73  * Adds a new field - of type and length given as input - to the global example_template struct.
74  *
75  * @type [in]: Type of field
76  * @length [in]: Length of field
77  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
78  */
79 static doca_error_t add_netflow_field(uint16_t type, uint16_t length)
80 {
81  struct doca_telemetry_exporter_netflow_flowset_field *field;
83 
85  if (result != DOCA_SUCCESS)
86  return result;
89 
91  if (result != DOCA_SUCCESS)
93 
94  return result;
95 }
96 
97 /*
98  * Adds all template fields to the global example_template struct.
99  *
100  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
101  */
103 {
105 
152  if (result != DOCA_SUCCESS)
153  return DOCA_ERROR_NO_MEMORY;
154 
155  return DOCA_SUCCESS;
156 }
157 
158 /*
159  * Fills a DOCA Telemetry Netflow example record with arbitrary info.
160  *
161  * @record [out]: The record getting filled
162  */
164 {
165  record->src_addr_v4 = inet_addr("192.168.120.1"); /* Source IPV4 Address */
166  record->dst_addr_v4 = inet_addr("192.168.120.2"); /* Destination IPV4 Address */
167  inet_pton(AF_INET6, "0:0:0:0:0:FFFF:C0A8:7801", &record->src_addr_v6); /* Source IPV6 Address */
168  inet_pton(AF_INET6, "0:0:0:0:0:FFFF:C0A8:7802", &record->dst_addr_v6); /* Destination IPV6 Address */
169  record->next_hop_v4 = inet_addr("192.168.133.7"); /* Next hop router's IPV4 Address */
170  inet_pton(AF_INET6, "0:0:0:0:0:FFFF:C0A8:8507", &record->next_hop_v6); /* Next hop router's IPV6 Address */
171  record->input = htobe16(1); /* Input interface index */
172  record->output = htobe16(65535); /* Output interface index */
173  record->src_port = htobe16(5353); /* TCP/UDP source port number or equivalent */
174  record->dst_port = htobe16(8000); /* TCP/UDP destination port number or equivalent */
175  record->tcp_flags = 0; /* Cumulative OR of tcp flags */
176  record->protocol = 17; /* IP protocol type (for example, TCP = 6 = , UDP = 17) */
177  record->tos = 0; /* IP Type-of-Service */
178  record->src_as = htobe16(0); /* originating AS of source address */
179  record->dst_as = htobe16(0); /* originating AS of destination address */
180  record->src_mask = 0; /* source address prefix mask bits */
181  record->dst_mask = 0; /* destination address prefix mask bits */
182  record->d_pkts = htobe32(9); /* Packets sent in Duration */
183  record->d_octets = htobe32(1909); /* Octets sent in Duration */
184  record->first = htobe32(800294); /* SysUptime at start of flow */
185  record->last = htobe32(804839); /* and of last packet of flow */
186  record->flow_id = htobe64(1337); /* This identifies a transaction within a connection */
187  strcpy(record->application_name, "DOCA TELEMETRY NETFLOW EXAMPLE"); /* Name associated with a classification */
188 }
189 
190 /*
191  * Main sample function.
192  * Initializes and starts DOCA Telemetry Netflow, and sends batches of records.
193  *
194  * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
195  */
197 {
198  bool file_write_enable = true; /* Enables writing to local machine */
199  bool ipc_enabled = true; /* Enables sending to DTS through ipc sockets */
201  int i;
202  size_t nb_of_records_sent;
206 
207  /* Address and port for DOCA Telemetry Netflow exportation */
208  char *netflow_addr = "127.0.0.1";
209  uint16_t netflow_port = 9996;
210 
211  /* Set attributes and initialize DOCA Telemetry Netflow */
212 
213  /* Create example template */
215  if (result != DOCA_SUCCESS) {
216  DOCA_LOG_ERR("Error creating DOCA Telemetry Netflow template %d", result);
217  return result;
218  }
219 
221  if (result != DOCA_SUCCESS) {
222  DOCA_LOG_ERR("Error initializing DOCA Telemetry Netflow template fields %d", result);
223  goto fields_init_err;
224  }
225 
226  /* Init DOCA Telemetry Netflow */
228  if (result != DOCA_SUCCESS) {
229  DOCA_LOG_ERR("DOCA Netflow init failed with error %d", result);
230  goto netflow_init_err;
231  }
232 
233  /*
234  * Enable file write during the app development.
235  * Check written files under data root to make sure that data format is correct.
236  * Default max_file_size is 1 Mb, default max_file_age is 1 hour.
237  */
238  if (file_write_enable)
240 
241  /*
242  * If IPC is enabled, DOCA Telemetry Netflow will try to find DOCA Telemetry Service (DTS)
243  * socket under ipc_sockets_dir. IPC is disabled by default.
244  */
245  if (ipc_enabled)
247 
250 
253 
254  /* Start Netflow */
256  if (result != DOCA_SUCCESS) {
257  DOCA_LOG_ERR("DOCA Telemetry Netflow start failed with error %d", result);
259  goto netflow_start_err;
260  }
261 
262  /* Report batches of netflow records */
264 
266  records[i] = &record;
267 
269  nb_of_records_sent = 0;
270 
272  (const void **)&records,
274  &nb_of_records_sent);
275  if ((result != DOCA_SUCCESS) ||
277  DOCA_LOG_ERR("Batch#%d: %zu out of %d records sent (err=%d)",
278  i,
279  nb_of_records_sent,
281  result);
284  goto netflow_send_err;
285  }
286  DOCA_LOG_INFO("Batch#%d: %zu records sent", i, nb_of_records_sent);
287  }
288 
289  /* Destroy Netflow to clean up */
292  return DOCA_SUCCESS;
293 
294 netflow_send_err:
295 netflow_start_err:
297 netflow_init_err:
298 fields_init_err:
300  return result;
301 }
int32_t result
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_IN_BYTES
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_L4_DST_PORT_DEFAULT_LENGTH
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_LAST_SWITCHED_DEFAULT_LENGTH
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_IPV6_SRC_ADDR_DEFAULT_LENGTH
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_DST_AS
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_PROTOCOL
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_IPV6_DST_ADDR
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_SRC_TOS
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_IN_BYTES_DEFAULT_LENGTH
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_INPUT_SNMP_DEFAULT_LENGTH
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_OUTPUT_SNMP_DEFAULT_LENGTH
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_FIRST_SWITCHED
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_SRC_AS
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_L4_SRC_PORT
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_APPLICATION_NAME_DEFAULT_LENGTH
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_APPLICATION_NAME
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_FIRST_SWITCHED_DEFAULT_LENGTH
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_DST_MASK_DEFAULT_LENGTH
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_IPV4_SRC_ADDR
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_IPV4_SRC_ADDR_DEFAULT_LENGTH
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_CONNECTION_TRANSACTION_ID
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_IN_PKTS_DEFAULT_LENGTH
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_L4_DST_PORT
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_DST_MASK
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_IPV4_NEXT_HOP
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_PROTOCOL_DEFAULT_LENGTH
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_IPV6_NEXT_HOP
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_SRC_MASK_DEFAULT_LENGTH
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_SRC_MASK
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_IPV6_NEXT_HOP_DEFAULT_LENGTH
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_TCP_FLAGS_DEFAULT_LENGTH
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_OUTPUT_SNMP
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_CONNECTION_TRANSACTION_ID_DEFAULT_LENGTH
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_IPV4_DST_ADDR_DEFAULT_LENGTH
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_INPUT_SNMP
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_IPV4_DST_ADDR
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_IPV6_DST_ADDR_DEFAULT_LENGTH
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_LAST_SWITCHED
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_SRC_TOS_DEFAULT_LENGTH
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_IPV6_SRC_ADDR
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_DST_AS_DEFAULT_LENGTH
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_SRC_AS_DEFAULT_LENGTH
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_L4_SRC_PORT_DEFAULT_LENGTH
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_IN_PKTS
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_TCP_FLAGS
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_IPV4_NEXT_HOP_DEFAULT_LENGTH
enum doca_error doca_error_t
DOCA API return codes.
@ DOCA_SUCCESS
Definition: doca_error.h:38
@ DOCA_ERROR_NO_MEMORY
Definition: doca_error.h:45
@ DOCA_ERROR_DRIVER
Definition: doca_error.h:59
#define DOCA_LOG_ERR(format,...)
Generates an ERROR application log message.
Definition: doca_log.h:466
#define DOCA_LOG_INFO(format,...)
Generates an INFO application log message.
Definition: doca_log.h:486
uint32_t __be32
uint64_t __be64
uint16_t __be16
DOCA_EXPERIMENTAL void doca_telemetry_exporter_netflow_source_set_id(const char *source_id)
Set source id.
DOCA_EXPERIMENTAL doca_error_t doca_telemetry_exporter_netflow_destroy(void)
Free the exporter memory and close the connection.
DOCA_EXPERIMENTAL void doca_telemetry_exporter_netflow_set_file_write_enabled(void)
Enable file write file write is disabled by default.
DOCA_EXPERIMENTAL void doca_telemetry_exporter_netflow_source_set_tag(const char *source_tag)
Set source tag.
DOCA_EXPERIMENTAL void doca_telemetry_exporter_netflow_field_set_len(struct doca_telemetry_exporter_netflow_flowset_field *field, uint16_t length)
Set doca telemetry netflow field length.
DOCA_EXPERIMENTAL doca_error_t doca_telemetry_exporter_netflow_send(const struct doca_telemetry_exporter_netflow_template *netflow_template, const void **records, size_t nof_records, size_t *nof_records_sent)
Sending netflow records. Need to init first.
DOCA_EXPERIMENTAL doca_error_t doca_telemetry_exporter_netflow_start(void)
Finalizes netflow setup.
DOCA_EXPERIMENTAL void doca_telemetry_exporter_netflow_set_ipc_enabled(void)
Enable IPC IPC is disabled by default.
DOCA_EXPERIMENTAL doca_error_t doca_telemetry_exporter_netflow_template_destroy(struct doca_telemetry_exporter_netflow_template *netflow_template)
Destructor for DOCA netflow template.
DOCA_EXPERIMENTAL doca_error_t doca_telemetry_exporter_netflow_field_destroy(struct doca_telemetry_exporter_netflow_flowset_field *field)
Destructor for DOCA netflow field.
DOCA_EXPERIMENTAL void doca_telemetry_exporter_netflow_set_collector_addr(const char *collector_addr)
Set collector address.
DOCA_EXPERIMENTAL void doca_telemetry_exporter_netflow_field_set_type(struct doca_telemetry_exporter_netflow_flowset_field *field, uint16_t type)
Set doca telemetry netflow field type.
DOCA_EXPERIMENTAL void doca_telemetry_exporter_netflow_set_collector_port(uint16_t collector_port)
Set collector port. See DOCA_NETFLOW_DEFAULT_PORT for default value.
DOCA_EXPERIMENTAL doca_error_t doca_telemetry_exporter_netflow_template_create(struct doca_telemetry_exporter_netflow_template **netflow_template)
Create new telemetry netflow template.
DOCA_EXPERIMENTAL doca_error_t doca_telemetry_exporter_netflow_init(uint16_t source_id)
Init exporter memory, set configs and open connection.
DOCA_EXPERIMENTAL doca_error_t doca_telemetry_exporter_netflow_template_add_field(struct doca_telemetry_exporter_netflow_template *netflow_template, struct doca_telemetry_exporter_netflow_flowset_field *field)
Add DOCA telemetry netflow field to netflow_template. The user loses the ownership of the field after...
DOCA_EXPERIMENTAL doca_error_t doca_telemetry_exporter_netflow_field_create(struct doca_telemetry_exporter_netflow_flowset_field **field)
Create new telemetry netflow field.
#define htobe64
Definition: os_utils.hpp:41
#define htobe32
Definition: os_utils.hpp:40
#define htobe16
Definition: os_utils.hpp:39
uint8_t type
Definition: packets.h:0
char application_name[DOCA_TELEMETRY_EXPORTER_NETFLOW_APPLICATION_NAME_DEFAULT_LENGTH]
struct doca_telemetry_exporter_netflow_example_record __attribute__((packed))
doca_error_t telemetry_netflow_export(void)
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_EXAMPLE_EVENTS_BATCH_SIZE
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_EXAMPLE_SOURCE_ID
#define DOCA_TELEMETRY_EXPORTER_NETFLOW_EXAMPLE_EVENTS_NOF_BATCHES
static doca_error_t add_netflow_field(uint16_t type, uint16_t length)
static doca_error_t init_template_fields(void)
static void prepare_netflow_example_record(struct doca_telemetry_exporter_netflow_example_record *record)
static struct doca_telemetry_exporter_netflow_template * example_template
DOCA_LOG_REGISTER(TELEMETRY_EXPORTER::NETFLOW)