Пример #1
0
 def test_parse_construct_l2vpn_evpn(self):
     data_dict = {
         "attr": {
             1: 0,
             2: [],
             5: 100,
             14: {
                 "afi_safi": (25, 70),
                 "nexthop":
                 "10.75.44.254",
                 "nlri": [{
                     "type": 2,
                     "value": {
                         "eth_tag_id": 108,
                         "ip": "11.11.11.1",
                         "label": [0],
                         "rd": "172.17.0.3:2",
                         "mac": "00-11-22-33-44-55",
                         "esi": 0
                     }
                 }]
             },
             16: [[1536, 1, 500]]
         }
     }
     self.assertEqual(
         data_dict['attr'],
         Update.parse(
             None,
             Update.construct(msg_dict=data_dict)[HDR_LEN:])['attr'])
Пример #2
0
 def test_parse_construct_l2vpn_evpn(self):
     data_bin = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x63\x02\x00\x00\x00' \
                b'\x4c\xc0\x10\x08\x06\x00\x01\x00\x00\x00\x01\xf4\x40\x01\x01\x00\x40\x02\x00\x40\x05\x04' \
                b'\x00\x00\x00\x64\x80\x0e\x30\x00\x19\x46\x04\x0a\x4b\x2c\xfe\x00\x02\x25\x00\x01\xac\x11' \
                b'\x00\x03\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6c\x30\x00\x11\x22' \
                b'\x33\x44\x55\x20\x0b\x0b\x0b\x01\x00\x00\x00'
     data_dict = {
         "attr": {
             1: 0,
             2: [],
             5: 100,
             14: {
                 "afi_safi": (25, 70),
                 "nexthop":
                 "10.75.44.254",
                 "nlri": [{
                     "type": 2,
                     "value": {
                         "eth_tag_id": 108,
                         "ip": "11.11.11.1",
                         "label": [0],
                         "rd": "172.17.0.3:2",
                         "mac": "00-11-22-33-44-55",
                         "esi": 0
                     }
                 }]
             },
             16: [[1536, 1, 500]]
         }
     }
     self.assertEqual(data_bin, Update.construct(msg_dict=data_dict))
     self.assertEqual(data_dict['attr'],
                      Update.parse(None, data_bin[HDR_LEN:])['attr'])
Пример #3
0
 def test_parse_and_construct_ipv6_unicast_update(self):
     value_parse = {
         'attr': {
             1: 0,
             2: [(2, [65502])],
             4: 0,
             14: {
                 'afi_safi': (2, 1),
                 'linklocal_nexthop':
                 'fe80::c002:bff:fe7e:0',
                 'nexthop':
                 '2001:db8::2',
                 'nlri': [
                     '::2001:db8:2:2/64', '::2001:db8:2:1/64',
                     '::2001:db8:2:0/64'
                 ]
             }
         }
     }
     self.assertEqual(
         value_parse['attr'],
         Update.parse(
             None,
             Update.construct(msg_dict=value_parse, asn4=True)[HDR_LEN:],
             True)['attr'], True)
Пример #4
0
 def test_parse_construct_l2vpn_evpn(self):
     data_bin = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x63\x02\x00\x00\x00' \
                b'\x4c\xc0\x10\x08\x06\x00\x01\x00\x00\x00\x01\xf4\x40\x01\x01\x00\x40\x02\x00\x40\x05\x04' \
                b'\x00\x00\x00\x64\x80\x0e\x30\x00\x19\x46\x04\x0a\x4b\x2c\xfe\x00\x02\x25\x00\x01\xac\x11' \
                b'\x00\x03\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6c\x30\x00\x11\x22' \
                b'\x33\x44\x55\x20\x0b\x0b\x0b\x01\x00\x00\x00'
     data_dict = {
         "attr": {
             1: 0,
             2: [],
             5: 100,
             14: {
                 "afi_safi": (25, 70),
                 "nexthop": "10.75.44.254",
                 "nlri": [
                     {
                         "type": 2,
                         "value": {
                             "eth_tag_id": 108,
                             "ip": "11.11.11.1",
                             "label": [0],
                             "rd": "172.17.0.3:2",
                             "mac": "00-11-22-33-44-55",
                             "esi": 0}}]
             },
             16: [[1536, 1, 500]]
         }}
     self.assertEqual(data_bin, Update.construct(msg_dict=data_dict))
     self.assertEqual(data_dict['attr'], Update.parse(None, data_bin[HDR_LEN:])['attr'])
Пример #5
0
 def test_parse_and_construct_ipv4_mpls_vpn_update(self):
     data_bin = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00' \
                b'\x74\x02\x00\x00\x00\x5d\x40\x01\x01\x02\x40\x02\x00\x80\x04\x04\x00' \
                b'\x00\x00\x00\x40\x05\x04\x00\x00\x00\x64\xc0\x10\x08\x00\x02\x00\x02' \
                b'\x00\x00\x00\x02\x80\x0a\x10\xc0\xa8\x01\x01\xc0\xa8\x01\x02\xc0\xa8' \
                b'\x01\x03\xc0\xa8\x01\x04\x80\x09\x04\xc0\xa8\x01\x06\x80\x0e\x20\x00' \
                b'\x01\x80\x0c\x00\x00\x00\x00\x00\x00\x00\x00\xc0\xa8\x01\x06\x00\x70' \
                b'\x00\x01\xd1\x00\x00\x00\x02\x00\x00\x00\x02\xc0\xa8\xc9'
     data_hoped = {
         'attr': {1: 2,
                  2: [],
                  4: 0,
                  5: 100,
                  9: '192.168.1.6',
                  10: ['192.168.1.1', '192.168.1.2', '192.168.1.3', '192.168.1.4'],
                  14: {'afi_safi': (1, 128),
                       'nexthop': {'rd': '0:0', 'str': '192.168.1.6'},
                       'nlri': [{'label': [29],
                                 'rd': '2:2',
                                 'prefix': '192.168.201.0/24'}]},
                  16: [[2, '2:2']]
                  }
     }
     self.maxDiff = None
     self.assertEqual(data_hoped['attr'], Update.parse(None, data_bin[HDR_LEN:], True)['attr'])
     self.assertEqual(data_hoped['attr'],
                      Update.parse(None, Update.construct(msg_dict=data_hoped)[HDR_LEN:], True)['attr'])
