Skip to content

Commit f7031d6

Browse files
committed
T7556: VPP add IPFIX collector configuration
Add VPP IPFIX configuration commands: ``` set vpp ipfix active-timeout '8' set vpp ipfix collector 192.0.2.2 port '2055' set vpp ipfix collector 192.0.2.2 source-address '192.0.2.1' set vpp ipfix flowprobe-record 'l2' set vpp ipfix flowprobe-record 'l3' set vpp ipfix flowprobe-record 'l4' set vpp ipfix inactive-timeout '32' set vpp ipfix interface eth0 set vpp ipfix interface eth1 direction 'both' set vpp ipfix interface eth1 flow-variant 'ipv4' ```
1 parent 71591b7 commit f7031d6

File tree

8 files changed

+613
-0
lines changed

8 files changed

+613
-0
lines changed

data/config-mode-dependencies/vyos-vpp.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"vpp_interfaces_vxlan": ["vpp_interfaces_vxlan"],
1212
"vpp_interfaces_xconnect": ["vpp_interfaces_xconnect"],
1313
"vpp_acl": ["vpp_acl"],
14+
"vpp_ipfix": ["vpp_ipfix"],
1415
"vpp_nat": ["vpp_nat"],
1516
"vpp_nat_cgnat": ["vpp_nat_cgnat"],
1617
"vpp_kernel_interface": ["vpp_kernel-interfaces"],

