From fbdfd7a2f03205d69ebe53e927f378850f832a20 Mon Sep 17 00:00:00 2001 From: DmitriyEshenko Date: Sat, 4 Apr 2020 20:51:22 +0000 Subject: pim: T1729: Add dr-priority and IGMP join support --- interface-definitions/protocols-igmp.xml.in | 27 +++++++++++++++++++++++ interface-definitions/protocols-pim.xml.in | 12 ++++++++++ src/conf_mode/protocols_igmp.py | 34 +++++++++++++++++++++++++++-- src/conf_mode/protocols_pim.py | 11 +++++++--- 4 files changed, 79 insertions(+), 5 deletions(-) diff --git a/interface-definitions/protocols-igmp.xml.in b/interface-definitions/protocols-igmp.xml.in index a6a2f1420..a9b11e1a3 100644 --- a/interface-definitions/protocols-igmp.xml.in +++ b/interface-definitions/protocols-igmp.xml.in @@ -16,6 +16,33 @@ + + + IGMP join multicast group + + ipv4 + Multicast group address + + + + + + + + + Source address + + ipv4 + Source address + + + + + + + + + IGMP version diff --git a/interface-definitions/protocols-pim.xml.in b/interface-definitions/protocols-pim.xml.in index 944224f7b..6152045a7 100644 --- a/interface-definitions/protocols-pim.xml.in +++ b/interface-definitions/protocols-pim.xml.in @@ -17,6 +17,18 @@ + + + Designated Router Election Priority + + 1-4294967295 + Value of the new DR Priority + + + + + + Hello Interval diff --git a/src/conf_mode/protocols_igmp.py b/src/conf_mode/protocols_igmp.py index 8d25fe9d5..dcbd9a0a8 100755 --- a/src/conf_mode/protocols_igmp.py +++ b/src/conf_mode/protocols_igmp.py @@ -23,6 +23,7 @@ import vyos.validate from vyos import ConfigError from vyos.config import Config +from ipaddress import IPv4Address config_file = r'/tmp/igmp.frr' @@ -31,6 +32,15 @@ config_tmpl = """ ! {% for iface in old_ifaces -%} interface {{ iface }} +{% for group in old_ifaces[iface].gr_join -%} +{% if old_ifaces[iface].gr_join[group] -%} +{% for source in old_ifaces[iface].gr_join[group] -%} +no ip igmp join {{ group }} {{ source }} +{% endfor -%} +{% else -%} +no ip igmp join {{ group }} +{% endif -%} +{% endfor -%} no ip igmp ! {% endfor -%} @@ -48,6 +58,15 @@ ip igmp query-interval {{ ifaces[iface].query_interval }} {% if ifaces[iface].query_max_resp_time -%} ip igmp query-max-response-time {{ ifaces[iface].query_max_resp_time }} {% endif -%} +{% for group in ifaces[iface].gr_join -%} +{% if ifaces[iface].gr_join[group] -%} +{% for source in ifaces[iface].gr_join[group] -%} +ip igmp join {{ group }} {{ source }} +{% endfor -%} +{% else -%} +ip igmp join {{ group }} +{% endif -%} +{% endfor -%} ! {% endfor -%} ! @@ -74,18 +93,24 @@ def get_config(): iface : { 'version' : conf.return_effective_value('interface {0} version'.format(iface)), 'query_interval' : conf.return_effective_value('interface {0} query-interval'.format(iface)), - 'query_max_resp_time' : conf.return_effective_value('interface {0} query-max-response-time'.format(iface)) + 'query_max_resp_time' : conf.return_effective_value('interface {0} query-max-response-time'.format(iface)), + 'gr_join' : {} } }) + for gr_join in conf.list_effective_nodes('interface {0} join'.format(iface)): + igmp_conf['old_ifaces'][iface]['gr_join'][gr_join] = conf.return_effective_values('interface {0} join {1} source'.format(iface, gr_join)) for iface in conf.list_nodes('interface'): igmp_conf['ifaces'].update({ iface : { 'version' : conf.return_value('interface {0} version'.format(iface)), 'query_interval' : conf.return_value('interface {0} query-interval'.format(iface)), - 'query_max_resp_time' : conf.return_value('interface {0} query-max-response-time'.format(iface)) + 'query_max_resp_time' : conf.return_value('interface {0} query-max-response-time'.format(iface)), + 'gr_join' : {} } }) + for gr_join in conf.list_nodes('interface {0} join'.format(iface)): + igmp_conf['ifaces'][iface]['gr_join'][gr_join] = conf.return_values('interface {0} join {1} source'.format(iface, gr_join)) return igmp_conf @@ -97,6 +122,11 @@ def verify(igmp): # Check interfaces if not igmp['ifaces']: raise ConfigError(f"IGMP require defined interfaces!") + # Check, is this multicast group + for intfc in igmp['ifaces']: + for gr_addr in igmp['ifaces'][intfc]['gr_join']: + if IPv4Address(gr_addr) < IPv4Address('224.0.0.0'): + raise ConfigError(gr_addr + " not a multicast group") def generate(igmp): if igmp is None: diff --git a/src/conf_mode/protocols_pim.py b/src/conf_mode/protocols_pim.py index dc65a59a6..f4c365923 100755 --- a/src/conf_mode/protocols_pim.py +++ b/src/conf_mode/protocols_pim.py @@ -45,10 +45,13 @@ no ip pim {% endfor -%} {% for iface in pim.ifaces -%} interface {{ iface }} +ip pim +{% if pim.ifaces[iface].dr_prio -%} +ip pim drpriority {{ pim.ifaces[iface].dr_prio }} +{% endif -%} {% if pim.ifaces[iface].hello -%} ip pim hello {{ pim.ifaces[iface].hello }} {% endif -%} -ip pim ! {% endfor -%} {% for rp_addr in pim.rp -%} @@ -87,14 +90,16 @@ def get_config(): for iface in conf.list_effective_nodes('interface'): pim_conf['old_pim']['ifaces'].update({ iface : { - 'hello' : conf.return_effective_value('interface {0} hello'.format(iface)) + 'hello' : conf.return_effective_value('interface {0} hello'.format(iface)), + 'dr_prio' : conf.return_effective_value('interface {0} dr-priority'.format(iface)) } }) for iface in conf.list_nodes('interface'): pim_conf['pim']['ifaces'].update({ iface : { - 'hello' : conf.return_value('interface {0} hello'.format(iface)) + 'hello' : conf.return_value('interface {0} hello'.format(iface)), + 'dr_prio' : conf.return_value('interface {0} dr-priority'.format(iface)), } }) -- cgit v1.2.3