Пример #6
0
 def test_parse_and_construct_pmsi_tunnel_evpn_overlay(self):
     data_dict = {
         'attr': {
             1: 0,
             5: 100,
             14: {
                 'afi_safi': (25, 70),
                 'nexthop':
                 '192.168.1.10',
                 'nlri': [{
                     'type': 3,
                     'value': {
                         'eth_tag_id': 0,
                         'ip': '192.168.1.10',
                         'rd': '65527:36802'
                     }
                 }]
             },
             16: [[2, '65527:36802'], [780, 8]],
             22: {
                 'mpls_label': [60001],
                 'tunnel_id': '192.168.1.10',
                 'tunnel_type': 6,
                 'leaf_info_required': 0
             }
         }
     }
     self.assertEqual(
         data_dict['attr'],
         Update.parse(
             None,
             Update.construct(msg_dict=data_dict)[HDR_LEN:])['attr'])
Пример #7
0
 def test_construct_prefix_v4(self):
     nlri = [
         '184.157.224.1/32', '32.65.243.12/30', '89.232.254.0/23',
         '69.179.221.0/24', '61.172.0.0/16', '202.223.128.0/17',
         '156.152.0.0/15', '15.0.0.0/8', '209.102.178.0/24',
         '66.112.100.0/22', '208.54.194.0/24'
     ]
     nlri_hex = Update.construct_prefix_v4(nlri)
     self.assertEqual(nlri, Update.parse_prefix_list(nlri_hex))
Пример #8
0
 def test_parse_and_construct_ipv4_mpls_vpn_withdraw(self):
     data_bin = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00' \
                b'\x2c\x02\x00\x00\x00\x15\x80\x0f\x12\x00\x01\x80\x70\x80\x00\x00\x00' \
                b'\x00\x00\x02\x00\x00\x00\x02\xc0\xa8\xc9'
     data_hoped = {'attr': {15: {'afi_safi': (1, 128),
                                 'withdraw': [{'label': [524288],
                                               'rd': '2:2',
                                               'prefix': '192.168.201.0/24'}]}}}
     self.assertEqual(data_hoped['attr'], Update.parse(None, data_bin[HDR_LEN:], True)['attr'])
     self.assertEqual(data_bin, Update.construct(msg_dict=data_hoped))
Пример #9
0
 def test_parse_and_construct_ipv4_unicast_2byteas(self):
     # 2 bytes asn
     msg_hex = b'\x00\x00\x00\x28\x40\x01\x01\x02\x40\x02\x0a\x02\x01\x00\x1e\x01\x02\x00\x0a\x00\x14\x40\x03\x04' \
               b'\x0a\x00\x00\x09\x80\x04\x04\x00\x00\x00\x00\xc0\x07\x06\x00\x1e\x0a\x00\x00\x09\x15\xac\x10\x00'
     update = Update.parse([None, False, msg_hex])
     attributes = {1: 2, 2: [(2, [30]), (1, [10, 20])], 3: '10.0.0.9', 4: 0, 7: (30, '10.0.0.9')}
     self.assertEqual(attributes, update['attr'])
     self.assertEqual([], update['withdraw'])
     self.assertEqual(['172.16.0.0/21'], update['nlri'])
     self.assertEqual(msg_hex, Update.construct(msg_dict=update, asn4=False)[HDR_LEN:])
Пример #10
0
 def test_construct_attributes_ipv4(self):
     attr = {
         1: 2,
         2: [(2, [701, 71])],
         3: '219.158.1.204',
         5: 100,
         6: b'',
         7: (71, '16.96.243.103'),
         8: ['4837:701', '4837:2100'],
         9: '219.158.1.204',
         10: ['219.158.1.209', '0.0.0.30']}
     attr_hex = Update.construct_attributes(attr, asn4=True)
     self.assertEqual(attr, Update.parse_attributes(attr_hex, asn4=True))
Пример #11
0
 def test_construct_attributes_ipv4(self):
     attr = {
         1: 2,
         2: [(2, [701, 71])],
         3: '219.158.1.204',
         5: 100,
         6: b'',
         7: (71, '16.96.243.103'),
         8: ['4837:701', '4837:2100'],
         9: '219.158.1.204',
         10: ['219.158.1.209', '0.0.0.30']
     }
     attr_hex = Update.construct_attributes(attr, asn4=True)
     self.assertEqual(attr, Update.parse_attributes(attr_hex, asn4=True))
Пример #12
0
 def test_parse_ipv4_addpath_withdraw(self):
     msg_hex = b'\x00\x09\x00\x00\x00\x01\x20\x63\x63\x63\x63\x00\x00'
     update = Update.parse(None, msg_hex, True, True)
     self.assertEqual([{
         'path_id': 1,
         'prefix': '99.99.99.99/32'
     }], update['withdraw'])
