diff --git a/agent_based/bgp_peer.py b/agent_based/bgp_peer.py
index a4bf779fd7bdf0650af54b4c759dda738f12e301..0f10cc652b0927e938409bc660e55e1afd367683 100644
--- a/agent_based/bgp_peer.py
+++ b/agent_based/bgp_peer.py
@@ -28,8 +28,10 @@
 # 2021-11-14: merged check function with cisco_bgp_peer
 #             moved parse function to utils/bgp_peer
 # 2021-04-02: rewritten bgp neighbor state handling (made configurable)
+# 2022-04-29: added upper/lower prefix limits from wato
+#             added info if device is admin prefix limit capable (device_admin_limit)
+# 2022-05-09: made item name configurable (don't use address-family/routing-instance/VRF)
 #
-# ToDo: make check/discovery function the base for huawei_bgp_peer
 
 # Example Agent Output:
 # BGP4-MIB
@@ -85,9 +87,20 @@ def parse_bgp_peer(string_table: StringTable) -> Optional[Dict[str, BgpPeer]]:
     return peer_table
 
 
-def discovery_bgp_peer(section: Dict[str, BgpPeer]) -> DiscoveryResult:
+def discovery_bgp_peer(params, section: Dict[str, BgpPeer]) -> DiscoveryResult:
+    _item_parts = [
+        'remote_address',
+        'address_family',
+        'routing_instance',
+    ]
     for key in section.keys():
-        yield Service(item=key)
+        parameters = {'internal_item': key}
+        item = ''
+        for item_part in _item_parts:
+            if item_part not in params['build_item']:
+                item += f'{section[key].item[item_part]} '
+        item = item.strip(' ')
+        yield Service(item=item, parameters=parameters)
 
 
 def check_bgp_peer(item, params, section: Dict[str, BgpPeer]) -> CheckResult:
@@ -101,6 +114,8 @@ def check_bgp_peer(item, params, section: Dict[str, BgpPeer]) -> CheckResult:
         '6': 0,  # established
     }
 
+    item = params.get('internal_item', item)
+
     neighborstate.update(params.get('neighborstate', neighborstate))  # update neighbor status with params
 
     peer_not_found_state = params['peernotfound']
@@ -135,26 +150,27 @@ def check_bgp_peer(item, params, section: Dict[str, BgpPeer]) -> CheckResult:
     if peer.peer_unavail_reason != 0:  # huawei peer unavailable state
         yield Result(state=State.CRIT, notice=F'Peer unavailable reason: {peer.peer_unavail_reason_str}')
 
-    acceptedprefixes = peer.accepted_prefixes
-    prefixadminlimit = peer.prefix_admin_limit
-    prefixthreshold = peer.prefix_threshold
-    warnthreshold = None
-
-    if prefixadminlimit is not None and prefixthreshold is not None:
-        warnthreshold = int(prefixadminlimit / 100.0 * prefixthreshold)  # use float (100.0) to get xx.xx in division
-    elif acceptedprefixes is not None:
+    if peer.device_admin_limit and peer.prefix_admin_limit is None:
         yield Result(
             state=State(params['noprefixlimit']),
-            notice='Prefix limit/warn threshold: not configured on the device.',
+            notice='Prefix limit/warn threshold not configured on the device.',
         )
-        warnthreshold = None
 
     if peer.admin_state == 2:  # no perfdata if admin shutdown
-        if acceptedprefixes is not None:
+        acceptedprefixes = peer.accepted_prefixes
+        prefixadminlimit = peer.prefix_admin_limit
+        prefixthreshold = peer.prefix_threshold
+        warnthreshold = None
+
+        if prefixadminlimit is not None and prefixthreshold is not None:
+            warnthreshold = int(
+                prefixadminlimit / 100.0 * prefixthreshold)  # use float (100.0) to get xx.xx in division
+        if acceptedprefixes is not None and peer.peer_state == 6:  # peer established and prefixes accepted
             yield from check_levels(
                 value=acceptedprefixes,
                 metric_name='bgp_peer_acceptedprefixes',
-                levels_upper=(warnthreshold, prefixadminlimit),
+                levels_upper=params.get('accepted_prefixes_upper_levels', (warnthreshold, prefixadminlimit)),
+                levels_lower=params.get('accepted_prefixes_lower_levels'),
                 label='Prefixes accepted',
                 render_func=lambda v: f'{v}'
             )
