diff --git a/agent_based/utils/bgp_peer.py b/agent_based/utils/bgp_peer.py
index 6792c53a0ccf2dc5a62c643d242bace0c6014703..616f18c3576085dec8c63eca394336b6576c481e 100644
--- a/agent_based/utils/bgp_peer.py
+++ b/agent_based/utils/bgp_peer.py
@@ -61,7 +61,7 @@ class InvBgpPeer(TypedDict):
     remote_addr: str
     remote_id: str
     version: str
-    local_addr:str
+    local_addr: str
     remote_as: str
     local_as: str
     local_id: str
@@ -127,49 +127,48 @@ def bgp_error_as_string(error_code: List[int]):
     except ValueError:
         return 'Unknown'
 
-    names = {}
-    names[0] = {0: 'NO ERROR'}
-    names[1] = {
-        0: 'Message',
-        2: 'Connection Not Synchronized',
-        3: 'Bad Message Length',
-        4: 'Bad Message Type',
-    }
-    names[2] = {
-        0: 'OPEN',
-        1: 'Unsupported Version Number',
-        2: 'Bad Peer AS',
-        3: 'Bad BGP Identifier',
-        4: 'Unsupported Optional Parameter',
-        5: 'Authentication Failure',
-        6: 'Unacceptable Hold',
-    }
-    names[3] = {
-        0: 'UPDATE',
-        1: 'Malformed Attribute List',
-        2: 'Unrecognized Well-known Attribute',
-        3: 'Missing Well-known Attribute',
-        4: 'Attribute Flags Error',
-        5: 'Attribute Length Error',
-        6: 'Invalid ORIGIN Attribute',
-        7: 'AS Routing Loop',
-        8: 'Invalid NEXT_HOP Attribute',
-        9: 'Optional Attribute Error',
-        10: 'Invalid Network Field',
-        11: 'Malformed AS_PATH',
-    }
-    names[4] = {0: 'Hold Timer Expired', }
-
-    names[5] = {0: 'Finite State Machine Error', }
+    names = {
+        0: {0: 'NO ERROR'},
+        1: {
+            0: 'Message',
+            2: 'Connection Not Synchronized',
+            3: 'Bad Message Length',
+            4: 'Bad Message Type',
+        },
+        2: {
+            0: 'OPEN',
+            1: 'Unsupported Version Number',
+            2: 'Bad Peer AS',
+            3: 'Bad BGP Identifier',
+            4: 'Unsupported Optional Parameter',
+            5: 'Authentication Failure',
+            6: 'Unacceptable Hold',
+        },
+        3: {
+            0: 'UPDATE',
+            1: 'Malformed Attribute List',
+            2: 'Unrecognized Well-known Attribute',
+            3: 'Missing Well-known Attribute',
+            4: 'Attribute Flags Error',
+            5: 'Attribute Length Error',
+            6: 'Invalid ORIGIN Attribute',
+            7: 'AS Routing Loop',
+            8: 'Invalid NEXT_HOP Attribute',
+            9: 'Optional Attribute Error',
+            10: 'Invalid Network Field',
+            11: 'Malformed AS_PATH',
+        },
+        4: {0: 'Hold Timer Expired', },
+        5: {0: 'Finite State Machine Error', },
+        6: {
+            0: 'Administratively Shutdown',
+            1: 'Max Prefix Reached',
+            2: 'Peer Unconfigured',
+            3: 'Administratively Reset',
+            4: 'Connection Rejected',
+            5: 'Other Configuration Change',
+        }}
 
-    names[6] = {
-        0: 'Administratively Shutdown',
-        1: 'Max Prefix Reached',
-        2: 'Peer Unconfigured',
-        3: 'Administratively Reset',
-        4: 'Connection Rejected',
-        5: 'Other Configuration Change',
-    }
     return names[main_code].get(sub_code)
 
 
diff --git a/bgp_peer.mkp b/bgp_peer.mkp
index 322502aab47095cb19f46e0dcd836ddf4b8f97a3..516ed8629448dc176edecabe4598ca217129752a 100644
Binary files a/bgp_peer.mkp and b/bgp_peer.mkp differ
diff --git a/gui/views/inv_bgp_peer.py b/gui/views/inv_bgp_peer.py
index f67054ca29363b724051f9db0549d5307c6f2049..7f2153ac8ecbc83c06962c982c8e4360f65a321f 100644
--- a/gui/views/inv_bgp_peer.py
+++ b/gui/views/inv_bgp_peer.py
@@ -2,15 +2,11 @@
 # -*- coding: utf-8 -*-
 
 from cmk.gui.i18n import _
-from cmk.gui.plugins.views.utils import (
-    inventory_displayhints,
-)
 from cmk.gui.plugins.visuals.inventory import (
     FilterInvtableAdminStatus,
     FilterInvtableTimestampAsAge,
-    FilterInvBool,
 )