Пример #13
0
 def test_parse_prefix_list_with_addpath(self):
     prefix_hex = b'\x00\x00\x00\x01\x20\x05\x05\x05\x05\x00\x00\x00\x01\x20\xc0\xa8\x01\x05'
     nlri = [
         {'prefix': '5.5.5.5/32', 'path_id': 1},
         {'prefix': '192.168.1.5/32', 'path_id': 1}
     ]
     self.assertEqual(nlri, Update.parse_prefix_list(prefix_hex, True))
Пример #14
0
 def test_parse_prefix_list(self):
     prefix_hex = b'\x13\xb8\x9d\xe0\x18E\xb3\xdd\x18E\xb3\xdc\x18\xd1f\xb2\x16Bpd\x18\xd06\xc2'
     nlri = [
         '184.157.224.0/19', '69.179.221.0/24', '69.179.220.0/24',
         '209.102.178.0/24', '66.112.100.0/22', '208.54.194.0/24'
     ]
     self.assertEqual(nlri, Update.parse_prefix_list(prefix_hex))
Пример #15
0
 def test_parse_and_construct_ipv6_unicast_update(self):
     value_parse = {
         'attr': {
             1: 0,
             2: [(2, [65502])],
             4: 0,
             14: {
                 'afi_safi': (2, 1),
                 'linklocal_nexthop': 'fe80::c002:bff:fe7e:0',
                 'nexthop': '2001:db8::2',
                 'nlri': ['::2001:db8:2:2/64', '::2001:db8:2:1/64', '::2001:db8:2:0/64']}
         }}
     self.assertEqual(value_parse['attr'], Update.parse(
         None,
         Update.construct(
             msg_dict=value_parse,
             asn4=True)[HDR_LEN:], True)['attr'], True)
Пример #16
0
 def test_parse_and_construct_ipv4_unicast_2byteas(self):
     # 2 bytes asn
     msg_hex = b'\x00\x00\x00\x28\x40\x01\x01\x02\x40\x02\x0a\x02\x01\x00\x1e\x01\x02\x00\x0a\x00\x14\x40\x03\x04' \
               b'\x0a\x00\x00\x09\x80\x04\x04\x00\x00\x00\x00\xc0\x07\x06\x00\x1e\x0a\x00\x00\x09\x15\xac\x10\x00'
     update = Update.parse(None, msg_hex)
     attributes = {
         1: 2,
         2: [(2, [30]), (1, [10, 20])],
         3: '10.0.0.9',
         4: 0,
         7: (30, '10.0.0.9')
     }
     self.assertEqual(attributes, update['attr'])
     self.assertEqual([], update['withdraw'])
     self.assertEqual(['172.16.0.0/21'], update['nlri'])
     self.assertEqual(
         msg_hex,
         Update.construct(msg_dict=update, asn4=False)[HDR_LEN:])
Пример #17
0
 def test_parse_and_construct_ipv4_mpls_vpn_withdraw(self):
     data_hoped = {
         'attr': {
             15: {
                 'afi_safi': (1, 128),
                 'withdraw': [{
                     'label': [524288],
                     'rd': '2:2',
                     'prefix': '192.168.201.0/24'
                 }]
             }
         }
     }
     self.assertEqual(
         data_hoped['attr'],
         Update.parse(None,
                      Update.construct(msg_dict=data_hoped)[HDR_LEN:],
                      True)['attr'])
Пример #18
0
 def test_parse_and_construct_ipv4_mpls_vpn_withdraw(self):
     data_bin = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00' \
                b'\x2c\x02\x00\x00\x00\x15\x80\x0f\x12\x00\x01\x80\x70\x80\x00\x00\x00' \
                b'\x00\x00\x02\x00\x00\x00\x02\xc0\xa8\xc9'
     data_hoped = {
         'attr': {
             15: {
                 'afi_safi': (1, 128),
                 'withdraw': [{
                     'label': [524288],
                     'rd': '2:2',
                     'prefix': '192.168.201.0/24'
                 }]
             }
         }
     }
     self.assertEqual(data_hoped['attr'],
                      Update.parse(None, data_bin[HDR_LEN:], True)['attr'])
     self.assertEqual(data_bin, Update.construct(msg_dict=data_hoped))
Пример #19
0
 def test_parse_ipv4_4byteas(self):
     # 4 bytes asn
     msg_hex = b'\x00\x00\x00\x30\x40\x01\x01\x02\x40\x02\x10\x02\x01\x00\x00\x00\x1e\x01\x02\x00\x00\x00\x0a\x00' \
               b'\x00\x00\x14\x40\x03\x04\x0a\x00\x00\x09\x80\x04\x04\x00\x00\x00\x00\xc0\x07\x08\x00\x00\x00' \
               b'\x1e\x0a\x00\x00\x09\x15\xac\x10\x00'
     update = Update.parse([None, True, msg_hex])
     attributes = {1: 2, 2: [(2, [30]), (1, [10, 20])], 3: '10.0.0.9', 4: 0, 7: (30, '10.0.0.9')}
     self.assertEqual(attributes, update['attr'])
     self.assertEqual([], update['withdraw'])
     self.assertEqual(['172.16.0.0/21'], update['nlri'])
Пример #20
0
 def test_parse_prefix_list_with_addpath(self):
     prefix_hex = b'\x00\x00\x00\x01\x20\x05\x05\x05\x05\x00\x00\x00\x01\x20\xc0\xa8\x01\x05'
     nlri = [{
         'prefix': '5.5.5.5/32',
         'path_id': 1
     }, {
         'prefix': '192.168.1.5/32',
         'path_id': 1
     }]
     self.assertEqual(nlri, Update.parse_prefix_list(prefix_hex, True))
Пример #21
0
 def test_construct_prefix_v4(self):
     nlri = [
         "184.157.224.0/19",
         "69.179.221.0/24",
         "69.179.220.0/24",
         "209.102.178.0/24",
         "66.112.100.0/22",
         "208.54.194.0/24",
     ]
     nlri_hex = Update().construct_prefix_v4(nlri)
     self.assertEqual(nlri, Update.parse_prefix_list(nlri_hex))