@@ -200,6 +216,14 @@ register.check_plugin(
     name='bgp_peer',
     service_name='BGP peer %s',
     discovery_function=discovery_bgp_peer,
+    discovery_default_parameters={
+        'build_item': [
+       #     'remote_address',
+       #     'address_family',
+       #     'routing_instance',
+        ]
+    },
+    discovery_ruleset_name='discovery_bgp_peer',
     check_function=check_bgp_peer,
     check_default_parameters={
         'minuptime': (7200, 3600),
diff --git a/agent_based/inv_bgp_peer.py b/agent_based/inv_bgp_peer.py
index 52b70867687d59804e63076d5bf7c8d23cd70da9..d273b4bc6738eb6eebb6c69c7b36d029858894d5 100644
--- a/agent_based/inv_bgp_peer.py
+++ b/agent_based/inv_bgp_peer.py
@@ -9,27 +9,33 @@
 #
 # inventory of bgp peers
 #
+# 2022-04-30: code cleanup/streamlining
 #
 
+import time
 from typing import List
+
 from cmk.base.plugins.agent_based.agent_based_api.v1 import (
     register,
     SNMPTree,
     TableRow,
     exists,
+    OIDBytes
 )
-
 from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
-    StringTable,
+    StringByteTable,
     InventoryResult,
 )
 from cmk.base.plugins.agent_based.utils.bgp_peer import (
-    ByteToHex,
-    bgp_errors,
+    bgp_error_code_as_hex,
+    bgp_error_as_string,
+    InvBgpPeer,
+    get_bgp_type,
+    BgpWhois,
 )
 
 
-def parse_inv_bgp_peer(string_table: List[StringTable]):
+def parse_inv_bgp_peer(string_table: List[StringByteTable]):
     peers, base = string_table
     try:
         local_as, local_id = base[0]
@@ -41,11 +47,11 @@ def parse_inv_bgp_peer(string_table: List[StringTable]):
 
     for entry in peers:
         try:
-            remote_id,  version, local_addr, remote_addr, remote_as, last_error = entry
+            remote_id,  state, version, local_addr, remote_addr, remote_as, last_error, fsm_established_time = entry
         except ValueError:
             return
 
-        bgp_peers.append({
+        bgp_peer: InvBgpPeer = {
             'remote_addr': remote_addr,
             'remote_id': remote_id,
             'version': version,
@@ -53,20 +59,30 @@ def parse_inv_bgp_peer(string_table: List[StringTable]):
             'remote_as': remote_as,
             'local_as': local_as,
             'local_id': local_id,
-            'bgp_type': 'iBGP' if local_as == remote_as else 'eBGP',
-            'status_columns': {
-                'last_error_code': ByteToHex(last_error),
-                'last_error': bgp_errors(last_error),
-            },
-        })
+            'bgp_type': get_bgp_type(local_as, remote_as),
+            'fsm_established_time': int(fsm_established_time),
+            'peer_state': 1 if state == '6' else 2,  # adjust to match if_oper_status for inventory painter
+            'last_error_code': bgp_error_code_as_hex(last_error),
+            'last_error': bgp_error_as_string(last_error),
+            'status_columns': {},
+            'address_family': 'N/A'
+        }
+
+        bgp_peers.append(bgp_peer)
+
     return bgp_peers
 
 
 def inventory_bgp_peers(params, section) -> InventoryResult:
     path = ['networking', 'bgp_peers']
+    whois = None
+    if params.get('whois_enable'):
+        whois = BgpWhois(
+            default_rir=params['whois_enable'].get('whois_rir', 'https://rdap.db.ripe.net'),
+            timeout=params['whois_enable'].get('whois_timeout', 5)
+        )
 
     for bgp_peer in section:
-
         key_columns = {'remote_addr': bgp_peer['remote_addr']}
 
         for key in key_columns.keys():
@@ -75,6 +91,29 @@ def inventory_bgp_peers(params, section) -> InventoryResult:
         status_columns = bgp_peer['status_columns']
         bgp_peer.pop('status_columns')
 
+        if whois:
+            as_info = whois.get_whois_data_by_asn(int(bgp_peer.get('remote_as')))
+            bgp_peer.update(as_info)
+
+        for column in params.get('remove_columns', []):
+            try:
+                bgp_peer.pop(column)
+            except KeyError:
+                pass
+
+        fsm_established_time = bgp_peer.get('fsm_established_time')
+        if fsm_established_time:
+            bgp_peer.pop('fsm_established_time')
+            peer_state = bgp_peer.get('peer_state')
+            in_service = True
+            not_in_service_time = params.get('not_in_service_time', 2592000)
+            if peer_state == 2:  # not established
+                if fsm_established_time >= not_in_service_time:
+                    in_service = False
+
+            bgp_peer.update({'in_service': in_service})
+            bgp_peer.update({'last_change': time.time() - fsm_established_time})
+
         yield TableRow(
             path=path,
             key_columns=key_columns,
@@ -82,6 +121,9 @@ def inventory_bgp_peers(params, section) -> InventoryResult:
             status_columns=status_columns
         )
 
+    if whois:
+        del whois
+
 
 register.snmp_section(
     name='inv_bgp_peer',
@@ -91,11 +133,13 @@ register.snmp_section(
             base='.1.3.6.1.2.1.15.3.1',  # BGP4-MIB::BgpPeerEntry
             oids=[
                 '1',  # bgpPeerIdentifier
+                '2',  # bgpPeerState
                 '4',  # bgpPeerNegotiatedVersion
                 '5',  # bgpPeerLocalAddr
                 '7',  # bgpPeerRemoteAddr
                 '9',  # bgpPeerRemoteAs
-                '14',  # bgpPeerLastError
+                OIDBytes('14'),  # bgpPeerLastError
+                '16',  # bgpPeerFsmEstablishedTime
             ]
         ),
         SNMPTree(
@@ -113,6 +157,7 @@ register.inventory_plugin(
     name='inv_bgp_peer',
     inventory_function=inventory_bgp_peers,
     inventory_default_parameters={
+        'not_in_service_time': 2592000,  # 30 days in seconds
     },
     inventory_ruleset_name='inv_bgp_peer',
 )
diff --git a/agent_based/utils/bgp_peer.py b/agent_based/utils/bgp_peer.py
index f48d76448f996fd123a517aa727d72555e91c340..0284eb0075c839096823df495b2b6cb9a32b16e4 100644
--- a/agent_based/utils/bgp_peer.py
+++ b/agent_based/utils/bgp_peer.py
@@ -7,16 +7,27 @@
 # URL   : https://thl-cmk.hopto.org
 # Date  : 2021-08-29
 #
-# include file, will be used with bgp_peer, inv_bgp_peer, cisco_bgp_peer, inv_cisco_bgp_peer
+# include file, will be used with (inv_)bgp_peer, (inv_)cisco_bgp_peer, (inv_)juniper_bgp_peer, huawei_bgp_peer
 #
 # 2022-04-17: added peer_unavail_reason/peer_unavail_reason_str for huawei bgp peers
+# 2022-04-29: added device_admin_limit
+# 2022-04-30: code cleanup/streamlining
+# 2022-05-09: added item to BgpPeer class, this is used in the discovery function
 #
 
+import requests
+import json
 import re
-from typing import List, Tuple, Optional, Dict
+import ipaddress
+from typing import List, Tuple, Optional, Dict, TypedDict
 from dataclasses import dataclass
 
 
+class BgpPeerItem(TypedDict):
+    remote_address: str
+    address_family: str
+    routing_instance: str
+
 @dataclass
 class BgpPeer:
     peer_state: int
@@ -26,6 +37,8 @@ class BgpPeer:
     fsm_established_time: int
     metric_rate: List[Tuple[str, int]]
     metric_count: List[Tuple[str, int]]
+    item: BgpPeerItem
+    device_admin_limit: Optional[bool]
     prefix_admin_limit: Optional[int]
     prefix_threshold: Optional[int]
     prefix_clear_threshold: Optional[int]
@@ -34,6 +47,23 @@ class BgpPeer:
     peer_unavail_reason_str: Optional[str]
 
 
+class InvBgpPeer(TypedDict):
+    remote_addr: str
+    remote_id: str
+    version: str
+    local_addr:str
+    remote_as: str
+    local_as: str
+    local_id: str
+    bgp_type: str
+    fsm_established_time: int
+    peer_state: int
+    last_error_code: str
+    last_error: str
+    status_columns: Dict[str, str]
+    address_family:  Optional[str]
+
+
 def sec2hr(seconds):
     m, s = divmod(seconds, 60)
     h, m = divmod(m, 60)
@@ -65,13 +95,24 @@ def bgp_adminstate(st):
     return names.get(st, st)
 
 
-def ByteToHex(byteStr):
-    return ''.join(['%02X ' % ord(x) for x in byteStr]).strip()
+def get_bgp_type(local_as: str, remote_as: str) -> str:
+    bgp_type = 'N/A'
+    if local_as.isdigit() and remote_as.isdigit():
+        if local_as == remote_as:
+            bgp_type = 'iBGP'
+        else:
+            bgp_type = 'eBGP'
 
+    return bgp_type
 
-def bgp_errors(bytestring):
-    byte1, byte2 = ByteToHex(bytestring).split()
 
+def bgp_error_code_as_hex(error_code: List[int]):
+    return ''.join([f'{m:02x}' for m in error_code])
+
+
+def bgp_error_as_string(error_code: List[int]):
+    # byte1, byte2 = ByteToHex(bytestring).split()
+    main_code, sub_code = error_code
     names = {}
     names[0] = {0: 'NO ERROR'}
     names[1] = {
@@ -115,14 +156,10 @@ def bgp_errors(bytestring):
         4: 'Connection Rejected',
         5: 'Other Configuration Change',
     }
-    return names[int(byte1, 16)].get(int(byte2, 16))
-
+    return names[main_code].get(sub_code)
 
-def bgp_render_ipv4_address(bytestring):
-    return '.'.join([f'{ord(m)}' for m in bytestring])
 
-
-def bgp_shorten_ipv6_adress(address):
+def bgp_shorten_ipv6_address(address):
     address = address.split(':')
     span = 2
     address = [''.join(address[i:i + span]) for i in range(0, len(address), span)]
@@ -139,35 +176,38 @@ def bgp_shorten_ipv6_adress(address):
     return address
 
 
-def bgp_render_ipv6_address(bytestring):
-    address = ":".join(["%02s" % hex(ord(m))[2:] for m in bytestring]).replace(' ', '0').upper()
-    address = bgp_shorten_ipv6_adress(address)
-
-    return address
-
-
-def bgp_render_ip_address(bytestring):
-    if len(bytestring) == 4:
-        return bgp_render_ipv4_address(bytestring)
-    elif len(bytestring) == 16:
-        return bgp_render_ipv6_address(bytestring)
+def bgp_render_ip_address(addr_type: str, addr: List[int]) -> str:
+    if addr_type == '1':
+        return '.'.join([str(m) for m in addr])
+    elif addr_type == '2':
+        # IPv6 address from snmp oid in decimal
+        # [10, 1, 7, 40, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 5, 25]
+        # change to hex with leading zero
+        # ['0a', '01', '07', '28', '00', '00', '32', '00', '00', '00', '00', '00', '00', '00', '05', '19']
+        remote_address = ':'.join([f'{m:02x}' for m in addr]).split(':')
+        # convert to long ipv6 address 0a01:0728:0000:3200:0000:0000:0000:0519
+        remote_address = ':'.join([''.join(remote_address[i:i + 2]) for i in range(0, len(remote_address), 2)])
+        # convert to short ipv6 address a01:728:0:3200::519
+        remote_address = str(ipaddress.ip_address(remote_address))
+        # replace bytes in entry with ip address
+        return remote_address
     else:
-        return ''
+        return 'N/A'
 
 
-def bgp_get_peer(OID_END):
+def bgp_get_ip_address_from_oid(oid_end):
     # returns peer address string from OID_END
     # u'1.4.217.119.208.34.1.1' --> 217.119.208.34
-    # u'2.20.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.17.2.1' -->  42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.17
-    peer_ip = ''
-    OID_END = OID_END.split('.')
-    if int(OID_END[1]) == 4:  # length of ip address
-        peer_ip = '.'.join(OID_END[2:6])  # ipv4 address
-    elif int(OID_END[1]) == 16:  # ipv6 address
-        peer_ip = ':'.join('%02s' % hex(int(m))[2:] for m in OID_END[2:18]).replace(' ', '0').upper()
-        peer_ip = bgp_shorten_ipv6_adress(peer_ip)
+    # u'2.16.42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.17.2.1' -->  42.5.87.192.0.0.255.255.0.0.0.0.0.0.0.17
+    ip_address = ''
+    oid_end = oid_end.split('.')
+    if int(oid_end[1]) == 4:  # length of ip address
+        ip_address = '.'.join(oid_end[2:6])  # ipv4 address
+    elif int(oid_end[1]) == 16:  # ipv6 address
+        ip_address = ':'.join('%02s' % hex(int(m))[2:] for m in oid_end[2:18]).replace(' ', '0').upper()
+        ip_address = bgp_shorten_ipv6_address(ip_address)
 
-    return peer_ip
+    return ip_address
 
 
 def bgp_get_peer_entry(peer: List) -> Optional[Dict[str, BgpPeer]]:
@@ -185,6 +225,12 @@ def bgp_get_peer_entry(peer: List) -> Optional[Dict[str, BgpPeer]]:
         fsm_established_time=int(fsm_established_time),
         metric_count=[],
         metric_rate=[],
+        item={
+            'remote_address': remote_addr,
+            'address_family': '',
+            'routing_instance': '',
+        },
+        device_admin_limit=None,
         prefix_admin_limit=None,
         prefix_threshold=None,
         prefix_clear_threshold=None,
@@ -214,3 +260,246 @@ def bgp_get_peer_entry(peer: List) -> Optional[Dict[str, BgpPeer]]:
             pass
 
     return {remote_addr: bgp_peer}
+
+
+def _fetch_data(url: str, timeout: int) -> dict:
+    response = requests.get(
+        url=url,
+        timeout=timeout,
+    )
+    # ToDo: improve/Implement error handling
+    if response.status_code == 200:
+        return json.loads(response.text)
+    else:
+        return {}
+
+
+class BgpWhois:
+    __rdap_boot_strap = {
+        'source': 'https://data.iana.org/rdap/asn.json',
+        'description': 'RDAP bootstrap file for Autonomous System Number allocations',
+        'publication': '2021-12-07T20:00:01Z',
+        'services': [
+            [
+                [
+                    '36864-37887',
+                    '327680-328703',
+                    '328704-329727'
+                ],
+                [
+                    'https://rdap.afrinic.net/rdap/',
+                    'http://rdap.afrinic.net/rdap/'
+                ]
+            ],
+            [
+                [
+                    '4608-4865',
+                    '7467-7722',
+                    '9216-10239',
+                    '17408-18431',
+                    '23552-24575',
+                    '37888-38911',
+                    '45056-46079',
+                    '55296-56319',
+                    '58368-59391',
+                    '63488-63999',
+                    '64000-64098',
+                    '64297-64395',
+                    '131072-132095',
+                    '132096-133119',
+                    '133120-133631',
+                    '133632-134556',
+                    '134557-135580',
+                    '135581-136505',
+                    '136506-137529',
+                    '137530-138553',
+                    '138554-139577',
+                    '139578-140601',
+                    '140602-141625',
+                    '141626-142649',
+                    '142650-143673',
+                    '143674-144697',
+                    '144698-145721',
+                    '145722-146745',
+                    '146746-147769',
+                    '147770-148793',
+                    '148794-149817',
+                    '149818-150841',
+                    '150842-151865'
+                ],
+                [
+                    'https://rdap.apnic.net/'
+                ]
+            ],
+            [
+                [
+                    '1-1876',
+                    '1902-2042',
+                    '2044-2046',
+                    '2048-2106',
+                    '2137-2584',
+                    '2615-2772',
+                    '2823-2829',
+                    '2880-3153',
+                    '3354-4607',
+                    '4866-5376',
+                    '5632-6655',
+                    '6912-7466',
+                    '7723-8191',
+                    '10240-12287',
+                    '13312-15359',
+                    '16384-17407',
+                    '18432-20479',
+                    '21504-23455',
+                    '23457-23551',
+                    '25600-26623',
+                    '26624-27647',
+                    '29696-30719',
+                    '31744-32767',
+                    '32768-33791',
+                    '35840-36863',
+                    '39936-40959',
+                    '46080-47103',
+                    '53248-54271',
+                    '54272-55295',
+                    '62464-63487',
+                    '64198-64296',
+                    '393216-394239',
+                    '394240-395164',
+                    '395165-396188',
+                    '396189-397212',
+                    '397213-398236',
+                    '398237-399260',
+                    '399261-400284',
+                    '400285-401308'
+                ],
+                [
+                    'https://rdap.arin.net/registry/',
+                    'http://rdap.arin.net/registry/'
+                ]
+            ],
+            [
+                [
+                    '1877-1901',
+                    '2043',
+                    '2047',
+                    '2107-2136',
+                    '2585-2614',
+                    '2773-2822',
+                    '2830-2879',
+                    '3154-3353',
+                    '5377-5631',
+                    '6656-6911',
+                    '8192-9215',
+                    '12288-13311',
+                    '15360-16383',
+                    '20480-21503',
+                    '24576-25599',
+                    '28672-29695',
+                    '30720-31743',
+                    '33792-34815',
+                    '34816-35839',
+                    '38912-39935',
+                    '40960-41983',
+                    '41984-43007',
+                    '43008-44031',
+                    '44032-45055',
+                    '47104-48127',
+                    '48128-49151',
+                    '49152-50175',
+                    '50176-51199',
+                    '51200-52223',
+                    '56320-57343',
+                    '57344-58367',
+                    '59392-60415',
+                    '60416-61439',
+                    '61952-62463',
+                    '64396-64495',
+                    '196608-197631',
+                    '197632-198655',
+                    '198656-199679',
+                    '199680-200191',
+                    '200192-201215',
+                    '201216-202239',
+                    '202240-203263',
+                    '203264-204287',
+                    '204288-205211',
+                    '205212-206235',
+                    '206236-207259',
+                    '207260-208283',
+                    '208284-209307',
+                    '209308-210331',
+                    '210332-211355',
+                    '211356-212379',
+                    '212380-213403'
+                ],
+                [
+                    'https://rdap.db.ripe.net/'
+                ]
+            ],
+            [
+                [
+                    '27648-28671',
+                    '52224-53247',
+                    '61440-61951',
+                    '64099-64197',
+                    '262144-263167',
+                    '263168-263679',
+                    '263680-264604',
+                    '264605-265628',
+                    '265629-266652',
+                    '266653-267676',
+                    '267677-268700',
+                    '268701-269724',
+                    '269725-270748',
+                    '270749-271772',
+                    '271773-272796',
+                    '272797-273820'
+                ],
+                [
+                    'https://rdap.lacnic.net/rdap/'
+                ]
+            ]
+        ],
+        'version': '1.0'
+    }
+    __rirs = {
+        'ripe': 'https://rdap.db.ripe.net',
+        'arin': 'https://rdap.arin.net/registry',
+        'afrinic': 'https://rdap.afrinic.net/rdap',
+        'lacnic': 'https://rdap.lacnic.net/rdap',
+        'apnic': 'https://rdap.apnic.net',
+    }
+
+    def __find_rir_by_asn(self, asn: int) -> str:
+        for rir in self.__rdap_boot_strap['services']:
+            url = rir[1][0]  # https rdap url
+            for asns in rir[0]:
+                asns = asns.split('-')
+                if len(asns) == 1:
+                    asns = asns + asns
+                if int(asns[0]) <= asn <= int(asns[1]):
+                    return url
+        return self.__rir
+
+    def __init__(self, default_rir: str, timeout: int):
+        self.__timeout = timeout
+        self.__rir = self.__rirs.get(default_rir, 'https://rdap.db.ripe.net')
+        self.__known_asns = {}
+
+    def get_whois_data_by_asn(self, asn: int) -> Dict[str, str]:
+        asn_info = {}
+        # don't fetch for private ASNs, two byte or four byte ASN number
+        if asn < 64512 or (65536 < asn < 4200000000):
+            rir = self.__find_rir_by_asn(asn)
+            query = 'autnum'
+            data = _fetch_data(f'{rir}{query}/{asn}', self.__timeout)
+            if data:
+                asn_info['as_name'] = data.get('name')
+                vcard_array = data.get('entities')[0].get('vcardArray')
+                if vcard_array:
+                    for line in vcard_array[1]:
+                        if line[0] == 'fn':
+                            asn_info['as_org_name'] = line[3]
+        self.__known_asns.update(asn_info)
+        return asn_info
diff --git a/bgp_peer.mkp b/bgp_peer.mkp
index fd34868a5bb1d7cad94daad457f702246101afc8..d710de6e528646e7a828bb7a8182917ab739b04a 100644
Binary files a/bgp_peer.mkp and b/bgp_peer.mkp differ
diff --git a/packages/bgp_peer b/packages/bgp_peer
index acd4ce4e62de8425841ef65416635f164192ec8c..fd6a9142c85e6d903ac74aeda8353f337e422f9c 100644
--- a/packages/bgp_peer
+++ b/packages/bgp_peer
@@ -15,11 +15,12 @@
            'checkman': ['bgp_peer'],
            'web': ['plugins/metrics/bgp_peer.py',
                    'plugins/views/inv_bgp_peer.py',
-                   'plugins/wato/bgp_peer.py']},
+                   'plugins/wato/bgp_peer.py',
+                   'plugins/wato/inv_bgp_peer.py']},
  'name': 'bgp_peer',
