aboutsummaryrefslogtreecommitdiffstats
path: root/test/test_syslog.py
blob: 0acf7c221eb5e3d1127a7cae8ee262413bc9d61f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#!/usr/bin/env python

import unittest
from framework import VppTestCase, VppTestRunner
from util import ppp
from scapy.packet import Raw
from scapy.layers.inet import IP, UDP
from syslog_rfc5424_parser import SyslogMessage, ParseError
from syslog_rfc5424_parser.constants import SyslogFacility, SyslogSeverity
from vpp_papi import VppEnum


class TestSyslog(VppTestCase):
    """ Syslog Protocol Test Cases """

    @property
    def SYSLOG_SEVERITY(self):
        return VppEnum.vl_api_syslog_severity_t

    @classmethod
    def setUpClass(cls):
        super(TestSyslog, cls).setUpClass()

        try:
            cls.pg0, = cls.create_pg_interfaces(range(1))
            cls.pg0.admin_up()
            cls.pg0.config_ip4()
            cls.pg0.resolve_arp()

        except Exception:
            super(TestSyslog, cls).tearDownClass()
            raise

    @classmethod
    def tearDownClass(cls):
        super(TestSyslog, cls).tearDownClass()

    def syslog_generate(self, facility, severity, appname, msgid, sd=None,
                        msg=None):
        """
        Generate syslog message

        :param facility: facility value
        :param severity: severity level
        :param appname: application name that originate message
        :param msgid: message identifier
        :param sd: structured data (optional)
        :param msg: free-form message (optional)
        """
        facility_str = ['kernel', 'user-level', 'mail-system',
                        'system-daemons', 'security-authorization', 'syslogd',
                        'line-printer', 'network-news', 'uucp', 'clock-daemon',
                        '', 'ftp-daemon', 'ntp-subsystem', 'log-audit',
                        'log-alert', '', 'local0', 'local1', 'local2',
                        'local3', 'local4', 'local5', 'local6', 'local7']

        severity_str = ['emergency', 'alert', 'critical', 'error', 'warning',
                        'notice', 'informational', 'debug']

        cli_str = "test syslog %s %s %s %s" % (facility_str[facility],
                                               severity_str[severity],
                                               appname,
                                               msgid)
        if sd is not None:
            for sd_id, sd_params in sd.items():
                cli_str += " sd-id %s" % (sd_id)
                for name, value in sd_params.items():
                    cli_str += " sd-param %s %s" % (name, value)
        if msg is not None:
            cli_str += " %s" % (msg)
        self.vapi.cli(cli_str)

    def syslog_verify(self, data, facility, severity, appname, msgid, sd=None,
                      msg=None):
        """
        Verify syslog message

        :param data: syslog message
        :param facility: facility value
        :param severity: severity level
        :param appname: application name that originate message
        :param msgid: message identifier
        :param sd: structured data (optional)
        :param msg: free-form message (optional)
        """
        message = data.decode('utf-8')
        if sd is None:
            sd = {}
        try:
            message = SyslogMessage.parse(message)
        except ParseError as e:
            self.logger.error(e)
            raise
        else:
            self.assertEqual(message.facility, facility)
            self.assertEqual(message.severity, severity)
            self.assertEqual(message.appname, appname)
            self.assertEqual(message.msgid, msgid)
            self.assertEqual(message.msg, msg)
            self.assertEqual(message.sd, sd)
            self.assertEqual(message.version, 1)
            self.assertEqual(message.hostname, self.pg0.local_ip4)

    def test_syslog(self):
        """ Syslog Protocol test """
        self.vapi.syslog_set_sender(src_address=self.pg0.local_ip4n,
                                    collector_address=self.pg0.remote_ip4n)
        config = self.vapi.syslog_get_sender()
        self.assertEqual(str(config.collector_address),
                         self.pg0.remote_ip4)
        self.assertEqual(config.collector_port, 514)
        self.assertEqual(str(config.src_address), self.pg0.local_ip4)
        self.assertEqual(config.vrf_id, 0)
        self.assertEqual(config.max_msg_size, 480)

        appname = 'test'
        msgid = 'testMsg'
        msg = 'this is message'
        sd1 = {'exampleSDID@32473': {'iut': '3',
                                     'eventSource': 'App',
                                     'eventID': '1011'}}
        sd2 = {'exampleSDID@32473': {'iut': '3',
                                     'eventSource': 'App',
                                     'eventID': '1011'},
               'examplePriority@32473': {'class': 'high'}}

        self.pg_enable_capture(self.pg_interfaces)
        self.syslog_generate(SyslogFacility.local7,
                             SyslogSeverity.info,
                             appname,
                             msgid,
                             None,
                             msg)
        capture = self.pg0.get_capture(1)
        try:
            self.assertEqual(capture[0][IP].src, self.pg0.local_ip4)
            self.assertEqual(capture[0][IP].dst, self.pg0.remote_ip4)
            self.assertEqual(capture[0][UDP].dport, 514)
            self.assert_packet_checksums_valid(capture[0], False)
        except:
            self.logger.error(ppp("invalid packet:", capture[0]))
            raise
        self.syslog_verify(capture[0][Raw].load,
                           SyslogFacility.local7,
                           SyslogSeverity.info,
                           appname,
                           msgid,
                           None,
                           msg)

        self.pg_enable_capture(self.pg_interfaces)
        self.vapi.syslog_set_filter(
            self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_WARN)
        filter = self.vapi.syslog_get_filter()
        self.assertEqual(filter.severity,
                         self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_WARN)
        self.syslog_generate(SyslogFacility.local7,
                             SyslogSeverity.info,
                             appname,
                             msgid,
                             None,
                             msg)
        self.pg0.assert_nothing_captured()

        self.pg_enable_capture(self.pg_interfaces)
        self.syslog_generate(SyslogFacility.local6,
                             SyslogSeverity.warning,
                             appname,
                             msgid,
                             sd1,
                             msg)
        capture = self.pg0.get_capture(1)
        self.syslog_verify(capture[0][Raw].load,
                           SyslogFacility.local6,
                           SyslogSeverity.warning,
                           appname,
                           msgid,
                           sd1,
                           msg)

        self.vapi.syslog_set_sender(self.pg0.local_ip4n,
                                    self.pg0.remote_ip4n,
                                    collector_port=12345)
        config = self.vapi.syslog_get_sender()
        self.assertEqual(config.collector_port, 12345)

        self.pg_enable_capture(self.pg_interfaces)
        self.syslog_generate(SyslogFacility.local5,
                             SyslogSeverity.err,
                             appname,
                             msgid,
                             sd2,
                             None)
        capture = self.pg0.get_capture(1)
        try:
            self.assertEqual(capture[0][UDP].dport, 12345)
        except:
            self.logger.error(ppp("invalid packet:", capture[0]))
            raise
        self.syslog_verify(capture[0][Raw].load,
                           SyslogFacility.local5,
                           SyslogSeverity.err,
                           appname,
                           msgid,
                           sd2,
                           None)