Пример #22
0
 def test_parse_attributes_ipv4(self):
     attr_hex = b'@\x01\x01\x00@\x02\x08\x02\x03\x00\x01\x00\x02\x00\x03@\x03\x04\xac\x10\x01\x0e\x80\x04\x04' \
                b'\x00\x00\x00\x00@\x05\x04\x00\x00\x00d\x80\t\x04\xac\x10\x01\x0e\x80\n\x08\x02\x02\x02\x02dddd'
     attributes = {1: 0,
                   2: [(2, [1, 2, 3])],
                   3: '172.16.1.14',
                   4: 0,
                   5: 100,
                   9: '172.16.1.14',
                   10: ['2.2.2.2', '100.100.100.100']}
     self.assertEqual(attributes, Update.parse_attributes(attr_hex, False))
     self.assertRaises(UpdateMessageError, Update.parse_attributes, attr_hex, True)
Пример #23
0
 def test_parse_ipv4_addpath_update(self):
     msg_hex = b'\x00\x00\x00\x30\x40\x01\x01\x00\x40\x02\x06\x02\x01\x00\x00\xfb\xff\x40\x03\x04\x0a\x00\x0e' \
               b'\x01\x80\x04\x04\x00\x00\x00\x00\x40\x05\x04\x00\x00\x00\x64\x80\x0a\x04\x0a\x00\x22' \
               b'\x04\x80\x09\x04\x0a\x00\x0f\x01\x00\x00\x00\x01\x20\x05\x05\x05\x05\x00\x00\x00\x01' \
               b'\x20\xc0\xa8\x01\x05'
     update = Update.parse(None, msg_hex, True, True)
     attributes = {1: 0, 2: [(2, [64511])], 3: '10.0.14.1', 4: 0, 5: 100, 9: '10.0.15.1', 10: ['10.0.34.4']}
     self.assertEqual(attributes, update['attr'])
     self.assertEqual([], update['withdraw'])
     self.assertEqual([
         {'path_id': 1, 'prefix': '5.5.5.5/32'},
         {'path_id': 1, 'prefix': '192.168.1.5/32'}], update['nlri'])
Пример #24
0
 def test_parse_and_construct_ipv4_mpls_vpn_update(self):
     data_bin = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00' \
                b'\x74\x02\x00\x00\x00\x5d\x40\x01\x01\x02\x40\x02\x00\x80\x04\x04\x00' \
                b'\x00\x00\x00\x40\x05\x04\x00\x00\x00\x64\xc0\x10\x08\x00\x02\x00\x02' \
                b'\x00\x00\x00\x02\x80\x0a\x10\xc0\xa8\x01\x01\xc0\xa8\x01\x02\xc0\xa8' \
                b'\x01\x03\xc0\xa8\x01\x04\x80\x09\x04\xc0\xa8\x01\x06\x80\x0e\x20\x00' \
                b'\x01\x80\x0c\x00\x00\x00\x00\x00\x00\x00\x00\xc0\xa8\x01\x06\x00\x70' \
                b'\x00\x01\xd1\x00\x00\x00\x02\x00\x00\x00\x02\xc0\xa8\xc9'
     data_hoped = {
         'attr': {
             1: 2,
             2: [],
             4: 0,
             5: 100,
             9: '192.168.1.6',
             10:
             ['192.168.1.1', '192.168.1.2', '192.168.1.3', '192.168.1.4'],
             14: {
                 'afi_safi': (1, 128),
                 'nexthop': {
                     'rd': '0:0',
                     'str': '192.168.1.6'
                 },
                 'nlri': [{
                     'label': [29],
                     'rd': '2:2',
                     'prefix': '192.168.201.0/24'
                 }]
             },
             16: [[2, '2:2']]
         }
     }
     self.maxDiff = None
     self.assertEqual(data_hoped['attr'],
                      Update.parse(None, data_bin[HDR_LEN:], True)['attr'])
     self.assertEqual(
         data_hoped['attr'],
         Update.parse(None,
                      Update.construct(msg_dict=data_hoped)[HDR_LEN:],
                      True)['attr'])
Пример #25
0
    def update_received(self, timestamp, msg):

        """Called when a BGP Update message was received."""
        result = Update().parse(timestamp, msg, self.fourbytesas, self.add_path_ipv4_receive, self.add_path_ipv4_send)
        if result['sub_error']:
            msg = {
                'attr': result['attr'],
                'nlri': result['nlri'],
                'withdraw': result['withdraw'],
                'hex': repr(result['hex'])
            }
            self.factory.write_msg(
                timestamp=result['time'],
                msg_type=6,
                msg={'msg': msg},
                flush=True
            )
            LOG.error('[%s] Update message error: sub error=%s', self.factory.peer_addr, result['sub_error'])
            self.msg_recv_stat['Updates'] += 1
            self.fsm.update_received()
            return
        afi_safi = None
        # process messages
        if result['nlri'] or result['withdraw']:
            afi_safi = 'ipv4'
        elif result['attr'].get(14):
            afi_safi = bgp_cons.AFI_SAFI_DICT[result['attr'][14]['afi_safi']]
        elif result['attr'].get(15):
            afi_safi = bgp_cons.AFI_SAFI_DICT[result['attr'][15]['afi_safi']]
        msg = {
            'attr': result['attr'],
            'nlri': result['nlri'],
            'withdraw': result['withdraw'],
            'afi_safi': afi_safi
        }

        # write message to disk
        self.factory.write_msg(
            timestamp=result['time'],
            msg_type=bgp_cons.MSG_UPDATE,
            msg={"msg": msg}
        )
        self.factory.flush_and_check_file_size()

        # check channel filter
        if not CONF.standalone and self.factory.tag in \
                [channel_cons.SOURCE_ROUTER_TAG, channel_cons.SOURCE_AND_TARGET_ROUTER_TAG]:
            self.channel_filter(msg=msg)
        # update rib
        self.update_rib(msg)
        self.msg_recv_stat['Updates'] += 1
        self.fsm.update_received()
