]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge branch 'master' into pim_5549
authorDonald Sharp <sharpd@cumulusnetworks.com>
Sat, 1 Apr 2017 11:58:05 +0000 (07:58 -0400)
committerGitHub <noreply@github.com>
Sat, 1 Apr 2017 11:58:05 +0000 (07:58 -0400)
34 files changed:
doc/Building_FRR_on_CentOS6.md
doc/Building_FRR_on_CentOS7.md
doc/Building_FRR_on_Debian8.md
doc/Building_FRR_on_Fedora24.md
doc/Building_FRR_on_FreeBSD10.md
doc/Building_FRR_on_FreeBSD11.md
doc/Building_FRR_on_FreeBSD9.md
doc/Building_FRR_on_NetBSD6.md
doc/Building_FRR_on_NetBSD7.md
doc/Building_FRR_on_OmniOS.md
doc/Building_FRR_on_OpenBSD6.md
doc/Building_FRR_on_Ubuntu1204.md
doc/Building_FRR_on_Ubuntu1404.md
doc/Building_FRR_on_Ubuntu1604.md
nhrpd/.gitignore [new file with mode: 0644]
pimd/Makefile.am
pimd/pim_cmd.c
pimd/pim_iface.h
pimd/pim_ifchannel.c
pimd/pim_main.c
pimd/pim_memory.c
pimd/pim_memory.h
pimd/pim_mroute.c
pimd/pim_register.c
pimd/pim_register.h
pimd/pim_ssm.c [new file with mode: 0644]
pimd/pim_ssm.h [new file with mode: 0644]
pimd/pim_upstream.c
pimd/pim_upstream.h
pimd/pim_vty.c
pimd/pim_zebra.c
pimd/pim_zebra.h
pimd/pimd.c
pimd/pimd.h

index ccb07fb2acf7157a970dc7ff50354e75a78e5af5..3829962d4a0b172f8491f261254889f438ed1c75 100644 (file)
@@ -18,7 +18,7 @@ Add packages:
 
     sudo yum install git autoconf automake libtool make gawk readline-devel \
       texinfo net-snmp-devel groff pkgconfig json-c-devel pam-devel \
-      flex pytest
+      flex c-ares-devel epel-release
 
 Install newer version of bison (CentOS 6 package source is too old) from 
 CentOS 7
@@ -48,16 +48,16 @@ Install newer version of autoconf and automake (Package versions are too old)
 
 Install `Python 2.7` in parallel to default 2.6 (needed for `make check` to 
 run unittests). 
-Pick correct EPEL based on CentOS version used. Then install current `pytest`
+Make sure you've install EPEL (`epel-release` as above). Then install current 
+`python2.7` and `pytest`
 
-    rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
     rpm -ivh https://centos6.iuscommunity.org/ius-release.rpm
-    yum install python27 python27-pip
+    yum install python27 python27-devel python27-pip 
     pip2.7 install pytest
 
 Please note that `CentOS 6` needs to keep python pointing to version 2.6 
 for `yum` to keep working, so don't create a symlink for python2.7 to python
-    
+
 Get FRR, compile it and install it (from Git)
 ---------------------------------------------
 
@@ -80,7 +80,6 @@ them if you are not building on a x86_64 architecture
 
     git clone https://github.com/freerangerouting/frr.git frr
     cd frr
-    git checkout stable/2.0
     ./bootstrap.sh
     ./configure \
         --sysconfdir=/etc/frr \
index cd10a91ed74fefad7b367a6060261e988ed52955..41c88b5593dbb7beb6bdc7f4d7f8583f9f7c3552 100644 (file)
@@ -10,12 +10,16 @@ CentOS 7 restrictions:
   
 Install required packages
 -------------------------
-        
+
 Add packages:
 
     sudo yum install git autoconf automake libtool make gawk readline-devel \
       texinfo net-snmp-devel groff pkgconfig json-c-devel pam-devel \
-      bison flex pytest
+      bison flex pytest c-ares-devel python-devel
+
+To build from git (in difference to building from distribution tar.gz as created by `make dist`), the python development libraries are needed. (Make sure you've installed EPEL libraries as shown above for this to work)
+
+    yum install python34-devel
 
 Get FRR, compile it and install it (from Git)
 ---------------------------------------------
@@ -39,7 +43,6 @@ them if you are not building on a x86_64 architecture
 
     git clone https://github.com/freerangerouting/frr.git frr
     cd frr
-    git checkout stable/2.0
     ./bootstrap.sh
     ./configure \
         --sysconfdir=/etc/frr \
index 902f8c623ae63a00760488df29c8420905b4c93c..1acbb802f629cc549f78fe7888f2f434e55adc92 100644 (file)
@@ -10,12 +10,12 @@ Debian 8 restrictions:
 
 Install required packages
 -------------------------
-        
+
 Add packages:
 
     sudo apt-get install git autoconf automake libtool make gawk \
        libreadline-dev texinfo libjson-c-dev pkg-config bison flex \
-       python-pip
+       python-pip libc-ares-dev python3-dev
 
 Install newer pytest (>3.0) from pip    
 
@@ -41,7 +41,6 @@ an example.)
 
     git clone https://github.com/freerangerouting/frr.git frr
     cd frr
-    git checkout stable/2.0
     ./bootstrap.sh
     ./configure \
         --enable-exampledir=/usr/share/doc/frr/examples/ \
index 9617afc733e37959cf44fbd45c8e3aef5a2ce3b3..0b9872bb098c82e5b2a0d5942ea59a025b189dec 100644 (file)
@@ -8,7 +8,8 @@ Add packages:
 
     sudo dnf install git autoconf automake libtool make gawk \
        readline-devel texinfo net-snmp-devel groff pkgconfig \
-       json-c-devel pam-devel perl-XML-LibXML pytest
+       json-c-devel pam-devel perl-XML-LibXML c-ares-devel \
+       python3-devel
 
 Get FRR, compile it and install it (from Git)
 ---------------------------------------------
@@ -32,7 +33,6 @@ them if you are not building on a x86_64 architecture
 
     git clone https://github.com/freerangerouting/frr.git frr
     cd frr
-    git checkout stable/2.0
     ./bootstrap.sh
     ./configure \
         --sysconfdir=/etc/frr \
index 696b7d5d2e85ac35bb02bd48b2f9aecc00ff7504..5f50bee0d914e82cd8c3b64db3744680695e191c 100644 (file)
@@ -16,7 +16,7 @@ Add packages:
 install and asked)  
 
     pkg install git autoconf automake libtool gmake gawk json-c pkgconf \
-        bison flex py27-pytest
+        bison flex py27-pytest c-ares python3
 
 Make sure there is no /usr/bin/flex preinstalled (and use the newly 
 installed in /usr/local/bin):