if __name__ == '__main__':
    unittest.main(testRunner=VppTestRunner)
f, bd_id, hosts): """ Delete required number of L2 FIB entries. :param int count: Number of L2 FIB entries to be created. """ ifs = [self.pg_interfaces[i] for i in self.bd_ifs(bd_id)] for pg_if in ifs: swif = pg_if.sw_if_index for host in hosts[swif]: self.vapi.l2fib_add_del( host.mac, bd_id, swif, is_add=0) def flush_int(self, swif, learned_hosts): """ Flush swif L2 FIB entries. :param int swif: sw if index. """ flushed = dict() self.vapi.l2fib_flush_int(swif) flushed[swif] = learned_hosts[swif] learned_hosts[swif] = [] return flushed def flush_bd(self, bd_id, learned_hosts): """ Flush bd_id L2 FIB entries. :param int bd_id: Bridge Domain id. """ self.vapi.l2fib_flush_bd(bd_id) flushed = dict() ifs = [self.pg_interfaces[i] for i in self.bd_ifs(bd_id)] for pg_if in ifs: swif = pg_if.sw_if_index flushed[swif] = learned_hosts[swif] learned_hosts[swif] = [] return flushed def flush_all(self): """ Flush All L2 FIB entries. """ self.vapi.l2fib_flush_all() def create_stream(self, src_if, packet_sizes, if_src_hosts, if_dst_hosts): """ Create input packet stream for defined interface using hosts or deleted_hosts list. :param object src_if: Interface to create packet stream for. :param list packet_sizes: List of required packet sizes. :param boolean deleted: Set to True if deleted_hosts list required. :return: Stream of packets. """ src_hosts = if_src_hosts[src_if.sw_if_index] if not src_hosts: return [] pkts = [] for dst_if in self.flows[src_if]: dst_swif = dst_if.sw_if_index if dst_swif not in if_dst_hosts: continue dst_hosts = if_dst_hosts[dst_swif] for dst_host in dst_hosts: src_host = random.choice(src_hosts) pkt_info = self.create_packet_info(src_if, dst_if) payload = self.info_to_payload(pkt_info) p = (Ether(dst=dst_host.mac, src=src_host.mac) / IP(src=src_host.ip4, dst=dst_host.ip4) / UDP(sport=1234, dport=1234) / Raw(payload)) pkt_info.data = p.copy() size = random.choice(packet_sizes) self.extend_packet(p, size) pkts.append(p) return pkts def verify_capture(self, pg_if, capture): """ Verify captured input packet stream for defined interface. :param object pg_if: Interface to verify captured packet stream for. :param list capture: Captured packet stream. """ last_info = dict() for i in self.pg_interfaces: last_info[i.sw_if_index] = None dst_sw_if_index = pg_if.sw_if_index for packet in capture: payload_info = self.payload_to_info(str(packet[Raw])) try: ip = packet[IP] udp = packet[UDP] packet_index = payload_info.index self.assertEqual(payload_info.dst, dst_sw_if_index) self.logger.debug("Got packet on port %s: src=%u (id=%u)" % (pg_if.name, payload_info.src, packet_index)) next_info = self.get_next_packet_info_for_interface2( payload_info.src, dst_sw_if_index, last_info[payload_info.src]) last_info[payload_info.src] = next_info self.assertTrue(next_info is not None) self.assertEqual(packet_index, next_info.index) saved_packet = next_info.data # Check standard fields self.assertEqual(ip.src, saved_packet[IP].src) self.assertEqual(ip.dst, saved_packet[IP].dst) self.assertEqual(udp.sport, saved_packet[UDP].sport) self.assertEqual(udp.dport, saved_packet[UDP].dport) except: self.logger.error(ppp("Unexpected or invalid packet:", packet)) raise for i in self.pg_interfaces: remaining_packet = self.get_next_packet_info_for_interface2( i, dst_sw_if_index, last_info[i.sw_if_index]) self.assertTrue( remaining_packet is None, "Port %u: Packet expected from source %u didn't arrive" % (dst_sw_if_index, i.sw_if_index)) def run_verify_test(self, bd_id, src_hosts, dst_hosts): # Test # Create incoming packet streams for packet-generator interfaces self.reset_packet_infos() ifs = [self.pg_interfaces[i] for i in self.bd_ifs(bd_id)] for i in ifs: pkts = self.create_stream( i, self.pg_if_packet_sizes, if_src_hosts=src_hosts, if_dst_hosts=dst_hosts) if pkts: i.add_stream(pkts) self.vapi.bridge_flags(bd_id, 0, 1) # Enable packet capture and start packet sending self.pg_enable_capture(ifs) self.pg_start() # Verify # Verify outgoing packet streams per packet-generator interface for i in ifs: if not dst_hosts[i.sw_if_index]: continue capture = i.get_capture() self.logger.info("Verifying capture on interface %s" % i.name) self.verify_capture(i, capture) def run_verify_negat_test(self, bd_id, src_hosts, dst_hosts): # Test # Create incoming packet streams for packet-generator interfaces for # deleted MAC addresses self.reset_packet_infos() ifs = [self.pg_interfaces[i] for i in self.bd_ifs(bd_id)] for i in ifs: pkts = self.create_stream( i, self.pg_if_packet_sizes, if_src_hosts=src_hosts, if_dst_hosts=dst_hosts) if pkts: i.add_stream(pkts) self.vapi.bridge_flags(bd_id, 0, 1) # Enable packet capture and start packet sending self.pg_enable_capture(ifs) self.pg_start() # Verify # Verify outgoing packet streams per packet-generator interface timeout = 1 for i in ifs: i.get_capture(0, timeout=timeout) i.assert_nothing_captured(remark="outgoing interface") timeout = 0.1 def test_l2_fib_program100(self): """ L2 FIB - program 100 MACs """ bd_id = 1 hosts = self.create_hosts(100, subnet=17) self.config_l2_fib_entries(bd_id, hosts) self.run_verify_test(bd_id, hosts, hosts) def test_l2_fib_delete12(self): """ L2 FIB - program 100 + delete 12 MACs """ bd_id = 1 hosts = self.create_hosts(100, subnet=17) self.config_l2_fib_entries(bd_id, hosts) del_hosts = self.split_hosts(hosts, 12) self.delete_l2_fib_entry(bd_id, del_hosts) self.run_verify_test(bd_id, hosts, hosts) self.run_verify_negat_test(bd_id, hosts, del_hosts) def test_l2_fib_add100_add100(self): """ L2 FIB - program 100 + 100 MACs """ bd_id = 1 hosts = self.create_hosts(100, subnet=17) self.config_l2_fib_entries(bd_id, hosts) hosts2 = self.create_hosts(100, subnet=22) self.config_l2_fib_entries(bd_id, hosts2) self.run_verify_test(bd_id, hosts, hosts2) def test_l2_fib_program10_learn10(self): """ L2 FIB - Program 10 MACs, learn 10 """ hosts = self.create_hosts(20, subnet=35) lhosts = self.split_hosts(hosts, 10) bd1 = 1 bd2 = 2 self.learn_hosts(bd1, lhosts) self.learn_hosts(bd2, lhosts) self.config_l2_fib_entries(bd1, hosts) self.config_l2_fib_entries(bd2, hosts) self.run_verify_test(bd1, lhosts, hosts) self.run_verify_test(bd2, lhosts, hosts) def test_l2_fib_flush_int(self): """ L2 FIB - flush interface """ hosts = self.create_hosts(20, subnet=36) lhosts = self.split_hosts(hosts, 10) bd1 = 1 self.learn_hosts(bd1, lhosts) self.config_l2_fib_entries(bd1, hosts) self.run_verify_test(bd1, lhosts, hosts) flushed = self.flush_int(self.pg_interfaces[0].sw_if_index, lhosts) self.run_verify_test(bd1, hosts, lhosts) self.run_verify_negat_test(bd1, hosts, flushed) def test_l2_fib_flush_bd(self): """ L2 FIB - flush BD """ hosts = self.create_hosts(20, subnet=37) lhosts = self.split_hosts(hosts, 10) bd1 = 1 self.learn_hosts(bd1, lhosts) self.config_l2_fib_entries(bd1, hosts) self.run_verify_test(bd1, lhosts, hosts) flushed = self.flush_bd(bd1, lhosts) self.run_verify_negat_test(bd1, hosts, flushed) def test_l2_fib_flush_all(self): """ L2 FIB - flush all """ hosts = self.create_hosts(20, subnet=38) lhosts = self.split_hosts(hosts, 10) bd1 = 1 bd2 = 2 self.learn_hosts(bd1, lhosts) self.learn_hosts(bd2, lhosts) self.config_l2_fib_entries(bd1, hosts) self.config_l2_fib_entries(bd2, hosts) self.run_verify_test(bd1, hosts, lhosts) self.run_verify_test(bd2, hosts, lhosts) self.flush_all() self.run_verify_negat_test(bd1, hosts, lhosts) self.run_verify_negat_test(bd2, hosts, lhosts) def test_l2_fib_mac_learn_evs(self): """ L2 FIB - mac learning events """ bd1 = 1 hosts = self.create_hosts(10, subnet=39) self.vapi.want_macs_learn_events() self.learn_hosts(bd1, hosts) self.sleep(1) self.logger.info(self.vapi.ppcli("show l2fib")) evs = self.vapi.collect_events() learned_macs = { e.mac[i].mac_addr for e in evs for i in range(e.n_macs) if e.mac[i].action == MAC_EVENT_ACTION_ADD} macs = {h.bin_mac for swif in self.bd_ifs(bd1) for h in hosts[self.pg_interfaces[swif].sw_if_index]} self.vapi.want_macs_learn_events(enable_disable=0) self.assertEqual(len(learned_macs ^ macs), 0) def test_l2_fib_macs_learn_max(self): """ L2 FIB - mac learning max macs in event """ bd1 = 1 hosts = self.create_hosts(10, subnet=40) ev_macs = 1 self.vapi.want_macs_learn_events(max_macs_in_event=ev_macs) self.learn_hosts(bd1, hosts) self.sleep(1) self.logger.info(self.vapi.ppcli("show l2fib")) evs = self.vapi.collect_events() self.vapi.want_macs_learn_events(enable_disable=0) self.assertGreater(len(evs), 0) learned_macs = { e.mac[i].mac_addr for e in evs for i in range(e.n_macs) if e.mac[i].action == MAC_EVENT_ACTION_ADD} macs = {h.bin_mac for swif in self.bd_ifs(bd1) for h in hosts[self.pg_interfaces[swif].sw_if_index]} for e in evs: self.assertLess(len(e), ev_macs * 10) self.assertEqual(len(learned_macs ^ macs), 0) if __name__ == '__main__': unittest.main(testRunner=VppTestRunner)