Пример #26
0
    def _update_received(self, timestamp, msg):
        # if self.msg_recv_stat['Updates'] % 1000 == 0:
        #     LOG.info(self.msg_recv_stat['Updates'])
        #     LOG.info(time.time())
        """Called when a BGP Update message was received."""
        result = Update().parse(timestamp, msg, self.fourbytesas,
                                self.add_path_ipv4_receive,
                                self.add_path_ipv4_send)
        if result['sub_error']:
            msg = {
                'attr': result['attr'],
                'nlri': result['nlri'],
                'withdraw': result['withdraw'],
                'hex': repr(result['hex'])
            }

            self.handler.on_update_error(self, timestamp, msg)

            LOG.error('[%s] Update message error: sub error=%s',
                      self.factory.peer_addr, result['sub_error'])
            self.msg_recv_stat['Updates'] += 1
            self.fsm.update_received()
            return

        afi_safi = None
        # process messages
        if result['nlri'] or result['withdraw']:
            afi_safi = 'ipv4'
        elif result['attr'].get(14):
            afi_safi = bgp_cons.AFI_SAFI_DICT[result['attr'][14]['afi_safi']]
        elif result['attr'].get(15):
            afi_safi = bgp_cons.AFI_SAFI_DICT[result['attr'][15]['afi_safi']]

        msg = {
            'attr': result['attr'],
            'nlri': result['nlri'],
            'withdraw': result['withdraw'],
            'afi_safi': afi_safi
        }

        self.update_receive_verion(result['attr'], result['nlri'],
                                   result['withdraw'])

        if CONF.bgp.rib:
            # try to update bgp rib in
            if msg.get('afi_safi') == 'ipv4':
                self.update_rib_in_ipv4(msg)
                # LOG.info(msg)
        self.handler.update_received(self, timestamp, msg)

        self.msg_recv_stat['Updates'] += 1
        self.fsm.update_received()
Пример #27
0
 def construct_update_to_bin(self, msg):
     """
     construct update message to binary
     :param msg: message dictionary
     :return:
     """
     try:
         msg_update = Update().construct(msg, self.fourbytesas,
                                         self.add_path_ipv4_send)
         return msg_update
     except Exception as e:
         LOG.error(e)
         return "construct failed"