- 'num_files': 7,
+ 'num_files': 8,
  'title': 'BGP Peer State Check',
- 'version': '20220418.v1.7',
+ 'version': '20220509.v1.8',
  'version.min_required': '2.0.0',
  'version.packaged': '2021.09.20',
  'version.usable_until': None}
\ No newline at end of file
diff --git a/web/plugins/metrics/bgp_peer.py b/web/plugins/metrics/bgp_peer.py
index d6cee6e915c4185a8275e51796040ddc4d879ecd..21c2c7f18a66cafdfbb5385b986965d5a15d1553 100644
--- a/web/plugins/metrics/bgp_peer.py
+++ b/web/plugins/metrics/bgp_peer.py
@@ -87,7 +87,27 @@ metric_info['bgp_peer_suppressedprefixes'] = {
     'color': '12/a',
 }
 
-
+# Juniper specific metrics
+metric_info['bgp_peer_in_prefixes'] = {
+    'title': _('Prefixes in'),
+    'unit': 'count',
+    'color': '11/a',
+}
+metric_info['bgp_peer_in_prefixes_rejected'] = {
+    'title': _('Prefixes in rejected'),
+    'unit': 'count',
+    'color': '21/a',
+}
+metric_info['bgp_peer_in_prefixes_active'] = {
+    'title': _('Prefixes in active'),
+    'unit': 'count',
+    'color': '31/a',
+}
+metric_info['bgp_peer_out_prefixes'] = {
+    'title': _('Prefixes out'),
+    'unit': 'count',
+    'color': '41/a',
+}
 
 
 ######################################################################################################################