@@ -43,7 +43,6 @@ an example)
 
     git clone https://github.com/freerangerouting/frr.git frr
     cd frr
-    git checkout stable/2.0
     ./bootstrap.sh
     export MAKE=gmake
     export LDFLAGS="-L/usr/local/lib"
index d0b8a7bf8832c37d8dd86bdfc4e7dbd4dc0d171b..9b327af1fda0756b013180947f548264423c4830 100644 (file)
@@ -16,7 +16,7 @@ Add packages:
 install and asked)  
 
     pkg install git autoconf automake libtool gmake gawk json-c pkgconf \
-        bison flex py27-pytest
+        bison flex py27-pytest c-ares python3
 
 Make sure there is no /usr/bin/flex preinstalled (and use the newly 
 installed in /usr/local/bin):
@@ -43,7 +43,6 @@ an example)
 
     git clone https://github.com/freerangerouting/frr.git frr
     cd frr
-    git checkout stable/2.0
     ./bootstrap.sh
     export MAKE=gmake
     export LDFLAGS="-L/usr/local/lib"
index d470d0046afbbf4ef3e800c1e24fed2e3a418fb2..2fd4f1095c9caa976a281b9ffdefe049988e9267 100644 (file)
@@ -16,7 +16,8 @@ Add packages:
 install and asked)  
 
     pkg install -y git autoconf automake libtool gmake gawk \
-        pkgconf texinfo json-c bison flex py27-pytest
+        pkgconf texinfo json-c bison flex py27-pytest c-ares \
+        python3
 
 Make sure there is no /usr/bin/flex preinstalled (and use the newly
 installed in /usr/local/bin):
@@ -25,6 +26,13 @@ takes preference in path)
 
     rm -f /usr/bin/flex
 
+For building with clang (instead of gcc), upgrade clang from 3.4 default to 3.6 *This is needed to build FreeBSD packages as well - for packages clang is default* (Clang 3.4 as shipped with FreeBSD 9 crashes during compile)
+
+    pkg install clang36
+    pkg delete clang34
+    mv /usr/bin/clang /usr/bin/clang34
+    ln -s /usr/local/bin/clang36 /usr/bin/clang
+
 Get FRR, compile it and install it (from Git)
 ---------------------------------------------
 
@@ -43,7 +51,6 @@ an example)
 
     git clone https://github.com/freerangerouting/frr.git frr
     cd frr
-    git checkout stable/2.0
     ./bootstrap.sh
     export MAKE=gmake
     export LDFLAGS="-L/usr/local/lib"
index 03d04ce954e4bf3cf51492328cbef2084d98ea5b..3a2dea7c2076b24f8af2c952a35e7fb2c45ab5fc 100644 (file)
@@ -18,7 +18,7 @@ Configure Package location:
 Add packages:
 
     sudo pkg_add git autoconf automake libtool gmake gawk openssl \
-       pkg-config json-c p5-XML-LibXML python27 py27-test
+       pkg-config json-c p5-XML-LibXML python27 py27-test python35
 
 Install SSL Root Certificates (for git https access):
 
@@ -47,7 +47,6 @@ an example)
 
     git clone https://github.com/freerangerouting/frr.git frr
     cd frr
-    git checkout stable/2.0
     ./bootstrap.sh
     MAKE=gmake
     export LDFLAGS="-L/usr/pkg/lib -R/usr/pkg/lib"
index d9b4b47ea60e809ecdc2045482dce7abb2c59c3a..38a116f4f190d2fa77438478f2bcac035c828536 100644 (file)
@@ -12,7 +12,7 @@ Install required packages
 -------------------------
 
     sudo pkgin install git autoconf automake libtool gmake gawk openssl \
-       pkg-config json-c p5-XML-LibXML python27 py27-test
+       pkg-config json-c p5-XML-LibXML python27 py27-test python35
 
 Install SSL Root Certificates (for git https access):
 
@@ -41,7 +41,6 @@ an example)
 
     git clone https://github.com/freerangerouting/frr.git frr
     cd frr
-    git checkout stable/2.0
     ./bootstrap.sh
     MAKE=gmake
     export LDFLAGS="-L/usr/pkg/lib -R/usr/pkg/lib"
index f158c80a7544ed30eaff1f8a203d76d1fa592c31..a64b054417f9cd8eca9d59994d7da9b26beea5a4 100644 (file)
@@ -41,7 +41,7 @@ Add additional Solaris packages:
     /opt/csw/bin/pkgutil -y -i texinfo
     /opt/csw/bin/pkgutil -y -i perl
     /opt/csw/bin/pkgutil -y -i libjson_c_dev
-    /opt/csw/bin/pkgutil -y -i python27 py_pip
+    /opt/csw/bin/pkgutil -y -i python27 py_pip python27_dev
 
 Add libjson to Solaris equivalent of ld.so.conf
 
@@ -61,7 +61,7 @@ Select Python 2.7 as default (required for pytest)
 
     rm -f /usr/bin/python
     ln -s /opt/csw/bin/python2.7 /usr/bin/python
-        
+
 Fix PATH for all users and non-interactive sessions. Edit `/etc/default/login`
 and add the following default PATH:
 
@@ -89,11 +89,11 @@ an example)
 
     git clone https://github.com/freerangerouting/frr.git frr
     cd frr
-    git checkout stable/2.0
     ./bootstrap.sh
     export MAKE=gmake
     export LDFLAGS="-L/opt/csw/lib"
     export CPPFLAGS="-I/opt/csw/include"
+    export PKG_CONFIG_PATH=/opt/csw/lib/pkgconfig
     ./configure \
         --sysconfdir=/etc/frr \
         --enable-exampledir=/usr/share/doc/frr/examples/ \
index 8ec23854a64223fc7ebaedaa2e3dffe06e8bc9c5..14a703b1d303b29f9974fc061c7614b3951dbc21 100644 (file)
@@ -36,7 +36,6 @@ an example)
 
     git clone https://github.com/freerangerouting/frr.git frr
     cd frr
-    git checkout stable/2.0
     ./bootstrap.sh
     export LDFLAGS="-L/usr/local/lib"
     export CPPFLAGS="-I/usr/local/include"
index 0e8fe6d8f481d8a35d00ea1be2c727bf2768f9a6..03d66af62998cda7768626e047acf8e6894ed88a 100644 (file)
@@ -12,8 +12,8 @@ Install required packages
 Add packages:
 
     apt-get install git autoconf automake libtool make gawk libreadline-dev \
-       texinfo libpam0g-dev dejagnu libjson0 pkg-config libpam0g-dev \
-       libjson0-dev flex python-pip
+       texinfo libpam0g-dev dejagnu libjson0-dev pkg-config libpam0g-dev \
+       libjson0-dev flex python-pip libc-ares-dev python3-dev
 
 Install newer bison from 14.04 package source (Ubuntu 12.04 package source
 is too old)