Пример #28
0
    def test_parse_and_construct_pmsi_tunnel_evpn_overlay(self):
        data_bin = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' \
                   b'\x00`\x02\x00\x00\x00I\xc0\x10\x10\x00\x02\xff\xf7\x00\x00\x8f' \
                   b'\xc2\x03\x0c\x00\x00\x00\x00\x00\x08@\x01\x01\x00\xc0\x16\t\x00' \
                   b'\x06\x00\xeaa\xc0\xa8\x01\n@\x05\x04\x00\x00\x00d\x80\x0e\x1c\x00' \
                   b'\x19F\x04\xc0\xa8\x01\n\x00\x03\x11\x00\x00\xff\xf7\x00\x00\x8f\xc2' \
                   b'\x00\x00\x00\x00 \xc0\xa8\x01\n'

        data_dict = {
            'attr': {
                1: 0,
                5: 100,
                14: {
                    'afi_safi': (25, 70),
                    'nexthop':
                    '192.168.1.10',
                    'nlri': [{
                        'type': 3,
                        'value': {
                            'eth_tag_id': 0,
                            'ip': '192.168.1.10',
                            'rd': '65527:36802'
                        }
                    }]
                },
                16: [[2, '65527:36802'], [780, 8]],
                22: {
                    'mpls_label': [60001],
                    'tunnel_id': '192.168.1.10',
                    'tunnel_type': 6,
                    'leaf_info_required': 0
                }
            }
        }
        self.maxDiff = None
        self.assertEqual(data_dict['attr'],
                         Update.parse(None, data_bin[HDR_LEN:])['attr'])
        self.assertEqual(data_bin, Update.construct(msg_dict=data_dict))
Пример #29
0
 def send_update(self, msg):
     """
     send update message to the peer
     :param msg: message dictionary
     :return:
     """
     try:
         msg_update = Update().construct(msg, self.fourbytesas, self.add_path_ipv4_send)
         reactor.callFromThread(self.write_tcp_thread, msg_update)
         self.msg_sent_stat['Updates'] += 1
         return True
     except Exception as e:
         LOG.error(e)
         return False
Пример #30
0
 def send_update(self, msg):
     """
     send update message to the peer
     :param msg: message dictionary
     :return:
     """
     try:
         msg_update = Update().construct(msg, self.fourbytesas)
         self.transport.write(msg_update)
         self.msg_sent_stat['Updates'] += 1
         return True
     except Exception as e:
         LOG.error(e)
         return False
Пример #31
0
 def test_parse_attributes_ipv4(self):
     attr_hex = b'@\x01\x01\x00@\x02\x08\x02\x03\x00\x01\x00\x02\x00\x03@\x03\x04\xac\x10\x01\x0e\x80\x04\x04' \
                b'\x00\x00\x00\x00@\x05\x04\x00\x00\x00d\x80\t\x04\xac\x10\x01\x0e\x80\n\x08\x02\x02\x02\x02dddd'
     attributes = {
         1: 0,
         2: [(2, [1, 2, 3])],
         3: '172.16.1.14',
         4: 0,
         5: 100,
         9: '172.16.1.14',
         10: ['2.2.2.2', '100.100.100.100']
     }
     self.assertEqual(attributes, Update.parse_attributes(attr_hex, False))
     self.assertRaises(UpdateMessageError, Update.parse_attributes,
                       attr_hex, True)
Пример #32
0
 def test_parse_ipv4_4byteas(self):
     # 4 bytes asn
     msg_hex = b'\x00\x00\x00\x30\x40\x01\x01\x02\x40\x02\x10\x02\x01\x00\x00\x00\x1e\x01\x02\x00\x00\x00\x0a\x00' \
               b'\x00\x00\x14\x40\x03\x04\x0a\x00\x00\x09\x80\x04\x04\x00\x00\x00\x00\xc0\x07\x08\x00\x00\x00' \
               b'\x1e\x0a\x00\x00\x09\x15\xac\x10\x00'
     update = Update.parse(None, msg_hex, True)
     attributes = {
         1: 2,
         2: [(2, [30]), (1, [10, 20])],
         3: '10.0.0.9',
         4: 0,
         7: (30, '10.0.0.9')
     }
     self.assertEqual(attributes, update['attr'])
     self.assertEqual([], update['withdraw'])
     self.assertEqual(['172.16.0.0/21'], update['nlri'])
Пример #33
0
    def update_received(self, timestamp, msg):

        """Called when a BGP Update message was received."""
        result = Update().parse(timestamp, msg, self.fourbytesas, self.add_path_ipv4_receive, self.add_path_ipv4_send)
        if result['sub_error']:
            msg = {
                'attr': result['attr'],
                'nlri': result['nlri'],
                'withdraw': result['withdraw'],
                'hex': repr(result['hex'])
            }
            self.factory.write_msg(
                timestamp=result['time'],
                msg_type=6,
                msg={'msg': msg},
                flush=True
            )
            LOG.error('[%s] Update message error: sub error=%s', self.factory.peer_addr, result['sub_error'])
            self.msg_recv_stat['Updates'] += 1
            self.fsm.update_received()
            return

        # process messages
        msg = {
            'attr': result['attr'],
            'nlri': result['nlri'],
            'withdraw': result['withdraw']
        }

        # write message to disk
        self.factory.write_msg(
            timestamp=result['time'],
            msg_type=bgp_cons.MSG_UPDATE,
            msg={"msg": msg}
        )
        if self.factory.flush_and_check_file_size():
            for afi, safi in CONF.bgp.running_config[self.factory.peer_addr]['capability']['remote']['afi_safi']:
                self.send_route_refresh(afi=afi, safi=safi)

        # check channel filter
        if not CONF.standalone and self.factory.tag in \
                [channel_cons.SOURCE_ROUTER_TAG, channel_cons.SOURCE_AND_TARGET_ROUTER_TAG]:
            self.channel_filter(msg=msg)
        # update rib
        self.update_rib(msg)
        self.msg_recv_stat['Updates'] += 1
        self.fsm.update_received()
Пример #34
0
    def update_received(self, timestamp, msg):
        """Called when a BGP Update message was received."""
        result = Update().parse(timestamp, msg, self.fourbytesas,
                                self.add_path_ipv4_receive,
                                self.add_path_ipv4_send)
        if result['sub_error']:
            msg = {
                'attr': result['attr'],
                'nlri': result['nlri'],
                'withdraw': result['withdraw'],
                'hex': repr(result['hex'])
            }
            self.factory.write_msg(timestamp=result['time'],
                                   msg_type=6,
                                   msg=msg,
                                   flush=True)
            LOG.error('[%s] Update message error: sub error=%s',
                      self.factory.peer_addr, result['sub_error'])
            self.msg_recv_stat['Updates'] += 1
            self.fsm.update_received()
            return
        afi_safi = None
        # process messages
        if result['nlri'] or result['withdraw']:
            afi_safi = 'ipv4'
        elif result['attr'].get(14):
            afi_safi = bgp_cons.AFI_SAFI_DICT[result['attr'][14]['afi_safi']]
        elif result['attr'].get(15):
            afi_safi = bgp_cons.AFI_SAFI_DICT[result['attr'][15]['afi_safi']]
        msg = {
            'attr': result['attr'],
            'nlri': result['nlri'],
            'withdraw': result['withdraw'],
            'afi_safi': afi_safi
        }

        # write message to disk
        self.factory.write_msg(timestamp=result['time'],
                               msg_type=bgp_cons.MSG_UPDATE,
                               msg=msg)
        self.factory.flush_and_check_file_size()

        self.msg_recv_stat['Updates'] += 1
        self.fsm.update_received()
Пример #35
0
 def test_parse_ipv6_unicast(self):
     data_bin = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' \
                b'\x00\x55\x02\x00\x00\x00\x3e\x80\x0e\x26\x00\x02\x01\x10\x00\x00' \
                b'\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xac\x1f\x22\xaa\x00\x80' \
                b'\x20\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01' \
                b'\x40\x01\x01\x00\x40\x02\x00\x80\x04\x04\x00\x00\x00\x00\x40\x05\x04\x00\x00\x00\x64'
     data_hoped = {
         1: 0,
         2: [],
         4: 0,
         5: 100,
         14: {
             'afi_safi': (2, 1),
             'nexthop': '::ffff:172.31.34.170',
             'nlri': ['2001::1/128']
         }
     }
     self.maxDiff = None
     self.assertEqual(data_hoped,
                      Update.parse(None, data_bin[HDR_LEN:], True)['attr'])
Пример #36
0
    def _update_received(self, timestamp, msg):
        """Called when a BGP Update message was received."""
        result = Update().parse(timestamp, msg, self.fourbytesas,
                                self.add_path_ipv4_receive,
                                self.add_path_ipv4_send)
        if result['sub_error']:
            msg = {
                'attr': result['attr'],
                'nlri': result['nlri'],
                'withdraw': result['withdraw'],
                'hex': repr(result['hex'])
            }

            self.handler.on_update_error(self, timestamp, msg)

            LOG.error('[%s] Update message error: sub error=%s',
                      self.factory.peer_addr, result['sub_error'])
            self.msg_recv_stat['Updates'] += 1
            self.fsm.update_received()
            return

        afi_safi = None
        # process messages
        if result['nlri'] or result['withdraw']:
            afi_safi = 'ipv4'
        elif result['attr'].get(14):
            afi_safi = bgp_cons.AFI_SAFI_DICT[result['attr'][14]['afi_safi']]
        elif result['attr'].get(15):
            afi_safi = bgp_cons.AFI_SAFI_DICT[result['attr'][15]['afi_safi']]

        msg = {
            'attr': result['attr'],
            'nlri': result['nlri'],
            'withdraw': result['withdraw'],
            'afi_safi': afi_safi
        }

        self.handler.update_received(self, timestamp, msg)

        self.msg_recv_stat['Updates'] += 1
        self.fsm.update_received()
Пример #37
0
    def update_received(self, timestamp, msg):

        """Called when a BGP Update message was received."""
        result = Update().parse([timestamp, self.fourbytesas, msg])
        if result['sub_error']:
            self.factory.write_msg(
                timestamp=result['time'],
                msg_type=6,
                msg={
                    'attr': result['attr'],
                    'nlri': result['nlri'],
                    'withdraw': result['withdraw']
                },
                flush=True
            )
            LOG.error('[%s] Update message error: sub error=%s', self.factory.peer_addr, result['sub_error'])
        else:
            msg = {
                'attr': result['attr'],
                'nlri': result['nlri'],
                'withdraw': result['withdraw']
            }
            self.factory.write_msg(
                timestamp=result['time'],
                msg_type=bgp_cons.MSG_UPDATE,
                msg=msg,
                flush=True
            )
            # update rib in ipv4
            for prefix in msg['nlri']:
                self._adj_rib_in['ipv4'][prefix] = msg['attr']
            for prefix in msg['withdraw']:
                if prefix in self._adj_rib_in['ipv4']:
                    self._adj_rib_in['ipv4'].pop(prefix)
                else:
                    LOG.warning('withdraw prefix which does not exist in rib table!')
            if not CONF.standalone:
                self.factory.channel.send_message(exchange='', routing_key=self.factory.peer_addr, message=str(msg))

        self.msg_recv_stat['Updates'] += 1
        self.fsm.update_received()
Пример #38
0
 def parse_route_monitoring_msg(msg):
     """
         Route Monitoring messages are used for initial synchronization of
     ADJ-RIBs-In. They are also used for ongoing monitoring of received
     advertisements and withdraws.
     Following the common BMP header and per-peer header is a BGP Update
     PDU.
     :param msg:
     :return:
     """
     LOG.debug('decode route monitoring message')
     bgp_msg_type = struct.unpack('!B', msg[18])[0]
     LOG.debug('bgp message type=%s' % bgp_msg_type)
     msg = msg[bgp_cons.HDR_LEN:]
     if bgp_msg_type == 2:
         # decode update message
         results = Update().parse(None, msg, asn4=True)
         if results['sub_error']:
             LOG.error(
                 'error: decode update message error!, error code: %s' %
                 results['sub_error'])
             LOG.error('Raw data: %s' % repr(results['hex']))
             return None
         return_result = {
             'attr': results['attr'],
             'nlri': results['nlri'],
             'withdraw': results['withdraw']
         }
         LOG.debug('bgp update message: %s' % return_result)
         return bgp_msg_type, return_result
     elif bgp_msg_type == 5:
         bgp_route_refresh_msg = RouteRefresh().parse(msg=msg)
         LOG.debug('bgp route refresh message: afi=%s,res=%s,safi=%s' %
                   (bgp_route_refresh_msg[0], bgp_route_refresh_msg[1],
                    bgp_route_refresh_msg[2]))
         return bgp_msg_type, {
             'afi': bgp_route_refresh_msg[0],
             'sub_type': bgp_route_refresh_msg[1],
             'safi': bgp_route_refresh_msg[2]
         }
Пример #39
0
 def test_parse_ipv4_addpath_update(self):
     msg_hex = b'\x00\x00\x00\x30\x40\x01\x01\x00\x40\x02\x06\x02\x01\x00\x00\xfb\xff\x40\x03\x04\x0a\x00\x0e' \
               b'\x01\x80\x04\x04\x00\x00\x00\x00\x40\x05\x04\x00\x00\x00\x64\x80\x0a\x04\x0a\x00\x22' \
               b'\x04\x80\x09\x04\x0a\x00\x0f\x01\x00\x00\x00\x01\x20\x05\x05\x05\x05\x00\x00\x00\x01' \
               b'\x20\xc0\xa8\x01\x05'
     update = Update.parse(None, msg_hex, True, True)
     attributes = {
         1: 0,
         2: [(2, [64511])],
         3: '10.0.14.1',
         4: 0,
         5: 100,
         9: '10.0.15.1',
         10: ['10.0.34.4']
     }
     self.assertEqual(attributes, update['attr'])
     self.assertEqual([], update['withdraw'])
     self.assertEqual([{
         'path_id': 1,
         'prefix': '5.5.5.5/32'
     }, {
         'path_id': 1,
         'prefix': '192.168.1.5/32'
     }], update['nlri'])
Пример #40
0
    def test_parse_prefix_list(self):

        prefix_hex = b'\x13\xb8\x9d\xe0\x18E\xb3\xdd\x18E\xb3\xdc\x18\xd1f\xb2\x16Bpd\x18\xd06\xc2'
        nlri = ['184.157.224.0/19', '69.179.221.0/24', '69.179.220.0/24',
                '209.102.178.0/24', '66.112.100.0/22', '208.54.194.0/24']
        self.assertEqual(nlri, Update.parse_prefix_list(prefix_hex))
Пример #41
0
 def test_construct_prefix_v4_addpath(self):
     nlri = [{'path_id': 1, 'prefix': '99.99.99.99/32'}]
     nlri_hex = Update.construct_prefix_v4(nlri, add_path=True)
     self.assertEqual(b'\x00\x00\x00\x01\x20\x63\x63\x63\x63', nlri_hex)
Пример #42
0
 def test_construct_prefix_v4_addpath(self):
     nlri = [{'path_id': 1, 'prefix': '99.99.99.99/32'}]
     nlri_hex = Update.construct_prefix_v4(nlri, add_path=True)
     self.assertEqual(b'\x00\x00\x00\x01\x20\x63\x63\x63\x63', nlri_hex)
Пример #43
0
 def test_parse_ipv4_addpath_withdraw(self):
     msg_hex = b'\x00\x09\x00\x00\x00\x01\x20\x63\x63\x63\x63\x00\x00'
     update = Update.parse(None, msg_hex, True, True)
     self.assertEqual([{'path_id': 1, 'prefix': '99.99.99.99/32'}], update['withdraw'])
Пример #44
0
 def test_construct_prefix_v4(self):
     nlri = ['184.157.224.1/32', '32.65.243.12/30', '89.232.254.0/23', '69.179.221.0/24',
             '61.172.0.0/16', '202.223.128.0/17', '156.152.0.0/15', '15.0.0.0/8',
             '209.102.178.0/24', '66.112.100.0/22', '208.54.194.0/24']
     nlri_hex = Update.construct_prefix_v4(nlri)
     self.assertEqual(nlri, Update.parse_prefix_list(nlri_hex))
Пример #45
0
 def test_parse_link_state(self):
     self.maxDiff = None
     data_bin = b"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" \
                b"\x00\xb3\x02\x00\x00\x00\x9c\x90\x0e\x00\x62\x40\x04\x47\x04\x0a" \
                b"\x7c\x01\x7e\x00\x00\x02\x00\x55\x02\x00\x00\x00\x00\x00\x00\x00" \
                b"\x00\x01\x00\x00\x1a\x02\x00\x00\x04\x00\x00\xff\xfe\x02\x01\x00" \
                b"\x04\x00\x00\x00\x00\x02\x03\x00\x06\x00\x00\x00\x00\x00\x01\x01" \
                b"\x01\x00\x1a\x02\x00\x00\x04\x00\x00\xff\xfe\x02\x01\x00\x04\x00" \
                b"\x00\x00\x00\x02\x03\x00\x06\x00\x00\x00\x00\x00\x03\x01\x03\x00" \
                b"\x04\x01\x03\x00\x01\x01\x04\x00\x04\x01\x03\x00\x02\x40\x01\x01" \
                b"\x00\x40\x02\x00\x40\x05\x04\x00\x00\x00\x64\x80\x1d\x25\x04\x44" \
                b"\x00\x04\x00\x00\x00\x0a\x04\x47\x00\x03\x00\x00\x0a\x04\x4b\x00" \
                b"\x07\x70\x00\x00\x00\x00\x61\xaa\x04\x4b\x00\x07\x30\x00\x00\x00" \
                b"\x00\x61\xab"
     data_dict = {
         1:
         0,
         2: [],
         5:
         100,
         14: {
             'afi_safi': (16388, 71),
             'nexthop':
             '10.124.1.126',
             'nlri': [{
                 'type':
                 'link',
                 'protocol_id':
                 2,
                 'instances_id':
                 0,
                 'descriptors': [{
                     'type': 'local_node',
                     'value': {
                         'as_num': 65534,
                         'bgpls_id': '0.0.0.0',
                         'igp_router_id': {
                             'pseudonode': False,
                             'iso_node_id': b"0000.0000.0001"
                         }
                     }
                 }, {
                     'type': 'remote_node',
                     'value': {
                         'as_num': 65534,
                         'bgpls_id': '0.0.0.0',
                         'igp_router_id': {
                             'pseudonode': False,
                             'iso_node_id': b"0000.0000.0003"
                         }
                     }
                 }, {
                     'type': 'link_local_ipv4',
                     'value': '1.3.0.1'
                 }, {
                     'type': 'link_remote_ipv4',
                     'value': '1.3.0.2'
                 }]
             }]
         },
         29: [{
             'type': 'te_metric',
             'value': 10
         }, {
             'type': 'igp_metric',
             'value': 10
         }, {
             'type': 'adj_sid',
             'value': {
                 'flags': {
                     'B': 1,
                     'F': 0,
                     'L': 1,
                     'P': 0,
                     'S': 0,
                     'V': 1
                 },
                 'value': 25002,
                 'weight': 0
             }
         }, {
             'type': 'adj_sid',
             'value': {
                 'flags': {
                     'B': 0,
                     'F': 0,
                     'L': 1,
                     'P': 0,
                     'S': 0,
                     'V': 1
                 },
                 'value': 25003,
                 'weight': 0
             }
         }]
     }
     self.assertEqual(data_dict,
                      Update.parse(None, data_bin[HDR_LEN:])['attr'])