@@ -165,6 +185,17 @@ graph_info['bgp_peer.time_since_last_update'] = {
     'range': (0, 'bgp_peer_inupdateelapsedtime:mac'),
 }
 
+# juniper prefixes
+graph_info['bgp_peer.juniper_prefixes'] = {
+    'title': _('Prefixes in/out'),
+    'metrics': [
+        ('bgp_peer_out_prefixes', '-line'),
+        ('bgp_peer_in_prefixes_rejected', 'line'),
+        ('bgp_peer_in_prefixes_active', 'line'),
+        ('bgp_peer_in_prefixes', 'line'),
+    ],
+}
+
 ######################################################################################################################
 #
 # define perf-o-meter for bgp peer uptime + prefixes accepted/advertised
diff --git a/web/plugins/views/inv_bgp_peer.py b/web/plugins/views/inv_bgp_peer.py
index 3d828a1c6d8d54c3a58d7e921dedf05eeae00c80..af7261dd1710949a655d8b8a0551e71ca8fc4ae0 100644
--- a/web/plugins/views/inv_bgp_peer.py
+++ b/web/plugins/views/inv_bgp_peer.py
@@ -1,16 +1,24 @@
 #!/usr/bin/env python3
 # -*- coding: utf-8 -*-
 
+from cmk.gui.i18n import _
 from cmk.gui.plugins.views import (
     inventory_displayhints,
 )
