summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/frr/ldpd.frr.tmpl12
-rw-r--r--interface-definitions/protocols-mpls.xml.in26
-rwxr-xr-xsrc/conf_mode/protocols_mpls.py24
-rwxr-xr-xsrc/op_mode/lldp_op.py180
4 files changed, 124 insertions, 118 deletions
diff --git a/data/templates/frr/ldpd.frr.tmpl b/data/templates/frr/ldpd.frr.tmpl
index bbff88ae5..dbaa917e8 100644
--- a/data/templates/frr/ldpd.frr.tmpl
+++ b/data/templates/frr/ldpd.frr.tmpl
@@ -21,6 +21,18 @@ no discovery transport-address {{ old_ldp.d_transp_ipv4 }}
{% if ldp.d_transp_ipv4 -%}
discovery transport-address {{ ldp.d_transp_ipv4 }}
{% endif -%}
+{% if old_ldp.hello_holdtime -%}
+no discovery hello holdtime {{ old_ldp.hello_holdtime }}
+{% endif -%}
+{% if ldp.hello_holdtime -%}
+discovery hello holdtime {{ ldp.hello_holdtime }}
+{% endif -%}
+{% if old_ldp.hello_interval -%}
+no discovery hello interval {{ old_ldp.hello_interval }}
+{% endif -%}
+{% if ldp.hello_interval -%}
+discovery hello interval {{ ldp.hello_interval }}
+{% endif -%}
{% for interface in old_ldp.interfaces -%}
no interface {{interface}}
{% endfor -%}
diff --git a/interface-definitions/protocols-mpls.xml.in b/interface-definitions/protocols-mpls.xml.in
index 376323855..3e9edbf72 100644
--- a/interface-definitions/protocols-mpls.xml.in
+++ b/interface-definitions/protocols-mpls.xml.in
@@ -54,6 +54,30 @@
</valueHelp>
</properties>
<children>
+ <leafNode name="hello-holdtime">
+ <properties>
+ <help>Hello holdtime</help>
+ <valueHelp>
+ <format>1-65535</format>
+ <description>Time in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-65535"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ <leafNode name="hello-interval">
+ <properties>
+ <help>Hello interval</help>
+ <valueHelp>
+ <format>1-65535</format>
+ <description>Time in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-65535"/>
+ </constraint>
+ </properties>
+ </leafNode>
<leafNode name="transport-ipv4-address">
<properties>
<help>Transport ipv4 address</help>
@@ -95,4 +119,4 @@
</node>
</children>
</node>
-</interfaceDefinition> \ No newline at end of file
+</interfaceDefinition>
diff --git a/src/conf_mode/protocols_mpls.py b/src/conf_mode/protocols_mpls.py
index 72208ffa1..bcb16fa04 100755
--- a/src/conf_mode/protocols_mpls.py
+++ b/src/conf_mode/protocols_mpls.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019 VyOS maintainers and contributors
+# Copyright (C) 2019-2020 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -38,13 +38,17 @@ def get_config():
'interfaces' : [],
'neighbors' : {},
'd_transp_ipv4' : None,
- 'd_transp_ipv6' : None
+ 'd_transp_ipv6' : None,
+ 'hello_holdtime' : None,
+ 'hello_interval' : None
},
'ldp' : {
'interfaces' : [],
'neighbors' : {},
'd_transp_ipv4' : None,
- 'd_transp_ipv6' : None
+ 'd_transp_ipv6' : None,
+ 'hello_holdtime' : None,
+ 'hello_interval' : None
}
}
if not (conf.exists('protocols mpls') or conf.exists_effective('protocols mpls')):
@@ -61,6 +65,20 @@ def get_config():
if conf.exists('router-id'):
mpls_conf['router_id'] = conf.return_value('router-id')
+ # Get hello holdtime
+ if conf.exists_effective('discovery hello-holdtime'):
+ mpls_conf['old_ldp']['hello_holdtime'] = conf.return_effective_value('discovery hello-holdtime')
+
+ if conf.exists('discovery hello-holdtime'):
+ mpls_conf['ldp']['hello_holdtime'] = conf.return_value('discovery hello-holdtime')
+
+ # Get hello interval
+ if conf.exists_effective('discovery hello-interval'):
+ mpls_conf['old_ldp']['hello_interval'] = conf.return_effective_value('discovery hello-interval')
+
+ if conf.exists('discovery hello-interval'):
+ mpls_conf['ldp']['hello_interval'] = conf.return_value('discovery hello-interval')
+
# Get discovery transport-ipv4-address
if conf.exists_effective('discovery transport-ipv4-address'):
mpls_conf['old_ldp']['d_transp_ipv4'] = conf.return_effective_value('discovery transport-ipv4-address')
diff --git a/src/op_mode/lldp_op.py b/src/op_mode/lldp_op.py
index 0df6749aa..06958c605 100755
--- a/src/op_mode/lldp_op.py
+++ b/src/op_mode/lldp_op.py
@@ -16,10 +16,10 @@
import argparse
import jinja2
+import json
from sys import exit
from tabulate import tabulate
-from xml.dom import minidom
from vyos.util import cmd
from vyos.config import Config
@@ -35,106 +35,61 @@ lldp_out = """Capability Codes: R - Router, B - Bridge, W - Wlan r - Repeater, S
Device ID Local Proto Cap Platform Port ID
--------- ----- ----- --- -------- -------
-{% for n in neighbors -%}
-{{ "%-25s" | format(n.chassis) }} {{ "%-9s" | format(n.interface) }} {{ "%-6s" | format(n.proto) }} {{ "%-5s" | format(n.cap) }} {{ "%-20s" | format(n.platform) }} {{ n.port }}
-{% endfor -%}
+{% for neighbor in neighbors %}
+{% for local_if, info in neighbor.items() %}
+{{ "%-25s" | format(info.chassis) }} {{ "%-9s" | format(local_if) }} {{ "%-6s" | format(info.proto) }} {{ "%-5s" | format(info.capabilities) }} {{ "%-20s" | format(info.platform[:18]) }} {{ info.remote_if }}
+{% endfor %}
+{% endfor %}
"""
def get_neighbors():
- return cmd('/usr/sbin/lldpcli -f xml show neighbors')
-
-def extract_neighbor(neighbor):
- """
- Extract LLDP neighbor information from XML document passed as param neighbor
-
- <lldp>
- <interface label="Interface" name="eth0" via="LLDP" rid="3" age="0 day, 00:17:42">
- <chassis label="Chassis">
- <id label="ChassisID" type="mac">00:50:56:9d:a6:11</id>
- <name label="SysName">VyOS</name>
- <descr label="SysDescr">VyOS unknown</descr>
- <mgmt-ip label="MgmtIP">172.18.254.203</mgmt-ip>
- <mgmt-ip label="MgmtIP">fe80::250:56ff:fe9d:a611</mgmt-ip>
- <capability label="Capability" type="Bridge" enabled="off"/>
- <capability label="Capability" type="Router" enabled="on"/>
- <capability label="Capability" type="Wlan" enabled="off"/>
- <capability label="Capability" type="Station" enabled="off"/>
- </chassis>
- <port label="Port">
- <id label="PortID" type="mac">00:50:56:9d:a6:11</id>
- <descr label="PortDescr">eth0</descr>
- <ttl label="TTL">120</ttl>
- <auto-negotiation label="PMD autoneg" supported="no" enabled="no">
- <current label="MAU oper type">10GigBaseCX4 - X copper over 8 pair 100-Ohm balanced cable</current>
- </auto-negotiation>
- </port>
- <vlan label="VLAN" vlan-id="203">eth0.203</vlan>
- <lldp-med label="LLDP-MED">
- <device-type label="Device Type">Network Connectivity Device</device-type>
- <capability label="Capability" type="Capabilities" available="yes"/>
- <capability label="Capability" type="Policy" available="yes"/>
- <capability label="Capability" type="Location" available="yes"/>
- <capability label="Capability" type="MDI/PSE" available="yes"/>
- <capability label="Capability" type="MDI/PD" available="yes"/>
- <capability label="Capability" type="Inventory" available="yes"/>
- <inventory label="Inventory">
- <hardware label="Hardware Revision">None</hardware>
- <software label="Software Revision">4.19.54-amd64-vyos</software>
- <firmware label="Firmware Revision">6.00</firmware>
- <serial label="Serial Number">VMware-42 1d cf 87 ab 7f da 7e-3</serial>
- <manufacturer label="Manufacturer">VMware, Inc.</manufacturer>
- <model label="Model">VMware Virtual Platform</model>
- <asset label="Asset ID">No Asset Tag</asset>
- </inventory>
- </lldp-med>
- </interface>
- </lldp>
- """
-
- device = {
- 'interface' : neighbor.getAttribute('name'),
- 'chassis' : '',
- 'proto' : neighbor.getAttribute('via'),
- 'descr' : '',
- 'cap' : '',
- 'platform' : '',
- 'port' : ''
- }
-
- # first change to <chassis> node and then retrieve <name> and <descr>
- chassis = neighbor.getElementsByTagName('chassis')
- device['chassis'] = chassis[0].getElementsByTagName('name')[0].firstChild.data
- # Cisco IOS comes with a ',' remove character ....
- device['platform'] = chassis[0].getElementsByTagName('descr')[0].firstChild.data[:20].replace(',',' ')
-
- # extract capabilities
- for capability in chassis[0].getElementsByTagName('capability'):
- # we are only interested in enabled capabilities ...
- if capability.getAttribute('enabled') == "on":
- if capability.getAttribute('type') == "Router":
- device['cap'] += 'R'
- elif capability.getAttribute('type') == "Bridge":
- device['cap'] += 'B'
- elif capability.getAttribute('type') == "Wlan":
- device['cap'] += 'W'
- elif capability.getAttribute('type') == "Station":
- device['cap'] += 'S'
- elif capability.getAttribute('type') == "Repeater":
- device['cap'] += 'r'
- elif capability.getAttribute('type') == "Telephone":
- device['cap'] += 'T'
- elif capability.getAttribute('type') == "Docsis":
- device['cap'] += 'D'
- elif capability.getAttribute('type') == "Other":
- device['cap'] += 'O'
-
- # first change to <port> node and then retrieve <descr>
- port = neighbor.getElementsByTagName('port')
- port = port[0].getElementsByTagName('descr')[0].firstChild.data
- device['port'] = port
-
-
- return device
+ return cmd('/usr/sbin/lldpcli -f json show neighbors')
+
+def parse_data(data):
+ output = []
+ for tmp in data:
+ for local_if, values in tmp.items():
+ for chassis, c_value in values.get('chassis', {}).items():
+ capabilities = c_value['capability']
+ if isinstance(capabilities, dict):
+ capabilities = [capabilities]
+
+ cap = ''
+ for capability in capabilities:
+ if capability['enabled']:
+ if capability['type'] == 'Router':
+ cap += 'R'
+ if capability['type'] == 'Bridge':
+ cap += 'B'
+ if capability['type'] == 'Wlan':
+ cap += 'W'
+ if capability['type'] == 'Station':
+ cap += 'S'
+ if capability['type'] == 'Repeater':
+ cap += 'r'
+ if capability['type'] == 'Telephone':
+ cap += 'T'
+ if capability['type'] == 'Docsis':
+ cap += 'D'
+ if capability['type'] == 'Other':
+ cap += 'O'
+
+
+ remote_if = 'Unknown'
+ if 'descr' in values.get('port', {}):
+ remote_if = values.get('port', {}).get('descr')
+ elif 'id' in values.get('port', {}):
+ remote_if = values.get('port', {}).get('id').get('value', 'Unknown')
+
+ output.append({local_if: {'chassis': chassis,
+ 'remote_if': remote_if,
+ 'proto': values.get('via','Unknown'),
+ 'platform': c_value.get('descr', 'Unknown'),
+ 'capabilities': cap}})
+
+
+ output = {'neighbors': output}
+ return output
if __name__ == '__main__':
args = parser.parse_args()
@@ -145,29 +100,26 @@ if __name__ == '__main__':
print('Service LLDP is not configured')
exit(0)
- if args.all:
- neighbors = minidom.parseString(get_neighbors())
- for neighbor in neighbors.getElementsByTagName('interface'):
- tmp['neighbors'].append( extract_neighbor(neighbor) )
-
- elif args.detail:
- out = cmd('/usr/sbin/lldpctl -f plain')
- print(out)
+ if args.detail:
+ print(cmd('/usr/sbin/lldpctl -f plain'))
exit(0)
+ elif args.all or args.interface:
+ tmp = json.loads(get_neighbors())
- elif args.interface:
- neighbors = minidom.parseString(get_neighbors())
- for neighbor in neighbors.getElementsByTagName('interface'):
- # check if neighbor appeared on proper interface
- if neighbor.getAttribute('name') == args.interface:
- tmp['neighbors'].append( extract_neighbor(neighbor) )
+ if args.all:
+ neighbors = tmp['lldp']['interface']
+ elif args.interface:
+ neighbors = []
+ for neighbor in tmp['lldp']['interface']:
+ if args.interface in neighbor:
+ neighbors.append(neighbor)
else:
parser.print_help()
exit(1)
- tmpl = jinja2.Template(lldp_out)
- config_text = tmpl.render(tmp)
+ tmpl = jinja2.Template(lldp_out, trim_blocks=True)
+ config_text = tmpl.render(parse_data(neighbors))
print(config_text)
exit(0)