@@ -74,7 +74,6 @@ an example.)
 
     git clone https://github.com/freerangerouting/frr.git frr
     cd frr
-    git checkout stable/2.0
     ./bootstrap.sh
     ./configure \
         --enable-exampledir=/usr/share/doc/frr/examples/ \
index ac0a45acdfcaa5a7c85c60529ecdff7942562804..5de2fd8bb956a3c0b1be4fc539d35b9b4a4e9a9b 100644 (file)
@@ -8,12 +8,12 @@ Building FRR on Ubuntu 14.04LTS from Git Source
 
 Install required packages
 -------------------------
-        
+
 Add packages:
 
     apt-get install git autoconf automake libtool make gawk libreadline-dev \
        texinfo dejagnu pkg-config libpam0g-dev libjson-c-dev bison flex \
-       python-pytest
+       python-pytest libc-ares-dev python3-dev
 
 Get FRR, compile it and install it (from Git)
 ---------------------------------------------
@@ -34,7 +34,6 @@ an example.)
 
     git clone https://github.com/freerangerouting/frr.git frr
     cd frr
-    git checkout stable/2.0
     ./bootstrap.sh
     ./configure \
         --enable-exampledir=/usr/share/doc/frr/examples/ \
index 17cc4949bdd906d0132c0f993c44167e64ed6474..996b8da898ed5e1512cb4bd4a2afd376fb75a195 100644 (file)
@@ -14,7 +14,7 @@ Add packages:
 
     apt-get install git autoconf automake libtool make gawk libreadline-dev \
        texinfo dejagnu pkg-config libpam0g-dev libjson-c-dev bison flex \
-       python-pytest
+       python-pytest libc-ares-dev python3-dev
 
 Get FRR, compile it and install it (from Git)
 ---------------------------------------------
@@ -35,7 +35,6 @@ an example.)
 
     git clone https://github.com/freerangerouting/frr.git frr
     cd frr
-    git checkout stable/2.0
     ./bootstrap.sh
     ./configure \
         --enable-exampledir=/usr/share/doc/frr/examples/ \
diff --git a/nhrpd/.gitignore b/nhrpd/.gitignore
new file mode 100644 (file)
index 0000000..3d4d56d
--- /dev/null
@@ -0,0 +1 @@
+nhrpd
index 7e1b451eab266c9ec822146ee2078f78585a8f93..77eb5c7568f628905fe8ac9af5f9719f1635b490 100644 (file)
@@ -53,7 +53,7 @@ libpim_a_SOURCES = \
        pim_ssmpingd.c pim_int.c pim_rp.c \
        pim_static.c pim_br.c pim_register.c pim_routemap.c \
        pim_msdp.c pim_msdp_socket.c pim_msdp_packet.c \
-       pim_jp_agg.c pim_nht.c
+       pim_jp_agg.c pim_nht.c pim_ssm.c
 
 noinst_HEADERS = \
        pim_memory.h \
@@ -66,7 +66,7 @@ noinst_HEADERS = \
        pim_igmp_join.h pim_ssmpingd.h pim_int.h pim_rp.h \
        pim_static.h pim_br.h pim_register.h \
        pim_msdp.h pim_msdp_socket.h pim_msdp_packet.h pim_nht.h \
-       pim_jp_agg.h
+       pim_jp_agg.h pim_ssm.h
 
 pimd_SOURCES = \
        pim_main.c $(libpim_a_SOURCES)
index 91d870fb1edcde32995bb1bc9f75dbc0695f2100..627971d3f9779e7fc8fb70687683010e96f2ce87 100644 (file)
@@ -54,6 +54,7 @@
 #include "pim_rp.h"
 #include "pim_zlookup.h"
 #include "pim_msdp.h"