-from cmk.gui.i18n import _
+from cmk.gui.plugins.visuals.inventory import (
+    FilterInvtableAdminStatus,
+    FilterInvtableTimestampAsAge,
+    FilterInvBool,
+)
+from cmk.gui.plugins.views.inventory import declare_invtable_view
 
 inventory_displayhints.update({
     '.networking.bgp_peers:': {
         'title': _('BGP Peers'),
         'keyorder': [
-            'remote_addr', 'local_addr', 'remote_id', 'local_id', 'remote_as', 'local_as', 'bgp_type', 'version',
+            'remote_addr',
+            'peer_state', 'last_change', 'in_service',
+            'local_addr', 'remote_id', 'local_id', 'remote_as', 'local_as',
         ],
         'view': 'invbgppeer_of_host',
     },
@@ -25,8 +33,26 @@ inventory_displayhints.update({
     '.networking.bgp_peers:*.last_error': {'title': _('Last error'), },
     '.networking.bgp_peers:*.last_error_code': {'title': _('Last error code'), },
     '.networking.bgp_peers:*.address_family': {'title': _('Address family'), },
+    '.networking.bgp_peers:*.as_name': {'title': _('Remote AS Name'), },
+    '.networking.bgp_peers:*.as_org_name': {'title': _('Remote AS Org Name'), },
+    '.networking.bgp_peers:*.peer_state': {
+        'title': _('Peer state'),
+        'short': _('State'),
+        'paint': 'if_admin_status',
+        'filter': FilterInvtableAdminStatus,
+    },
+    '.networking.bgp_peers:*.in_service': {
+        'title': _('In service'),
+        'short': _('In service'),
+        'paint': 'bool',
+        # 'filter': FilterInvBool,
+    },
+    '.networking.bgp_peers:*.last_change': {
+        'title': _('Last change'),
+        'short': _('Last change'),
+        'paint': 'timestamp_as_age_days',
+        'filter': FilterInvtableTimestampAsAge,
+    },
 })
 
-from cmk.gui.plugins.views.inventory import declare_invtable_view
-
 declare_invtable_view('invbgppeer', '.networking.bgp_peers:', _('BGP peers'), _('BGP peers'))
diff --git a/web/plugins/wato/bgp_peer.py b/web/plugins/wato/bgp_peer.py
index 3756c91874973b5b896b20839623a80b85d36f04..5e37eb5c8f0d3c87b198aec880155372f6609ffe 100644
--- a/web/plugins/wato/bgp_peer.py
+++ b/web/plugins/wato/bgp_peer.py
@@ -13,7 +13,10 @@
 # 2021-08-21: modified for bgp_peer plugin (from cisco_bgp_peer)
 # 2021-08-29: removed htmloutput and infotext_values option
 # 2022-04-02: added bgp neighbour states
+# 2022-04-29: added upper/lower prefix limit
+# 2022-05-09: added discovery rule set
 #
+
 from cmk.gui.i18n import _
 from cmk.gui.valuespec import (
     Dictionary,
@@ -23,12 +26,15 @@ from cmk.gui.valuespec import (
     Tuple,
     TextUnicode,
     MonitoringState,
+    ListChoice,
 )
 
 from cmk.gui.plugins.wato import (
     CheckParameterRulespecWithItem,
     rulespec_registry,
     RulespecGroupCheckParametersNetworking,
+    HostRulespec,
+    RulespecGroupCheckParametersDiscovery,
 )
 
 
@@ -37,10 +43,30 @@ def _parameter_valuespec_bgp_peer():
         ('minuptime',
          Tuple(
              title=_('Minimum uptime for peer'),
+             orientation='horizontal',
              help=_('Set the time in seconds, a peer must be up before the peer is considered sable.'),
              elements=[
-                 Integer(title=_('Warning if below'), unit='seconds', default_value=7200, minvalue=0),
-                 Integer(title=_('Critical if below'), unit='seconsa', default_value=3600, minvalue=0)
+                 Integer(title=_('Warning below'), unit='seconds', default_value=7200, minvalue=0),
+                 Integer(title=_('Critical below'), unit='seconds', default_value=3600, minvalue=0)
+             ],
+         )),
+        ('accepted_prefixes_upper_levels',
+         Tuple(
+             title=_('Accepted prefixes upper levels'),
+             help=_('The values from WATO are preferred to the values from the device.'),
+             orientation='horizontal',
+             elements=[
+                 Integer(title=_('Warning at'), minvalue=0, unit=_('prefixes'), size=5),
+                 Integer(title=_('Critical at'), minvalue=0, unit=_('prefixes'), size=5),
+             ],
+         )),
+        ('accepted_prefixes_lower_levels',
+         Tuple(
+             title=_('Accepted prefixes lower levels'),
+             orientation='horizontal',
+             elements=[
+                 Integer(title=_('Warning below'), minvalue=0, unit=_('prefixes'), size=5),
+                 Integer(title=_('Critical below'), minvalue=0, unit=_('prefixes'), size=5),
              ],
          )),
         ('peernotfound',
@@ -136,18 +162,21 @@ def _parameter_valuespec_bgp_peer():
         ('peer_list',
          ListOf(
              Tuple(
+                 orientation='horizontal',
                  elements=[
                      TextUnicode(
                          title=_('BGP Peer'),
                          help=_('The configured value must match a BGP item reported by the monitored '
                                 'device. For example: "10.194.115.98" or "2A10:1CD0:1020:135::20 IPv6 Unicast"'),
                          allow_empty=False,
+                         size=50,
                      ),
                      TextUnicode(
                          title=_('BGP Peer Alias'),
                          help=_('You can configure an individual alias here for the BGP peer matching '
                                 'the text configured in the "BGP Peer IP-address" field. The alias will '
                                 'be shown in the check info'),
+                         size=50,
                      ),
                      MonitoringState(
                          default_value=2,
@@ -172,3 +201,39 @@ rulespec_registry.register(
         parameter_valuespec=_parameter_valuespec_bgp_peer,
         title=lambda: _('BGP peer'),
     ))
+
+
+def _valuespec_discovery_bgp_peer():
+    item_parts = [
+        # ('remote_address', 'Peer remote address'),
+        ('address_family', 'Address family'),
+        ('routing_instance', 'Routing instance/VRF'),
+
+    ]
+    return Dictionary(
+            title=_('BGP peer'),
+            elements=[
+                ('build_item',
+                 ListChoice(
+                     title=_('Information not to use in the item name'),
+                     help=_(
+                         'The Peer remote address is always used as the item name. By default the check will add the '
+                         'address-family and the routing instance/VRF if available. You can decide to not use these '
+                         'additional information in the item name. Do so only if your peers have only one address-'
+                         'family configured and you don\'t have the same peer remote address in different routing '
+                         'instances/VRFs configured.'
+                     ),
+                     choices=item_parts,
+                     default_value=[],
+                 )),
+            ],
+        )
+
+
+rulespec_registry.register(
+    HostRulespec(
+        group=RulespecGroupCheckParametersDiscovery,
+        match_type='dict',
+        name='discovery_bgp_peer',
+        valuespec=_valuespec_discovery_bgp_peer,
+    ))
diff --git a/web/plugins/wato/inv_bgp_peer.py b/web/plugins/wato/inv_bgp_peer.py
new file mode 100644
index 0000000000000000000000000000000000000000..a62b0048c9d35ffbdce14e1f0e806efeef38420e
--- /dev/null
+++ b/web/plugins/wato/inv_bgp_peer.py
@@ -0,0 +1,107 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# Author: thl-cmk[at]outlook[dot]com
+# URL   : https://thl-cmk.hopto.org
+# Date  : 2022-04-24
+#
+# 2022-04-24: added option for BGP down time
+#             added option to remove some columns from inventory
+# 2022-04-28: added Whois options
+
+from cmk.gui.i18n import _
+from cmk.gui.plugins.wato import (
+    HostRulespec,
+    rulespec_registry,
+)
+from cmk.gui.valuespec import (
+    Dictionary,
+    ListChoice,
+    Age,
+    DropdownChoice,
+    Integer,
+)
+
+from cmk.gui.plugins.wato.inventory import (
+    RulespecGroupInventory,
+)
+
+
+def _valuespec_inv_bgp_peer():
+    removecolumns = [
+        # ('remote_as', 'Remote AS'),
+        # ('remote_id', 'Remote ID'),
+        # ('local_addr', 'Local address'),
+        # ('local_as', 'Local AS'),
+        # ('local_id', 'Local ID'),
+        ('address_family', 'Address family'),
+        ('last_error', 'Last error'),
+        ('last_error_code', 'Last error code'),
+        # ('prev_state', 'Previous state'),
+        ('as_name', 'Remote AS name'),
+        ('as_org_name', 'Remote AS Org Name'),
+        ('bgp_type', 'Type'),
+        ('version', 'Version'),
+    ]
+
+    return Dictionary(
+        title=_('BGP peer'),
+        elements=[
+            ('not_in_service_time',
+             Age(
+                 title=_('Time peer is not up until considered not in service'),
+                 default_value=2592000,  # 30 days in seconds,
+             )),
+            ('remove_columns',
+             ListChoice(
+                 title=_('List of columns to remove'),
+                 help=_('Information to remove from inventory'),
+                 choices=removecolumns,
+                 default_value=[],
+             )),
+            ('whois_enable',
+             Dictionary(
+                 title=_('Add whois data to the inventory'),
+                 help=_(
+                     'The whois data will be fetched via RDAP from the registries. For this the the plugin tries to'
+                     'find the best registry via the RDAP bootstrap data from https://data.iana.org/rdap/asn.json.'
+                     'The query it self will go to the found registry via http(s). Note: the request might be get '
+                     'redirected if there a different authoritative registry for the ASn'
+                 ),
+                 elements=[
+                     ('whois_rir',
+                      DropdownChoice(
+                          title='Preferred RIR to fetch whois data',
+                          help=_(
+                              'This registry will be used if the plugin can not determine the authoritative registry '
+                              'based on the bootstrap data.'
+                          ),
+                          choices=[
+                              ('afrinic', _('AFRINIC (https://rdap.afrinic.net/rdap)')),
+                              ('apnic', _('APNIC (https://rdap.apnic.net)')),
+                              ('arin', _('ARIN (https://rdap.arin.net/registry)')),
+                              ('ripe', _('RIPE (https://rdap.db.ripe.net)')),
+                              ('lacnic', _('LACNIC (https://rdap.apnic.net)')),
+                          ]
+                      )),
+                     ('whois_timeout',
+                      Integer(
+                          title='Timeout for connections to RIRs',
+                          help=_('The connection timeout for each whois request.'),
+                          default_value=5,
+                          minvalue=1,
+                          unit=_('seconds'),
+                      )),
+                 ]
+             )),
+        ],
+    )
+
+
+rulespec_registry.register(
+    HostRulespec(
+        group=RulespecGroupInventory,
+        match_type='dict',
+        name='inv_parameters:inv_bgp_peer',
+        valuespec=_valuespec_inv_bgp_peer,
+    ))