data/templates/vpp/startup.conf.j2

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ plugins {
9191
plugin linux_cp_plugin.so { enable }
9292
plugin linux_nl_plugin.so { enable }
9393
plugin pppoe_plugin.so { enable }
94+
# Flow
95+
plugin flowprobe_plugin.so { enable }
9496
plugin sflow_plugin.so { enable }
9597
# NAT uncomment if needed
9698
# plugin cnat_plugin.so { enable }

interface-definitions/vpp.xml.in

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,182 @@
346346
</tagNode>
347347
</children>
348348
</node>
349+
<node name="ipfix" owner="${vyos_conf_scripts_dir}/vpp_ipfix.py">
350+
<properties>
351+
<help>IPFIX</help>
352+
<priority>322</priority>
353+
</properties>
354+
<children>
355+
<tagNode name="collector">
356+
<properties>
357+
<help>Collector IP address</help>
358+
<valueHelp>
359+
<format>ipv4</format>
360+
<description>IPv4 server to export IPFIX</description>
361+
</valueHelp>
362+
<valueHelp>
363+
<format>ipv6</format>
364+
<description>IPv6 server to export IPFIX</description>
365+
</valueHelp>
366+
<constraint>
367+
<validator name="ip-address"/>
368+
</constraint>
369+
</properties>
370+
<children>
371+
#include <include/port-number.xml.i>
372+
<leafNode name="port">
373+
<defaultValue>4739</defaultValue>
374+
</leafNode>
375+
<leafNode name="path-mtu">
376+
<properties>
377+
<help>Path MTU</help>
378+
<valueHelp>
379+
<format>u32:68-1450</format>
380+
<description>Bytes</description>
381+
</valueHelp>
382+
<constraint>
383+
<validator name="numeric" argument="--range 68-1450"/>
384+
</constraint>
385+
</properties>
386+
<defaultValue>512</defaultValue>
387+
</leafNode>
388+
#include <include/source-address-ipv4-ipv6.xml.i>
389+
<leafNode name="template-interval">
390+
<properties>
391+
<help>Interval in seconds</help>
392+
<valueHelp>
393+
<format>u32:1-300</format>
394+
<description>Seconds</description>
395+
</valueHelp>
396+
<constraint>
397+
<validator name="numeric" argument="--range 1-300"/>
398+
</constraint>
399+
</properties>
400+
<defaultValue>20</defaultValue>
401+
</leafNode>
402+
<leafNode name="udp-checksum">
403+
<properties>
404+
<help>Allow UDP checksum</help>
405+
<valueless/>
406+
</properties>
407+
</leafNode>
408+
</children>
409+
</tagNode>
410+
<tagNode name="interface">
411+
<properties>
412+
<help>Interface</help>
413+
<completionHelp>
414+
<script>${vyos_completion_dir}/list_interfaces</script>
415+
</completionHelp>
416+
<valueHelp>
417+
<format>txt</format>
418+
<description>Interface name</description>
419+
</valueHelp>
420+
</properties>
421+
<children>
422+
<leafNode name="direction">
423+
<properties>
424+
<help>Flow direction</help>
425+
<completionHelp>
426+
<list>rx tx both</list>
427+
</completionHelp>
428+
<valueHelp>
429+
<format>rx</format>
430+
<description>Rx direction</description>
431+
</valueHelp>
432+
<valueHelp>
433+
<format>tx</format>
434+
<description>Tx direction</description>
435+
</valueHelp>
436+
<valueHelp>
437+
<format>both</format>
438+
<description>Rx and Tx direction</description>
439+
</valueHelp>
440+
<constraint>
441+
<regex>(rx|tx|both)</regex>
442+
</constraint>
443+
</properties>
444+
<defaultValue>both</defaultValue>
445+
</leafNode>
446+
<leafNode name="flow-variant">
447+
<properties>
448+
<help>Flow variant</help>
449+
<completionHelp>
450+
<list>l2 ipv4 ipv6</list>
451+
</completionHelp>
452+
<valueHelp>
453+
<format>l2</format>
454+
<description>L2</description>
455+
</valueHelp>
456+
<valueHelp>
457+
<format>ipv4</format>
458+
<description>IPv4</description>
459+
</valueHelp>
460+
<valueHelp>
461+
<format>ipv6</format>
462+
<description>IPv6</description>
463+
</valueHelp>
464+
<constraint>
465+
<regex>(l2|ipv4|ipv6)</regex>
466+
</constraint>
467+
</properties>
468+
<defaultValue>ipv4</defaultValue>
469+
</leafNode>
470+
</children>
471+
</tagNode>
472+
<leafNode name="active-timeout">
473+
<properties>
474+
<help>Flow activity timeout</help>
475+
<valueHelp>
476+
<format>u32:0-2147483647</format>
477+
<description>Active flow export timeout (seconds)</description>
478+
</valueHelp>
479+
<constraint>
480+
<validator name="numeric" argument="--range 0-2147483647"/>
481+
</constraint>
482+
</properties>
483+
<defaultValue>15</defaultValue>
484+
</leafNode>
485+
<leafNode name="inactive-timeout">
486+
<properties>
487+
<help>Flow inactivity timeout</help>
488+
<valueHelp>
489+
<format>u32:0-2147483647</format>
490+
<description>Inactive flow export timeout (seconds)</description>
491+
</valueHelp>
492+
<constraint>
493+
<validator name="numeric" argument="--range 0-2147483647"/>
494+
</constraint>
495+
</properties>
496+
<defaultValue>120</defaultValue>
497+
</leafNode>
498+
<leafNode name="flowprobe-record">
499+
<properties>
500+
<help>Flow method</help>
501+
<completionHelp>
502+
<list>l2 l3 l4</list>
503+
</completionHelp>
504+
<valueHelp>
505+
<format>l2</format>
506+
<description>Include level 2 information</description>
507+
</valueHelp>
508+
<valueHelp>
509+
<format>l3</format>
510+
<description>Include level 3 information</description>
511+
</valueHelp>
512+
<valueHelp>
513+
<format>l4</format>
514+
<description>Include level 4 information</description>
515+
</valueHelp>
516+
<constraint>
517+
<regex>(l2|l3|l4)</regex>
518+
</constraint>
519+
<multi/>
520+
</properties>
521+
<defaultValue>l3</defaultValue>
522+
</leafNode>
523+
</children>
524+
</node>
349525
<node name="settings">
350526
<properties>
351527
<help>VPP settings</help>

python/vyos/vpp/ipfix/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from .ipfix import IPFIX
2+
3+
__all__ = ['IPFIX']

python/vyos/vpp/ipfix/ipfix.py

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
#
2+
# Copyright (C) VyOS Inc.
3+
#
4+
# This program is free software; you can redistribute it and/or modify
5+
# it under the terms of the GNU General Public License as published by
6+
# the Free Software Foundation; either version 2 of the License, or
7+
# (at your option) any later version.
8+
#
9+
# This program is distributed in the hope that it will be useful,
10+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
# GNU General Public License for more details.
13+
#
14+
# You should have received a copy of the GNU General Public License along
15+
# with this program; if not, write to the Free Software Foundation, Inc.,
16+
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17+
18+
from vpp_papi import VppEnum
19+
from vyos.vpp import VPPControl
20+
21+
22+
class IPFIX:
23+
def __init__(
24+
self,
25+
collector_address: str = '0.0.0.0',
26+
collector_port: int = 4739,
27+
src_address: str = '0.0.0.0',
28+
path_mtu: int = 0,
29+
template_interval: int = 20,
30+
udp_checksum: bool = False,
31+
vrf_id: int = 0,
32+
):
33+
self.vpp = VPPControl()
34+
self.collector_address = collector_address
35+
self.collector_port = collector_port
36+
self.src_address = src_address
37+
self.path_mtu = path_mtu
38+
self.template_interval = template_interval
39+
self.udp_checksum = udp_checksum
40+
self.vrf_id = vrf_id
41+
42+
# enums mapping
43+
self.RECORD_FLAGS_MAP = {
44+
'l2': VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L2,
45+
'l3': VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L3,
46+
'l4': VppEnum.vl_api_flowprobe_record_flags_t.FLOWPROBE_RECORD_FLAG_L4,
47+
}
48+
49+
self.WHICH_FLAGS_MAP = {
50+
'ipv4': VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_IP4,
51+
'ipv6': VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_IP6,
52+
'l2': VppEnum.vl_api_flowprobe_which_t.FLOWPROBE_WHICH_L2,
53+
}
54+
55+
self.DIRECTION_MAP = {
56+
'rx': VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_RX,
57+
'tx': VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_TX,
58+
'both': VppEnum.vl_api_flowprobe_direction_t.FLOWPROBE_DIRECTION_BOTH,
59+
}
60+
61+
def ipfix_exporter_delete(self):
62+
"""Delete IPFIX exporter
63+
https://github.com/FDio/vpp/blob/stable/2506/src/vnet/ipfix-export/ipfix_export.api
64+
Example:
65+
from vyos.vpp import ipfix
66+
i = ipfix.IPFIX()
67+
i.ipfix_exporter_delete()
68+
"""
69+
self.vpp.api.set_ipfix_exporter(
70+
collector_port=0,
71+
collector_address='0.0.0.0',
72+
src_address='0.0.0.0',
73+
path_mtu=0xFFFFFFFF,
74+
template_interval=0,
75+
udp_checksum=False,
76+
vrf_id=4294967295,
77+
)
78+
79+
def set_ipfix_exporter(self):
80+
"""Set IPFIX exporter parameters
81+
Example:
82+
from vyos.vpp import ipfix
83+
i = ipfix.IPFIX(collector_address='192.0.2.2', src_address='192.0.2.1', collector_port=2055, template_interval=20, path_mtu=1450)
84+
i.set_ipfix_exporter()
85+
"""
86+
self.vpp.api.set_ipfix_exporter(
87+
collector_port=self.collector_port,
88+
collector_address=self.collector_address,
89+
src_address=self.src_address,
90+
path_mtu=self.path_mtu,
91+
template_interval=self.template_interval,
92+
udp_checksum=self.udp_checksum,
93+
vrf_id=self.vrf_id,
94+
)
95+
96+
def flowprobe_interface_add(
97+
self,
98+
interface: str,
99+
direction: str = 'both',
100+
which: str = 'ipv4',
101+
):
102+
"""Add IPFIX flowprobe to interface
103+
https://github.com/FDio/vpp/blob/stable/2506/src/plugins/flowprobe/flowprobe.api
104+
Args:
105+
interface (str): Interface name
106+
direction (str): Direction of flowprobe ('rx', 'tx', 'both')
107+
which (str): Which packets to probe ('ipv4', 'ipv6', 'l2')
108+
Example:
109+
from vyos.vpp import ipfix
110+
i = ipfix.IPFIX(collector_address='192.0.2.2', src_address='192.0.2.1', collector_port=2055, template_interval=20, path_mtu=1450)
111+
i.flowprobe_set_params(record_flags=['l2', 'l3'], active_timer=2, passive_timer=20)
112+
i.flowprobe_interface_add('eth0')
113+
"""
114+
sw_if_index = self.vpp.get_sw_if_index(interface)
115+
direction_flag = self.DIRECTION_MAP.get(direction, self.DIRECTION_MAP['both'])
116+
which_flag = self.WHICH_FLAGS_MAP.get(which, self.WHICH_FLAGS_MAP['ipv4'])
117+
118+
self.vpp.api.flowprobe_interface_add_del(
119+
is_add=True,
120+
sw_if_index=sw_if_index,
121+
direction=direction_flag,
122+
which=which_flag,
123+
)
124+
125+
def flowprobe_interface_delete(self, interface: str):
126+
"""Delete IPFIX flowprobe from interface
127+
https://github.com/FDio/vpp/blob/stable/2506/src/plugins/flowprobe/flowprobe.api
128+
Args:
129+
interface (str): Interface name
130+
Example:
131+
from vyos.vpp import ipfix
132+
i = ipfix.IPFIX(collector_address='192.0.2.2', src_address='192.0.2.1', collector_port=2055, template_interval=20, path_mtu=1450)
133+
i.flowprobe_interface_delete('eth0')
134+
"""
135+
sw_if_index = self.vpp.get_sw_if_index(interface)
136+
self.vpp.api.flowprobe_interface_add_del(
137+
is_add=False,
138+
sw_if_index=sw_if_index,
139+
)
140+
141+
def flowprobe_set_params(
142+
self,
143+
active_timer: int = 15,
144+
passive_timer: int = 120,
145+
record_flags: list = None,
146+
):
147+
"""Set IPFIX flowprobe parameters
148+
149+
Args:
150+
active_timer (int): Active timer in seconds
151+
passive_timer (int): Passive timer in seconds
152+
record_flags: Record flags as list of 'l2', 'l3', 'l4'
153+
Examples: ['l2'], ['l2', 'l3'], ['l2', 'l3', 'l4']
154+
Example:
155+
from vyos.vpp import ipfix
156+
i = ipfix.IPFIX(collector_address='192.0.2.2', src_address='192.0.2.1', collector_port=2055, template_interval=20, path_mtu=1450)
157+
i.flowprobe_set_params(record_flags=['l2', 'l3'], active_timer=10, passive_timer=30)
158+
i.flowprobe_interface_add('eth0')
159+
"""
160+
if record_flags is None:
161+
record_flags = ['l2', 'l3', 'l4']
162+
# Calculate combined flags
163+
record_flag = 0
164+
for flag in record_flags:
165+
record_flag |= self.RECORD_FLAGS_MAP[flag]
166+
167+
self.vpp.api.flowprobe_set_params(
168+
active_timer=active_timer,
169+
passive_timer=passive_timer,
170+
record_flags=record_flag,
171+
)

0 commit comments

Comments
 (0)