+#include "pim_ssm.h"
 
 static struct cmd_node pim_global_node = {
   PIM_NODE,
@@ -3622,6 +3623,153 @@ DEFUN (no_ip_pim_rp_prefix_list,
   return pim_no_rp_cmd_worker (vty, argv[4]->arg, NULL, argv[6]->arg);
 }
 
+static int
+pim_ssm_cmd_worker (struct vty *vty, const char *plist)
+{
+  int result = pim_ssm_range_set (VRF_DEFAULT, plist);
+
+  if (result == PIM_SSM_ERR_NONE)
+    return CMD_SUCCESS;
+
+  switch (result)
+    {
+    case PIM_SSM_ERR_NO_VRF:
+      vty_out (vty, "%% VRF doesn't exist%s", VTY_NEWLINE);
+      break;
+    case PIM_SSM_ERR_DUP:
+      vty_out (vty, "%% duplicate config%s", VTY_NEWLINE);
+      break;
+    default:
+      vty_out (vty, "%% ssm range config failed%s", VTY_NEWLINE);
+    }
+
+  return CMD_WARNING;
+}
+
+DEFUN (ip_pim_ssm_prefix_list,
+       ip_pim_ssm_prefix_list_cmd,
+       "ip pim ssm prefix-list WORD",
+       IP_STR
+       "pim multicast routing\n"
+       "Source Specific Multicast\n"
+       "group range prefix-list filter\n"
+       "Name of a prefix-list\n")
+{
+  return pim_ssm_cmd_worker (vty, argv[0]->arg);
+}
+
+DEFUN (no_ip_pim_ssm_prefix_list,
+       no_ip_pim_ssm_prefix_list_cmd,
+       "no ip pim ssm prefix-list",
+       NO_STR
+       IP_STR
+       "pim multicast routing\n"
+       "Source Specific Multicast\n"
+       "group range prefix-list filter\n")
+{
+  return pim_ssm_cmd_worker (vty, NULL);
+}
+
+DEFUN (no_ip_pim_ssm_prefix_list_name,
+       no_ip_pim_ssm_prefix_list_name_cmd,
+       "no ip pim ssm prefix-list WORD",
+       NO_STR
+       IP_STR
+       "pim multicast routing\n"
+       "Source Specific Multicast\n"
+       "group range prefix-list filter\n"
+       "Name of a prefix-list\n")
+{
+  struct pim_ssm *ssm = pimg->ssm_info;
+
+  if (ssm->plist_name && !strcmp(ssm->plist_name, argv[0]->arg))
+    return pim_ssm_cmd_worker (vty, NULL);
+
+  vty_out (vty, "%% pim ssm prefix-list %s doesn't exist%s",
+           argv[0]->arg, VTY_NEWLINE);
+
+  return CMD_WARNING;
+}
+
+static void
+ip_pim_ssm_show_group_range(struct vty *vty, u_char uj)
+{
+  struct pim_ssm *ssm = pimg->ssm_info;
+  const char *range_str = ssm->plist_name?ssm->plist_name:PIM_SSM_STANDARD_RANGE;
+
+  if (uj)
+    {
+      json_object *json;
+      json = json_object_new_object();
+      json_object_string_add(json, "ssmGroups", range_str);
+      vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+      json_object_free(json);
+    }
+  else
+    vty_out(vty, "SSM group range : %s%s", range_str, VTY_NEWLINE);
+}
+
+DEFUN (show_ip_pim_ssm_range,
+       show_ip_pim_ssm_range_cmd,
+       "show ip pim group-type [json]",
+       SHOW_STR
+       IP_STR
+       PIM_STR
+       "PIM group type\n"
+       "JavaScript Object Notation\n")
+{
+  u_char uj = use_json(argc, argv);
+  ip_pim_ssm_show_group_range(vty, uj);
+
+  return CMD_SUCCESS;
+}
+
+static void
+ip_pim_ssm_show_group_type(struct vty *vty, u_char uj, const char *group)
+{
+  struct in_addr group_addr;
+  const char *type_str;
+  int result;
+
+  result = inet_pton(AF_INET, group, &group_addr);
+  if (result <= 0)
+    type_str = "invalid";
+  else
+    {
+      if (pim_is_group_224_4 (group_addr))
+        type_str = pim_is_grp_ssm (group_addr)?"SSM":"ASM";
+      else
+        type_str = "not-multicast";
+    }
+
+  if (uj)
+    {
+      json_object *json;
+      json = json_object_new_object();
+      json_object_string_add(json, "groupType", type_str);
+      vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+      json_object_free(json);
+    }
+  else
+    vty_out(vty, "Group type : %s%s", type_str, VTY_NEWLINE);
+}
+
+DEFUN (show_ip_pim_group_type,
+       show_ip_pim_group_type_cmd,
+       "show ip pim group-type A.B.C.D [json]",
+       SHOW_STR
+       IP_STR
+       PIM_STR
+       "multicast group type\n"
+       "group address\n"
+       "JavaScript Object Notation\n")
+{
+  u_char uj = use_json(argc, argv);
+  ip_pim_ssm_show_group_type(vty, uj, argv[0]->arg);
+
+  return CMD_SUCCESS;
+}
+
 DEFUN_HIDDEN (ip_multicast_routing,
               ip_multicast_routing_cmd,
               "ip multicast-routing",
@@ -4316,7 +4464,7 @@ DEFUN (interface_no_ip_pim_drprio,
 }
 
 static int
-pim_cmd_interface_add (struct interface *ifp, enum pim_interface_type itype)
+pim_cmd_interface_add (struct interface *ifp)
 {
   struct pim_interface *pim_ifp = ifp->info;
 
@@ -4330,14 +4478,12 @@ pim_cmd_interface_add (struct interface *ifp, enum pim_interface_type itype)
     PIM_IF_DO_PIM(pim_ifp->options);
   }
 
-  pim_ifp->itype = itype;
   pim_if_addr_add_all(ifp);
   pim_if_membership_refresh(ifp);
   return 1;
 }
 
-
-DEFUN (interface_ip_pim_ssm,
+DEFUN_HIDDEN (interface_ip_pim_ssm,
        interface_ip_pim_ssm_cmd,
        "ip pim ssm",
        IP_STR
@@ -4346,11 +4492,12 @@ DEFUN (interface_ip_pim_ssm,
 {
   VTY_DECLVAR_CONTEXT(interface, ifp);
 
-  if (!pim_cmd_interface_add(ifp, PIM_INTERFACE_SSM)) {
-    vty_out(vty, "Could not enable PIM SSM on interface%s", VTY_NEWLINE);
+  if (!pim_cmd_interface_add(ifp)) {
+    vty_out(vty, "Could not enable PIM SM on interface%s", VTY_NEWLINE);
     return CMD_WARNING;
   }
 
+  vty_out(vty, "WARN: Enabled PIM SM on interface; configure PIM SSM range if needed%s", VTY_NEWLINE);
   return CMD_SUCCESS;
 }
 
@@ -4362,7 +4509,7 @@ DEFUN (interface_ip_pim_sm,
        IFACE_PIM_SM_STR)
 {
   VTY_DECLVAR_CONTEXT(interface, ifp);
-  if (!pim_cmd_interface_add(ifp, PIM_INTERFACE_SM)) {
+  if (!pim_cmd_interface_add(ifp)) {
     vty_out(vty, "Could not enable PIM SM on interface%s", VTY_NEWLINE);
     return CMD_WARNING;
   }
@@ -4398,7 +4545,7 @@ pim_cmd_interface_delete (struct interface *ifp)
   return 1;
 }
 
-DEFUN (interface_no_ip_pim_ssm,
+DEFUN_HIDDEN (interface_no_ip_pim_ssm,
        interface_no_ip_pim_ssm_cmd,
        "no ip pim ssm",
        NO_STR
@@ -6053,6 +6200,9 @@ void pim_cmd_init()
   install_element (CONFIG_NODE, &no_ip_pim_rp_cmd);
   install_element (CONFIG_NODE, &ip_pim_rp_prefix_list_cmd);
   install_element (CONFIG_NODE, &no_ip_pim_rp_prefix_list_cmd);
+  install_element (CONFIG_NODE, &no_ip_pim_ssm_prefix_list_cmd);
+  install_element (CONFIG_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
+  install_element (CONFIG_NODE, &ip_pim_ssm_prefix_list_cmd);
   install_element (CONFIG_NODE, &ip_pim_register_suppress_cmd);
   install_element (CONFIG_NODE, &no_ip_pim_register_suppress_cmd);
   install_element (CONFIG_NODE, &ip_pim_joinprune_time_cmd);
@@ -6212,6 +6362,8 @@ void pim_cmd_init()
   install_element (VIEW_NODE, &show_ip_msdp_sa_detail_cmd);
   install_element (VIEW_NODE, &show_ip_msdp_sa_sg_cmd);
   install_element (VIEW_NODE, &show_ip_msdp_mesh_group_cmd);
+  install_element (VIEW_NODE, &show_ip_pim_ssm_range_cmd);
+  install_element (VIEW_NODE, &show_ip_pim_group_type_cmd);
   install_element (INTERFACE_NODE, &interface_pim_use_source_cmd);
   install_element (INTERFACE_NODE, &interface_no_pim_use_source_cmd);
 }
index f4d7518d7afe5328eb00bc17a4e1e87b13b70077..c42c6910676dea57148cf9720268e59f669fed31 100644 (file)
@@ -58,11 +58,6 @@ struct pim_iface_upstream_switch {
   struct list *us;
 };
 
-enum pim_interface_type {
-  PIM_INTERFACE_SSM,
-  PIM_INTERFACE_SM
-};
-
 enum pim_secondary_addr_flags {
   PIM_SEC_ADDRF_NONE = 0,
   PIM_SEC_ADDRF_STALE = (1 << 0)
@@ -74,7 +69,6 @@ struct pim_secondary_addr {
 };
 
 struct pim_interface {
-  enum pim_interface_type itype;
   uint32_t       options;                            /* bit vector */
   ifindex_t      mroute_vif_index;
   struct in_addr primary_address; /* remember addr to detect change */
index 5688d0e45d2e3f755a75dafb4ec81b3bcd3992f4..e6b4ba92a90810a2538178b31f068bf04546e6c0 100644 (file)
@@ -41,6 +41,7 @@
 #include "pim_macro.h"
 #include "pim_oil.h"
 #include "pim_upstream.h"
+#include "pim_ssm.h"
 
 int
 pim_ifchannel_compare (struct pim_ifchannel *ch1, struct pim_ifchannel *ch2)
@@ -967,6 +968,18 @@ pim_ifchannel_local_membership_add(struct interface *ifp,
   if (!PIM_IF_TEST_PIM(pim_ifp->options))
     return 0;
 
+  /* skip (*,G) ch creation if G is of type SSM */
+  if (sg->src.s_addr == INADDR_ANY)
+    {
+      if (pim_is_grp_ssm (sg->grp))
+        {
+          if (PIM_DEBUG_PIM_EVENTS)
+            zlog_debug("%s: local membership (S,G)=%s ignored as group is SSM",
+                __PRETTY_FUNCTION__, pim_str_sg_dump (sg));
+          return 1;
+        }
+    }
+
   ch = pim_ifchannel_add(ifp, sg, PIM_UPSTREAM_FLAG_MASK_SRC_IGMP);
   if (!ch) {
     return 0;
index 07f2812725a9fd2ddba04261cda4cfe11b17c04d..d814af6b2c1ba9b2750f5488f800a8790ad8b750 100644 (file)
@@ -46,7 +46,6 @@
 #include "pim_zebra.h"
 #include "pim_msdp.h"
 #include "pim_iface.h"
-#include "pim_rp.h"
 
 extern struct host host;
 
@@ -120,8 +119,8 @@ int main(int argc, char** argv, char** envp) {
   pim_vrf_init ();
   access_list_init();
   prefix_list_init ();
-  prefix_list_add_hook (pim_rp_prefix_list_update);
-  prefix_list_delete_hook (pim_rp_prefix_list_update);
+  prefix_list_add_hook (pim_prefix_list_update);
+  prefix_list_delete_hook (pim_prefix_list_update);
 
   pim_route_map_init ();
   pim_init();
index f46cf193bb16944ab59181e1214b2aa7cd184b83..2acca6f49be879483ee3cdc56db6fa8c4eaac0d0 100644 (file)
@@ -51,3 +51,4 @@ DEFINE_MTYPE(PIMD, PIM_JP_AGG_GROUP,      "PIM JP AGG Group")
 DEFINE_MTYPE(PIMD, PIM_JP_AGG_SOURCE,     "PIM JP AGG Source")
 DEFINE_MTYPE(PIMD, PIM_PIM_INSTANCE,      "PIM global state")
 DEFINE_MTYPE(PIMD, PIM_NEXTHOP_CACHE,     "PIM nexthop cache state")
+DEFINE_MTYPE(PIMD, PIM_SSM_INFO,          "PIM SSM configuration")
index bd9e12f2fc4de6b4984a27e4bd641487e3a10d25..02446de46a65f93d48c725d129490a15ba10cb86 100644 (file)
@@ -50,5 +50,6 @@ DECLARE_MTYPE(PIM_JP_AGG_GROUP)
 DECLARE_MTYPE(PIM_JP_AGG_SOURCE)
 DECLARE_MTYPE(PIM_PIM_INSTANCE)
 DECLARE_MTYPE(PIM_NEXTHOP_CACHE)
+DECLARE_MTYPE(PIM_SSM_INFO)
 
 #endif /* _QUAGGA_PIM_MEMORY_H */
index 04b6a4c697af147e70a8487738f4e6bcbc932da5..90e30ea3d65211ebc3e4d3b4ce570c2214942552 100644 (file)
@@ -39,6 +39,7 @@
 #include "pim_register.h"
 #include "pim_ifchannel.h"
 #include "pim_zlookup.h"
+#include "pim_ssm.h"
 
 /* GLOBAL VARS */
 static struct thread *qpim_mroute_socket_reader = NULL;
@@ -127,8 +128,7 @@ pim_mroute_msg_nocache (int fd, struct interface *ifp, const struct igmpmsg *msg
    */
   if ((pim_rpf_addr_is_inaddr_none (rpg)) ||
       (!pim_ifp) ||
-      (!(PIM_I_am_DR(pim_ifp))) ||
-      (pim_ifp->itype == PIM_INTERFACE_SSM))
+      (!(PIM_I_am_DR(pim_ifp))))
     {
       if (PIM_DEBUG_MROUTE_DETAIL)
        zlog_debug ("%s: Interface is not configured correctly to handle incoming packet: Could be !DR, !pim_ifp, !SM, !RP",
@@ -178,8 +178,7 @@ pim_mroute_msg_nocache (int fd, struct interface *ifp, const struct igmpmsg *msg
 
   up->channel_oil->cc.pktcnt++;
   PIM_UPSTREAM_FLAG_SET_FHR(up->flags);
-  pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM);
-  up->reg_state = PIM_REG_JOIN;
+  pim_register_join (up);
 
   return 0;
 }
@@ -214,8 +213,7 @@ pim_mroute_msg_wholepkt (int fd, struct interface *ifp, const char *buf)
 
   if ((pim_rpf_addr_is_inaddr_none (rpg)) ||
       (!pim_ifp) ||
-      (!(PIM_I_am_DR(pim_ifp))) ||
-      (pim_ifp->itype == PIM_INTERFACE_SSM)) {
+      (!(PIM_I_am_DR(pim_ifp)))) {
     if (PIM_DEBUG_MROUTE) {
       zlog_debug("%s: Failed Check send packet", __PRETTY_FUNCTION__);
     }
@@ -226,9 +224,18 @@ pim_mroute_msg_wholepkt (int fd, struct interface *ifp, const char *buf)
    * If we've received a register suppress
    */
   if (!up->t_rs_timer)
-    pim_register_send((uint8_t *)buf + sizeof(struct ip),
-                      ntohs (ip_hdr->ip_len) - sizeof (struct ip),
-                      pim_ifp->primary_address, rpg, 0, up);
+    {
+      if (pim_is_grp_ssm (sg.grp))
+        {
+          if (PIM_DEBUG_PIM_REG)
+            zlog_debug ("%s register forward skipped as group is SSM",
+                        pim_str_sg_dump (&sg));
+          return 0;
+        }
+      pim_register_send((uint8_t *)buf + sizeof(struct ip),
+                        ntohs (ip_hdr->ip_len) - sizeof (struct ip),
+                        pim_ifp->primary_address, rpg, 0, up);
+    }
   return 0;
 }
 
@@ -442,8 +449,7 @@ pim_mroute_msg_wrvifwhole (int fd, struct interface *ifp, const char *buf)
       pim_upstream_keep_alive_timer_start (up, qpim_keep_alive_time);
       up->channel_oil = oil;
       up->channel_oil->cc.pktcnt++;
-      pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM);
-      up->reg_state = PIM_REG_JOIN;
+      pim_register_join (up);
       pim_upstream_inherited_olist (up);
 
       // Send the packet to the RP
index cb9d7e3744d4439ccc283960b05b4d47182d5490..effc212722b46e1c46e1cd3f4b14d00e8368c971 100644 (file)
 #include "pim_zebra.h"
 #include "pim_join.h"
 #include "pim_util.h"
+#include "pim_ssm.h"
 
 struct thread *send_test_packet_timer = NULL;
 
+void
+pim_register_join (struct pim_upstream *up)
+{
+  if (pim_is_grp_ssm (up->sg.grp))
+    {
+      if (PIM_DEBUG_PIM_EVENTS)
+       zlog_debug ("%s register setup skipped as group is SSM", up->sg_str);
+        return;
+    }
+
+  pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM);
+  up->reg_state = PIM_REG_JOIN;
+}
+
 void
 pim_register_stop_send (struct interface *ifp, struct prefix_sg *sg,
                        struct in_addr src, struct in_addr originator)
index 42a908b225af702efff0b0afdbbfb3f31098b691..210a904ae9488af0133458b5de04076b90efb229 100644 (file)
@@ -40,5 +40,6 @@ int pim_register_recv (struct interface *ifp,
 
 void pim_register_send (const uint8_t *buf, int buf_size, struct in_addr src, struct pim_rpf *rpg, int null_register, struct pim_upstream *up);
 void pim_register_stop_send (struct interface *ifp, struct prefix_sg *sg, struct in_addr src, struct in_addr originator);
+void pim_register_join (struct pim_upstream *up);
 
 #endif
diff --git a/pimd/pim_ssm.c b/pimd/pim_ssm.c
new file mode 100644 (file)
index 0000000..41bf1e5
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * IP SSM ranges for FRR
+ * Copyright (C) 2017 Cumulus Networks, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+
+#include <lib/linklist.h>
+#include <lib/prefix.h>
+#include <lib/vty.h>
+#include <lib/vrf.h>
+#include <lib/plist.h>
+
+#include "pimd.h"
+#include "pim_ssm.h"
+#include "pim_zebra.h"
+
+static void
+pim_ssm_range_reevaluate (void)
+{
+  /* 1. Setup register state for (S,G) entries if G has changed from SSM to
+   *    ASM.
+   * 2. check existing (*,G) IGMP registrations to see if they are
+   * still ASM. if they are now SSM delete them.
+   * 3. Allow channel setup for IGMP (*,G) members if G is now ASM
+   * 4. I could tear down all (*,G), (S,G,rpt) states. But that is an
+   * unnecessary sladge hammer and may not be particularly useful as it is
+   * likely the SPT switchover has already happened for flows along such RPTs.
+   * As for the RPT states it seems that the best thing to do is let them age
+   * out gracefully. As long as the FHR and LHR do the right thing RPTs will
+   * disappear in time for SSM groups.
+   */
+  pim_upstream_register_reevaluate ();
+  igmp_source_forward_reevaluate_all ();
+}
+
+void
+pim_ssm_prefix_list_update (struct prefix_list *plist)
+{
+  struct pim_ssm *ssm = pimg->ssm_info;
+
+  if (!ssm->plist_name || strcmp (ssm->plist_name, prefix_list_name (plist)))
+    {
+      /* not ours */
+      return;
+    }
+
+  pim_ssm_range_reevaluate ();
+}
+
+static int
+pim_is_grp_standard_ssm (struct prefix *group)
+{
+  static int first = 1;
+  static struct prefix group_ssm;
+
+  if (first)
+    {
+      str2prefix (PIM_SSM_STANDARD_RANGE, &group_ssm);
+      first = 0;
+    }
+
+  return prefix_match (&group_ssm, group);
+}
+
+int
+pim_is_grp_ssm (struct in_addr group_addr)
+{
+  struct pim_ssm *ssm;
+  struct prefix group;
+  struct prefix_list *plist;
+
+  memset (&group, 0, sizeof (group));
+  group.family = AF_INET;
+  group.u.prefix4 = group_addr;
+  group.prefixlen = 32;
+
+  ssm = pimg->ssm_info;
+  if (!ssm->plist_name)
+    {
+      return pim_is_grp_standard_ssm (&group);
+    }
+
+  plist = prefix_list_lookup (AFI_IP, ssm->plist_name);
+  if (!plist)
+    return 0;
+
+  return (prefix_list_apply (plist, &group) == PREFIX_PERMIT);
+}
+
+int
+pim_ssm_range_set (vrf_id_t vrf_id, const char *plist_name)
+{
+  struct pim_ssm *ssm;
+  int change = 0;
+
+  if (vrf_id != VRF_DEFAULT)
+    return PIM_SSM_ERR_NO_VRF;
+
+  ssm = pimg->ssm_info;
+  if (plist_name)
+    {
+      if (ssm->plist_name)
+        {
+          if (!strcmp (ssm->plist_name, plist_name))
+            return PIM_SSM_ERR_DUP;
+          XFREE (MTYPE_PIM_FILTER_NAME, ssm->plist_name);
+        }
+      ssm->plist_name = XSTRDUP (MTYPE_PIM_FILTER_NAME, plist_name);
+      change = 1;
+    }
+  else
+    {
+      if (ssm->plist_name)
+        {
+          change = 1;
+          XFREE (MTYPE_PIM_FILTER_NAME, ssm->plist_name);
+        }
+    }
+
+  if (change)
+    pim_ssm_range_reevaluate ();
+
+  return PIM_SSM_ERR_NONE;
+}
+
+void *
+pim_ssm_init (vrf_id_t vrf_id)
+{
+  struct pim_ssm *ssm;
+
+  ssm = XCALLOC (MTYPE_PIM_SSM_INFO, sizeof (*ssm));
+  ssm->vrf_id = vrf_id;
+
+  return ssm;
+}
+
+void
+pim_ssm_terminate (struct pim_ssm *ssm)
+{
+  if (ssm && ssm->plist_name)
+    XFREE (MTYPE_PIM_FILTER_NAME, ssm->plist_name);
+}
diff --git a/pimd/pim_ssm.h b/pimd/pim_ssm.h
new file mode 100644 (file)
index 0000000..ca82d33
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * IP SSM ranges for FRR
+ * Copyright (C) 2017 Cumulus Networks, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+#ifndef PIM_SSM_H
+#define PIM_SSM_H
+
+#define PIM_SSM_STANDARD_RANGE "232.0.0.0/8"
+
+/* SSM error codes */
+enum pim_ssm_err
+{
+  PIM_SSM_ERR_NONE = 0,
+  PIM_SSM_ERR_NO_VRF = -1,
+  PIM_SSM_ERR_DUP = -2,
+};
+
+struct pim_ssm
+{
+  vrf_id_t vrf_id;
+  char *plist_name; /* prefix list of group ranges */
+};
+
+void pim_ssm_prefix_list_update (struct prefix_list *plist);
+int pim_is_grp_ssm (struct in_addr group_addr);
+int pim_ssm_range_set (vrf_id_t vrf_id, const char *plist_name);
+void *pim_ssm_init (vrf_id_t vrf_id);
+void pim_ssm_terminate (struct pim_ssm *ssm);
+#endif
index d95849fce079627ae41c7d55e33f041797fcdd94..172d0d21c985f97086f3165d39880e510f0499ea 100644 (file)
@@ -53,6 +53,7 @@
 #include "pim_msdp.h"
 #include "pim_jp_agg.h"
 #include "pim_nht.h"
+#include "pim_ssm.h"
 
 struct hash *pim_upstream_hash = NULL;
 struct list *pim_upstream_list = NULL;
@@ -476,6 +477,51 @@ pim_upstream_could_register (struct pim_upstream *up)
   return 0;
 }
 
+/* Source registration is supressed for SSM groups. When the SSM range changes
+ * we re-revaluate register setup for existing upstream entries */
+void
+pim_upstream_register_reevaluate (void)
+{
+  struct listnode *upnode;
+  struct pim_upstream *up;
+
+  for (ALL_LIST_ELEMENTS_RO (pim_upstream_list, upnode, up))
+    {
+      /* If FHR is set CouldRegister is True. Also check if the flow
+       * is actually active; if it is not kat setup will trigger source
+       * registration whenever the flow becomes active. */
+      if (!PIM_UPSTREAM_FLAG_TEST_FHR (up->flags) || !up->t_ka_timer)
+        continue;
+
+      if (pim_is_grp_ssm (up->sg.grp))
+        {
+          /* clear the register state  for SSM groups */
+          if (up->reg_state != PIM_REG_NOINFO)
+            {
+              if (PIM_DEBUG_PIM_EVENTS)
+                zlog_debug ("Clear register for %s as G is now SSM",
+                            up->sg_str);
+              /* remove regiface from the OIL if it is there*/
+              pim_channel_del_oif (up->channel_oil, pim_regiface,
+                                   PIM_OIF_FLAG_PROTO_PIM);
+              up->reg_state = PIM_REG_NOINFO;
+            }
+        }
+      else
+        {
+          /* register ASM sources with the RP */
+          if (up->reg_state == PIM_REG_NOINFO)
+            {
+              if (PIM_DEBUG_PIM_EVENTS)
+                zlog_debug ("Register %s as G is now ASM", up->sg_str);
+              pim_channel_add_oif (up->channel_oil, pim_regiface,
+                                   PIM_OIF_FLAG_PROTO_PIM);
+              up->reg_state = PIM_REG_JOIN;
+            }
+        }
+    }
+}
+
 void
 pim_upstream_switch(struct pim_upstream *up,
                    enum pim_upstream_state new_state)
@@ -507,9 +553,8 @@ pim_upstream_switch(struct pim_upstream *up,
             PIM_UPSTREAM_FLAG_SET_FHR(up->flags);
             if (!old_fhr && PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags))
               {
-                up->reg_state = PIM_REG_JOIN;
                 pim_upstream_keep_alive_timer_start (up, qpim_keep_alive_time);
-               pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM);
+                pim_register_join (up);
               }
          }
        else
@@ -1018,10 +1063,8 @@ static void pim_upstream_fhr_kat_start(struct pim_upstream *up)
       zlog_debug ("kat started on %s; set fhr reg state to joined", up->sg_str);
 
     PIM_UPSTREAM_FLAG_SET_FHR(up->flags);
-    if (up->reg_state == PIM_REG_NOINFO) {
-      pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM);
-      up->reg_state = PIM_REG_JOIN;
-    }
+    if (up->reg_state == PIM_REG_NOINFO)
+      pim_register_join (up);
   }
 }
 
index e293c0c146022b25f32de70d10ec43e4b1a9ac7e..6f7556f323e84746950a8312036ecf7e93b20c7f 100644 (file)
@@ -192,4 +192,5 @@ void pim_upstream_terminate (void);
 
 void join_timer_start (struct pim_upstream *up);
 int pim_upstream_compare (void *arg1, void *arg2);
+void pim_upstream_register_reevaluate (void);
 #endif /* PIM_UPSTREAM_H */
index 9788c58cd9b0d6434d9971439a26b1fab657c906..55855e5a6a1ac9c5cbc00b05f34c8d0ad3538698 100644 (file)
@@ -38,6 +38,7 @@
 #include "pim_static.h"
 #include "pim_rp.h"
 #include "pim_msdp.h"
+#include "pim_ssm.h"
 
 int
 pim_debug_config_write (struct vty *vty)
@@ -145,6 +146,7 @@ pim_debug_config_write (struct vty *vty)
 int pim_global_config_write(struct vty *vty)
 {
   int writes = 0;
+  struct pim_ssm *ssm = pimg->ssm_info;
 
   writes += pim_msdp_config_write (vty);
 
@@ -180,6 +182,12 @@ int pim_global_config_write(struct vty *vty)
               qpim_packet_process, VTY_NEWLINE);
       ++writes;
     }
+  if (ssm->plist_name)
+    {
+      vty_out (vty, "ip pim ssm prefix-list %s%s",
+               ssm->plist_name, VTY_NEWLINE);
+      ++writes;
+    }
 
   if (qpim_ssmpingd_list) {
     struct listnode *node;
@@ -212,12 +220,8 @@ int pim_interface_config_write(struct vty *vty)
     if (ifp->info) {
       struct pim_interface *pim_ifp = ifp->info;
 
-      /* IF ip pim ssm */
       if (PIM_IF_TEST_PIM(pim_ifp->options)) {
-       if (pim_ifp->itype == PIM_INTERFACE_SSM)
-         vty_out(vty, " ip pim ssm%s", VTY_NEWLINE);
-       else
-         vty_out(vty, " ip pim sm%s", VTY_NEWLINE);
+       vty_out(vty, " ip pim sm%s", VTY_NEWLINE);
        ++writes;
       }
 
index bbee95bddd7dab50c509dc60dc2c9feca91490b9..33efb7c96683eb165f0a4b25fe64cad173e4c47c 100644 (file)
@@ -46,6 +46,7 @@
 #include "pim_igmpv3.h"
 #include "pim_jp_agg.h"
 #include "pim_nht.h"
+#include "pim_ssm.h"
 
 #undef PIM_DEBUG_IFADDR_DUMP
 #define PIM_DEBUG_IFADDR_DUMP
@@ -740,6 +741,84 @@ static int fib_lookup_if_vif_index(struct in_addr addr)
   return vif_index;
 }
 
+static void
+igmp_source_forward_reevaluate_one(struct igmp_source *source)
+{
+  struct prefix_sg sg;
+  struct igmp_group *group = source->source_group;
+  struct pim_ifchannel *ch;
+
+  if ((source->source_addr.s_addr != INADDR_ANY) ||
+      !IGMP_SOURCE_TEST_FORWARDING (source->source_flags))
+    return;
+
+  memset (&sg, 0, sizeof (struct prefix_sg));
+  sg.src = source->source_addr;
+  sg.grp = group->group_addr;
+
+  ch = pim_ifchannel_find (group->group_igmp_sock->interface, &sg);
+  if (pim_is_grp_ssm (group->group_addr))
+    {
+      /* If SSM group withdraw local membership */
+      if (ch && (ch->local_ifmembership == PIM_IFMEMBERSHIP_INCLUDE))
+        {
+          if (PIM_DEBUG_PIM_EVENTS)
+            zlog_debug ("local membership del for %s as G is now SSM",
+                        pim_str_sg_dump (&sg));
+          pim_ifchannel_local_membership_del (group->group_igmp_sock->interface, &sg);
+        }
+    }
+  else
+    {
+      /* If ASM group add local membership */
+      if (!ch || (ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO))
+        {
+          if (PIM_DEBUG_PIM_EVENTS)
+            zlog_debug ("local membership add for %s as G is now ASM",
+                        pim_str_sg_dump (&sg));
+          pim_ifchannel_local_membership_add (group->group_igmp_sock->interface, &sg);
+        }
+    }
+}
+
+void
+igmp_source_forward_reevaluate_all(void)
+{
+  struct listnode *ifnode;
+  struct interface *ifp;
+
+  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp))
+    {
+      struct pim_interface *pim_ifp = ifp->info;
+      struct listnode  *sock_node;
+      struct igmp_sock *igmp;
+
+      if (!pim_ifp)
+        continue;
+
+      /* scan igmp sockets */
+      for (ALL_LIST_ELEMENTS_RO (pim_ifp->igmp_socket_list, sock_node, igmp))
+        {
+          struct listnode *grpnode;
+          struct igmp_group *grp;
+
+          /* scan igmp groups */
+          for (ALL_LIST_ELEMENTS_RO (igmp->igmp_group_list, grpnode, grp))
+            {
+              struct listnode    *srcnode;
+              struct igmp_source *src;
+
+              /* scan group sources */
+              for (ALL_LIST_ELEMENTS_RO (grp->group_source_list,
+                                        srcnode, src))
+                {
+                  igmp_source_forward_reevaluate_one (src);
+                } /* scan group sources */
+            } /* scan igmp groups */
+        } /* scan igmp sockets */
+    } /* scan interfaces */
+}
+
 void igmp_source_forward_start(struct igmp_source *source)
 {
   struct igmp_group *group;
index 5dc06a4a19d7916113a0efc63cf6ae5976fc05ed..2ed463efaad14c842997efedd4e2303b03dbe8a4 100644 (file)
@@ -38,6 +38,7 @@ void igmp_anysource_forward_stop(struct igmp_group *group);
 
 void igmp_source_forward_start(struct igmp_source *source);
 void igmp_source_forward_stop(struct igmp_source *source);
+void igmp_source_forward_reevaluate_all(void);
 
 void pim_forward_start(struct pim_ifchannel *ch);
 void pim_forward_stop(struct pim_ifchannel *ch);
index 9058e14b0af1d79f2446b72aa88e06083ec4489d..e76e202bd3ddf47015fc37c6872f76716c293859 100644 (file)
@@ -41,6 +41,7 @@
 #include "pim_ssmpingd.h"
 #include "pim_static.h"
 #include "pim_rp.h"
+#include "pim_ssm.h"
 #include "pim_zlookup.h"
 #include "pim_nht.h"
 
@@ -184,6 +185,13 @@ pim_rp_list_hash_clean (void *data)
     list_delete_all_node (pnc->upstream_list);
 }
 
+void
+pim_prefix_list_update (struct prefix_list *plist)
+{
+    pim_rp_prefix_list_update (plist);
+    pim_ssm_prefix_list_update (plist);
+}
+
 static void
 pim_instance_terminate (void)
 {
@@ -193,6 +201,7 @@ pim_instance_terminate (void)
       hash_clean (pimg->rpf_hash, (void *) pim_rp_list_hash_clean);
       hash_free (pimg->rpf_hash);
     }
+  pim_ssm_terminate (pimg->ssm_info);
 
   XFREE (MTYPE_PIM_PIM_INSTANCE, pimg);
 }
@@ -235,6 +244,11 @@ pim_instance_init (vrf_id_t vrf_id, afi_t afi)
   if (PIM_DEBUG_ZEBRA)
     zlog_debug ("%s: NHT rpf hash init ", __PRETTY_FUNCTION__);
 
+  pim->ssm_info = pim_ssm_init (vrf_id);
+  if (!pim->ssm_info) {
+    pim_instance_terminate ();
+    return NULL;
+  }
 
   return pim;
 }
index 8dc58990229f2fc99e34ce342179741c0e0a4213..7febc38fa7a9539dac084a7cdf7fd90c8dc052e6 100644 (file)
@@ -24,6 +24,9 @@
 #include <stdint.h>
 #include "zebra.h"
 #include "libfrr.h"
+#include "prefix.h"
+#include "vty.h"
+#include "plist.h"
 
 #include "pim_str.h"
 #include "pim_memory.h"
@@ -241,6 +244,8 @@ struct pim_instance
   vrf_id_t vrf_id;
   struct hash *rpf_hash;
 
+  void *ssm_info; /* per-vrf SSM configuration */
+  
   int send_v6_secondary;
 };
 
@@ -252,5 +257,6 @@ void pim_terminate(void);
 extern void pim_route_map_init (void);
 extern void pim_route_map_terminate(void);
 void pim_vrf_init (void);
+void pim_prefix_list_update (struct prefix_list *plist);
 
 #endif /* PIMD_H */