-from cmk.gui.plugins.views.inventory import declare_invtable_view
+from cmk.gui.views.inventory.registry import inventory_displayhints
 
 inventory_displayhints.update({
     '.networking.bgp_peers:': {
@@ -54,5 +50,3 @@ inventory_displayhints.update({
         'filter': FilterInvtableTimestampAsAge,
     },
 })
-
-declare_invtable_view('invbgppeer', '.networking.bgp_peers:', _('BGP peers'), _('BGP peers'))
diff --git a/gui/wato/check_parameters/bgp_peer.py b/gui/wato/check_parameters/bgp_peer.py
new file mode 100644
index 0000000000000000000000000000000000000000..bcfff4fbfafac8fe10c406192a1e9670f1c7e039
--- /dev/null
+++ b/gui/wato/check_parameters/bgp_peer.py
@@ -0,0 +1,255 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# License: GNU General Public License v2
+#
+# Author: thl-cmk[at]outlook[dot]com
+# URL   : https://thl-cmk.hopto.org
+# Date  : 2017-12-25
+#
+# Check_MK bgp_peers WATO plugin
+#
+# 2021-03-27: rewrite for CMK 2.0
+# 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
+# 2022-05-11: added remote_as to build_item
+# 2022-09-05: added internal_item to avoid warnings on cmk updates (THX to Jay2k1 for reporting the issue)
+# 2023-06-11: moved wato file from ~local/lib/check_mk/gui/plugins/wato
+#             to ~/local/lib/check_mk/gui/plugins/wato/check_parameters to override the build in wato plugin
+#
+# Known issue: the override of the build in wato plugin will break the build in aritsa bgp peer plugin
+
+from cmk.gui.i18n import _
+from cmk.gui.valuespec import (
+    Dictionary,
+    Integer,
+    TextAscii,
+    ListOf,
+    Tuple,
+    TextUnicode,
+    MonitoringState,
+    ListChoice,
+    TextInput,
+)
+
+from cmk.gui.plugins.wato.utils import (
+    CheckParameterRulespecWithItem,
+    rulespec_registry,
+    RulespecGroupCheckParametersNetworking,
+    HostRulespec,
+    RulespecGroupCheckParametersDiscovery,
+)
+
+
+def _parameter_valuespec_bgp_peer():
+    return Dictionary(
+        elements=[
+            ('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 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',
+             MonitoringState(
+                 default_value=2,
+                 title=_('State if peer is no not found.'),
+                 help=_('Default monitoring state if the peer is not found in the SNMP data')
+             )),
+            ('admindown',
+             MonitoringState(
+                 default_value=1,
+                 title=_('State if peer is admin shutdown.'),
+                 help=_('Monitoring state if the peer is admin shutdown')
+             )),
+            ('neighborstate',
+             Dictionary(
+                 title=_('State to report for BGP neighbor state'),
+                 help=_('Map each BGP state to a CheckMK monitoring state'),
+                 elements=[
+                     ('1',
+                      MonitoringState(
+                          title=_('1 - idle'),
+                          help=_(
+                              'This is the first stage of the BGP FSM. BGP detects a start event, tries to initiate a '
+                              'TCP connection to the BGP peer, and also listens for a new connect from a peer router. '
+                              'If an error causes BGP to go back to the Idle state for a second time, the '
+                              'ConnectRetryTimer is set to 60 seconds and must decrement to zero before the connection '
+                              'is initiated again. Further failures to leave the Idle state result in the '
+                              'ConnectRetryTimer doubling in length from the previous time. '
+                              'Default monitoring state is "CRIT"'),
+                          default_value=2,
+                      )),
+                     ('2',
+                      MonitoringState(
+                          title=_('2 - connect'),
+                          help=_(
+                              'In this state, BGP initiates the TCP connection. If the 3-way TCP handshake completes, '
+                              'the established BGP Session BGP process resets the ConnectRetryTimer and sends the Open '
+                              'message to the neighbor, and then changes to the OpenSent State.'
+                              'Default monitoring state is "WARN"'),
+                          default_value=1,
+                      )),
+                     ('3',
+                      MonitoringState(
+                          title=_('3 - active'),
+                          help=_('In this state, BGP starts a new 3-way TCP handshake. If a connection is established, '
+                                 'an Open message is sent, the Hold Timer is set to 4 minutes, and the state moves to '
+                                 'OpenSent. If this attempt for TCP connection fails, the state moves back to the Connect '
+                                 'state and resets the ConnectRetryTimer. '
+                                 'Default monitoring state is "WARN"'),
+                          default_value=1,
+                      )),
+                     ('4',
+                      MonitoringState(
+                          title=_('4 - opensent'),
+                          help=_(
+                              'In this state, an Open message has been sent from the originating router and is awaiting '
+                              'an Open message from the other router. After the originating router receives the OPEN '
+                              'message from the other router, both OPEN messages are checked for errors. If the Open '
+                              'messages do not have any errors, the Hold Time is negotiated (using the lower value), '
+                              'and a KEEPALIVE message is sent (assuming the value is not set to zero). The connection '
+                              'state is then moved to OpenConfirm. If an error is found in the OPEN message, a '
+                              'Notification message is sent, and the state is moved back to Idle.'
+                              ' Default monitoring state is "WARN"'),
+                          default_value=1,
+                      )),
+                     ('5',
+                      MonitoringState(
+                          title=_('5 - openconfirm'),
+                          help=_('In this state, BGP waits for a Keepalive or Notification message. Upon receipt of a '
+                                 'neighbor’s Keepalive, the state is moved to Established. If the hold timer expires, a '
+                                 'stop event occurs, or a Notification message is received, and the state is moved to '
+                                 'Idle. '
+                                 'Default monitoring state is "WARN"'),
+                          default_value=1,
+                      )),
+                     ('6',
+                      MonitoringState(
+                          title=_('6 - established'),
+                          help=_(
+                              'In this state, the BGP session is established. BGP neighbors exchange routes via Update '
+                              'messages. As Update and Keepalive messages are received, the Hold Timer is reset. If the '
+                              'Hold Timer expires, an error is detected and BGP moves the neighbor back to the Idle '
+                              'state. '
+                              'Default monitoring state is "OK"'),
+                          default_value=0,
+                      )),
+                 ])),
+            ('noprefixlimit',
+             MonitoringState(
+                 default_value=1,
+                 title=_('State if no admin prefix limit/warn threshold is configured.'),
+                 help=_('The admin prefix limit and warn threshold needs to be configured on the device. '
+                        'For example: "neighbor 172.17.10.10 maximum-prefix 10000 80". The threshold is in percentage '
+                        'of the prefix limit.')
+             )),
+            ('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,
+                             title=_('State if not found'),
+                             help=_('You can configure an individual state if the BGP peer matching the text '
+                                    'configured in the "BGP Peer IP-address" field is not found')
+                         ),
+                     ]),
+                 add_label=_('Add BGP peer'),
+                 movable=False,
+                 title=_('BGP Peers'),
+             )),
+            ('internal_item',  # added by plugin discovery function
+             TextUnicode()),
+        ],
+        hidden_keys=['internal_item'],
+    )
+
+
+rulespec_registry.register(
+    CheckParameterRulespecWithItem(
+        check_group_name='bgp_peer',
+        group=RulespecGroupCheckParametersNetworking,
+        item_spec=lambda: TextInput(title=_('BGP peer'), ),
+        match_type='dict',
+        parameter_valuespec=_parameter_valuespec_bgp_peer,
+        title=lambda: _('BGP peer'),
+    ))
+
+
+def _valuespec_discovery_bgp_peer():
+    item_parts = [
+        # ('remote_address', 'Peer remote address'),
+        ('remote_as', 'Remote AS'),
+        ('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=['remote_as'],
+                 )),
+            ],
+        )
+
+
+rulespec_registry.register(
+    HostRulespec(
+        group=RulespecGroupCheckParametersDiscovery,
+        match_type='dict',
+        name='discovery_bgp_peer',
+        valuespec=_valuespec_discovery_bgp_peer,
+    ))
diff --git a/gui/wato/check_parameters/inv_bgp_peer.py b/gui/wato/check_parameters/inv_bgp_peer.py
new file mode 100644
index 0000000000000000000000000000000000000000..f4832c661908036a3d309eb0b9f13b8dcba7db90
--- /dev/null
+++ b/gui/wato/check_parameters/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.utils 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,
+    ))
diff --git a/packages/bgp_peer b/packages/bgp_peer
index 99a8b76789c275f737d6710b3f76e4508ba2ee44..f7c703172b9df97c24863bef6ee2d03f72508143 100644
--- a/packages/bgp_peer
+++ b/packages/bgp_peer
@@ -15,11 +15,11 @@
            'checkman': ['bgp_peer'],
            'gui': ['metrics/bgp_peer.py',
                    'views/inv_bgp_peer.py',
-                   'wato/bgp_peer.py',
-                   'wato/inv_bgp_peer.py']},
+                   'wato/check_parameters/bgp_peer.py',
+                   'wato/check_parameters/inv_bgp_peer.py']},
  'name': 'bgp_peer',
  'title': 'BGP Peer',
- 'version': '2.0.1-20230611',
- 'version.min_required': '2.1.0b1',
+ 'version': '2.2.1-20230612',
+ 'version.min_required': '2.2.0b1',
  'version.packaged': '2.2.0p2',
- 'version.usable_until': '2.2.0b1'}
+ 'version.usable_until': None}