[Xorp-hackers] [RFC 1/3] static-mcast: Support multicast address distances.
greearb at candelatech.com
greearb at candelatech.com
Mon Jul 9 12:04:16 PDT 2012
From: Ben Greear <greearb at candelatech.com>
Add RIB-like behaviour for multicast addresses in
the MFEA logic. This will allow static multicast
routes to over-ride dynamic routes, for instance.
PIM currently always uses distance of 1, so if
static uses 0, it will win.
Signed-off-by: Ben Greear <greearb at candelatech.com>
---
xorp/fea/mfea_node.cc | 280 +++++++++++++++++++++++++++++++---
xorp/fea/mfea_node.hh | 74 ++++++++--
xorp/fea/xrl_fea_node.hh | 5 -
xorp/fea/xrl_mfea_node.cc | 107 ++++++++-----
xorp/fea/xrl_mfea_node.hh | 23 ++-
xorp/pim/xrl_pim_node.cc | 2 +
xorp/xrl/interfaces/mfea.xif | 27 +++-
xorp/xrl/interfaces/mfea_client.xif | 1 -
xorp/xrl/interfaces/pim.xif | 2 -
9 files changed, 423 insertions(+), 98 deletions(-)
diff --git a/xorp/fea/mfea_node.cc b/xorp/fea/mfea_node.cc
index ea65ede..a54de56 100644
--- a/xorp/fea/mfea_node.cc
+++ b/xorp/fea/mfea_node.cc
@@ -42,6 +42,29 @@
#include "mfea_vif.hh"
+MfeaRouteStorage::MfeaRouteStorage(uint32_t d, const string module_name, const IPvX& _source,
+ const IPvX& _group, const string& _iif_name, const string& _oif_names) :
+ distance(d), is_binary(false), module_instance_name(module_name), source(_source),
+ group(_group), iif_name(_iif_name), oif_names(_oif_names) { }
+
+MfeaRouteStorage::MfeaRouteStorage(uint32_t d, const string module_name, const IPvX& _source,
+ const IPvX& _group, uint32_t iif_vif_idx,
+ const Mifset& _oiflist, const Mifset& _oif_disable_wrongvif,
+ uint32_t max_vifs, const IPvX& _rp_addr) :
+ distance(d), is_binary(true), module_instance_name(module_name), source(_source),
+ group(_group), iif_vif_index(iif_vif_idx), oiflist(_oiflist),
+ oiflist_disable_wrongvif(_oif_disable_wrongvif), max_vifs_oiflist(max_vifs),
+ rp_addr(_rp_addr) { }
+
+MfeaRouteStorage::MfeaRouteStorage(const MfeaRouteStorage& o) :
+ distance(o.distance), is_binary(true), module_instance_name(o.module_instance_name),
+ source(o.source), group(o.group), iif_name(o.iif_name),
+ oif_names(o.oif_names), iif_vif_index(o.iif_vif_index),
+ oiflist(o.oiflist), oiflist_disable_wrongvif(o.oiflist_disable_wrongvif),
+ max_vifs_oiflist(o.max_vifs_oiflist), rp_addr(o.rp_addr) { }
+
+MfeaRouteStorage::MfeaRouteStorage() : distance(0), is_binary(false), max_vifs_oiflist(0) { }
+
/**
* MfeaNode::MfeaNode:
* @fea_node: The corresponding FeaNode.
@@ -1816,10 +1839,106 @@ MfeaNode::signal_dataflow_message_recv(const IPvX& source, const IPvX& group,
return (XORP_OK);
}
+int MfeaNode::add_mfc_str(const string& module_instance_name,
+ const IPvX& source,
+ const IPvX& group,
+ const string& iif_name,
+ const string& oif_names,
+ uint32_t distance,
+ string& error_msg, bool check_stored_routes) {
+ int rv;
+ uint32_t iif_vif_index;
+
+ XLOG_INFO("MFEA add_mfc_str, module: %s source: %s group: %s check-stored-routes: %i distance: %u",
+ module_instance_name.c_str(), source.str().c_str(),
+ group.str().c_str(), (int)(check_stored_routes), distance);
+
+ if (distance >= MAX_MFEA_DISTANCE) {
+ error_msg += c_format("distance is above maximimum: %u >= %u\n",
+ distance, MAX_MFEA_DISTANCE);
+ return XORP_ERROR;
+ }
+
+ if (check_stored_routes) {
+ MfeaRouteStorage mrs(distance, module_instance_name, source,
+ group, iif_name, oif_names);
+ routes[mrs.distance][mrs.getHash()] = mrs;
+
+ // If any lower distance routes are already in place, do nothing and
+ // return.
+ if (mrs.distance > 0) {
+ for (unsigned int i = mrs.distance - 1; i > 0; i--) {
+ map<string, MfeaRouteStorage>::const_iterator iter = routes[i].find(mrs.getHash());
+ if (iter != routes[i].end()) {
+ XLOG_INFO("Lower-distance mfea route exists, distance: %i source: %s group: %s",
+ i, source.str().c_str(), group.str().c_str());
+ return XORP_OK;
+ }
+ }
+ }
+
+ // If any higher distance routes are already in place, remove them from kernel.
+ for (unsigned int i = mrs.distance + 1; i<MAX_MFEA_DISTANCE; i++) {
+ map<string, MfeaRouteStorage>::const_iterator iter = routes[i].find(mrs.getHash());
+ if (iter != routes[i].end()) {
+ XLOG_INFO("Removing higher-distance mfea route, distance: %i source: %s group: %s",
+ i, source.str().c_str(), group.str().c_str());
+ delete_mfc(iter->second.module_instance_name, iter->second.source,
+ iter->second.group, error_msg, false);
+ break;
+ }
+ }
+ }
+
+ // Convert strings to mfc binary stuff and pass to
+ // add_mfc()
+ MfeaVif *mfea_vif = vif_find_by_name(iif_name);
+ if (!mfea_vif) {
+ error_msg = "Could not find iif-interface: " + iif_name;
+ return XORP_ERROR;
+ }
+ iif_vif_index = mfea_vif->vif_index();
+
+ Mifset oiflist;
+ Mifset oiflist_disable_wrongvif;
+ istringstream iss(oif_names);
+ string t;
+ while (!(iss.eof() || iss.fail())) {
+ iss >> t;
+ if (t.size() == 0)
+ break;
+ mfea_vif = vif_find_by_name(t);
+ if (!mfea_vif) {
+ error_msg = "Could not find oif-interface: " + t;
+ return XORP_ERROR;
+ }
+ uint32_t vi = mfea_vif->vif_index();
+ if (vi < MAX_VIFS) {
+ oiflist.set(vi);
+ }
+ else {
+ error_msg = c_format("Vif %s has invalid vif_index: %u",
+ mfea_vif->ifname().c_str(), vi);
+ return XORP_ERROR;
+ }
+ }
+
+ IPvX rp_addr;
+
+ rv = add_mfc(module_instance_name, source, group,
+ iif_vif_index, oiflist,
+ oiflist_disable_wrongvif,
+ MAX_VIFS, rp_addr, distance, error_msg, false);
+ if (rv != XORP_OK) {
+ error_msg = "call to add_mfc failed";
+ }
+ return rv;
+}
+
/**
* MfeaNode::add_mfc:
* @module_instance_name: The module instance name of the protocol that adds
- * the MFC.
+ * the MFC.
* @source: The source address.
* @group: The group address.
* @iif_vif_index: The vif index of the incoming interface.
@@ -1827,7 +1946,7 @@ MfeaNode::signal_dataflow_message_recv(const IPvX& source, const IPvX& group,
* @oiflist_disable_wrongvif: The bitset with the outgoing interfaces to
* disable the WRONGVIF signal.
* @max_vifs_oiflist: The number of vifs covered by @oiflist
- * or @oiflist_disable_wrongvif.
+ * or @oiflist_disable_wrongvif.
* @rp_addr: The RP address.
*
* Add Multicast Forwarding Cache (MFC) to the kernel.
@@ -1835,24 +1954,78 @@ MfeaNode::signal_dataflow_message_recv(const IPvX& source, const IPvX& group,
* Return value: %XORP_OK on success, otherwise %XORP_ERROR.
**/
int
-MfeaNode::add_mfc(const string& , // module_instance_name,
+MfeaNode::add_mfc(const string& module_instance_name,
const IPvX& source, const IPvX& group,
uint32_t iif_vif_index, const Mifset& oiflist,
const Mifset& oiflist_disable_wrongvif,
uint32_t max_vifs_oiflist,
- const IPvX& rp_addr)
+ const IPvX& rp_addr, uint32_t distance,
+ string& error_msg,
+ bool check_stored_routes)
{
uint8_t oifs_ttl[MAX_VIFS];
uint8_t oifs_flags[MAX_VIFS];
-
- if (max_vifs_oiflist > MAX_VIFS)
- return (XORP_ERROR);
+
+ XLOG_INFO("MFEA add_mfc, module: %s source: %s group: %s check-stored-routes: %i distance: %u",
+ module_instance_name.c_str(), source.str().c_str(),
+ group.str().c_str(), (int)(check_stored_routes), distance);
+
+ if (distance >= MAX_MFEA_DISTANCE) {
+ error_msg += c_format("distance is above maximimum: %u >= %u\n",
+ distance, MAX_MFEA_DISTANCE);
+ return XORP_ERROR;
+ }
+
+ if (max_vifs_oiflist > MAX_VIFS) {
+ error_msg += c_format("max-vifs-oiflist: %u > MAX_VIFS: %u\n",
+ max_vifs_oiflist, MAX_VIFS);
+ return XORP_ERROR;
+ }
// Check the iif
- if (iif_vif_index == Vif::VIF_INDEX_INVALID)
- return (XORP_ERROR);
- if (iif_vif_index >= max_vifs_oiflist)
- return (XORP_ERROR);
+ if (iif_vif_index == Vif::VIF_INDEX_INVALID) {
+ error_msg += "iif_vif_index is VIF_INDEX_INVALID\n";
+ return XORP_ERROR;
+ }
+
+ if (iif_vif_index >= max_vifs_oiflist) {
+ error_msg += c_format("iif_vif_index: %u >= max-vifs-oiflist: %u\n",
+ iif_vif_index, max_vifs_oiflist);
+ return XORP_ERROR;
+ }
+
+ if (check_stored_routes) {
+ MfeaRouteStorage mrs(distance, module_instance_name, source,
+ group, iif_vif_index, oiflist,
+ oiflist_disable_wrongvif, max_vifs_oiflist,
+ rp_addr);
+ routes[mrs.distance][mrs.getHash()] = mrs;
+
+ // If any lower distance routes are already in place, do nothing and
+ // return.
+ if (mrs.distance > 0) {
+ for (unsigned int i = mrs.distance - 1; i > 0; i--) {
+ map<string, MfeaRouteStorage>::const_iterator iter = routes[i].find(mrs.getHash());
+ if (iter != routes[i].end()) {
+ XLOG_INFO("Lower-distance mfea route exists, distance: %i source: %s group: %s",
+ i, source.str().c_str(), group.str().c_str());
+ return XORP_OK;
+ }
+ }
+ }
+
+ // If any higher distance routes are already in place, remove them from kernel.
+ for (unsigned int i = mrs.distance + 1; i<MAX_MFEA_DISTANCE; i++) {
+ map<string, MfeaRouteStorage>::const_iterator iter = routes[i].find(mrs.getHash());
+ if (iter != routes[i].end()) {
+ XLOG_INFO("Removing higher-distance mfea route, distance: %i source: %s group: %s",
+ i, source.str().c_str(), group.str().c_str());
+ delete_mfc(iter->second.module_instance_name, iter->second.source,
+ iter->second.group, error_msg, false);
+ break;
+ }
+ }
+ }
//
// Reset the initial values
@@ -1889,9 +2062,10 @@ MfeaNode::add_mfc(const string& , // module_instance_name,
case AF_INET6:
{
#ifndef HAVE_IPV6_MULTICAST_ROUTING
- XLOG_ERROR("add_mfc() failed: "
- "IPv6 multicast routing not supported");
- return (XORP_ERROR);
+ string em = "add_mfc() failed: IPv6 multicast routing not supported\n";
+ error_msg += em;
+ XLOG_ERROR(em);
+ return XORP_ERROR;
#else
#if defined(MRT6_MFC_FLAGS_DISABLE_WRONGVIF) && defined(ENABLE_ADVANCED_MULTICAST_API)
oifs_flags[i] |= MRT6_MFC_FLAGS_DISABLE_WRONGVIF;
@@ -1911,10 +2085,11 @@ MfeaNode::add_mfc(const string& , // module_instance_name,
if (_mfea_mrouter.add_mfc(source, group, iif_vif_index, oifs_ttl,
oifs_flags, rp_addr)
!= XORP_OK) {
- return (XORP_ERROR);
+ error_msg += "mfea_mrouter add_mfc failed.\n";
+ return XORP_ERROR;
}
- return (XORP_OK);
+ return XORP_OK;
}
/**
@@ -1930,19 +2105,74 @@ MfeaNode::add_mfc(const string& , // module_instance_name,
* Return value: %XORP_OK on success, otherwise %XORP_ERROR.
**/
int
-MfeaNode::delete_mfc(const string& , // module_instance_name,
- const IPvX& source, const IPvX& group)
+MfeaNode::delete_mfc(const string& module_instance_name,
+ const IPvX& source, const IPvX& group,
+ string& error_msg, bool check_stored_routes)
{
- if (_mfea_mrouter.delete_mfc(source, group) != XORP_OK) {
- return (XORP_ERROR);
+ bool do_rem_route = true;
+ int rv;
+ string hash = source.str() + ":" + group.str();
+
+ XLOG_INFO("delete-mfc, module: %s source: %s group: %s check-stored-routes: %i\n",
+ module_instance_name.c_str(), source.str().c_str(),
+ group.str().c_str(), (int)(check_stored_routes));
+
+ if (check_stored_routes) {
+ // find existing route by instance-name.
+ for (unsigned int i = 0; i<MAX_MFEA_DISTANCE; i++) {
+ map<string, MfeaRouteStorage>::iterator iter = routes[i].find(hash);
+ if (iter != routes[i].end()) {
+ // Found something to delete..see if it belongs to us?
+ if (iter->second.module_instance_name == module_instance_name) {
+ // Yep, that's us.
+ routes[i].erase(hash);
+ goto check_remove_route;
+ }
+ else {
+ // was some other protocol's route. Don't mess with this,
+ // and don't remove anything from the kernel.
+ do_rem_route = false;
+ }
+ }
+ }
}
+
+ check_remove_route:
+
+ if (! do_rem_route) {
+ return XORP_OK;
+ }
+
+ rv = _mfea_mrouter.delete_mfc(source, group);
- //
- // XXX: Remove all corresponding dataflow entries
- //
+ // Remove all corresponding dataflow entries
mfea_dft().delete_entry(source, group);
-
- return (XORP_OK);
+
+ if (check_stored_routes) {
+ // Now, see if we have any higher-distance routes to add.
+ for (unsigned int i = 0; i<MAX_MFEA_DISTANCE; i++) {
+ map<string, MfeaRouteStorage>::iterator iter = routes[i].find(hash);
+ if (iter != routes[i].end()) {
+ if (iter->second.isBinary()) {
+ rv = add_mfc(iter->second.module_instance_name,
+ iter->second.source, iter->second.group,
+ iter->second.iif_vif_index,
+ iter->second.oiflist, iter->second.oiflist_disable_wrongvif,
+ iter->second.max_vifs_oiflist, iter->second.rp_addr,
+ iter->second.distance, error_msg, false);
+ }
+ else {
+ rv = add_mfc_str(iter->second.module_instance_name,
+ iter->second.source, iter->second.group,
+ iter->second.iif_name, iter->second.oif_names,
+ iter->second.distance, error_msg, false);
+ }
+ break;
+ }
+ }
+ }
+
+ return rv;
}
/**
diff --git a/xorp/fea/mfea_node.hh b/xorp/fea/mfea_node.hh
index b698a7e..39f08d7 100644
--- a/xorp/fea/mfea_node.hh
+++ b/xorp/fea/mfea_node.hh
@@ -17,8 +17,6 @@
// XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
// http://xorp.net
-// $XORP: xorp/fea/mfea_node.hh,v 1.51 2008/10/02 21:56:49 bms Exp $
-
#ifndef __FEA_MFEA_NODE_HH__
#define __FEA_MFEA_NODE_HH__
@@ -48,6 +46,44 @@ class MfeaVif;
class SgCount;
class VifCount;
+
+class MfeaRouteStorage {
+public:
+ uint32_t distance; // lower is higer priority.
+ bool is_binary;
+
+ string module_instance_name;
+ IPvX source;
+ IPvX group;
+
+ // String based route
+ string iif_name;
+ string oif_names;
+
+ // Binary based route
+ uint32_t iif_vif_index;
+ Mifset oiflist;
+ Mifset oiflist_disable_wrongvif;
+ uint32_t max_vifs_oiflist;
+ IPvX rp_addr;
+
+ MfeaRouteStorage(uint32_t d, const string module_name, const IPvX& _source,
+ const IPvX& _group, const string& _iif_name, const string& _oif_names);
+
+ MfeaRouteStorage(uint32_t d, const string module_name, const IPvX& _source,
+ const IPvX& _group, uint32_t iif_vif_idx,
+ const Mifset& _oiflist, const Mifset& _oif_disable_wrongvif,
+ uint32_t max_vifs, const IPvX& _rp_addr);
+
+ MfeaRouteStorage(const MfeaRouteStorage& o);
+ MfeaRouteStorage();
+
+ bool isBinary() const { return is_binary; }
+
+ string getHash() { return source.str() + ":" + group.str(); }
+};
+
+
/**
* @short The MFEA node class.
*
@@ -580,12 +616,22 @@ public:
*
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
- int add_mfc(const string& module_instance_name,
- const IPvX& source, const IPvX& group,
- uint32_t iif_vif_index, const Mifset& oiflist,
- const Mifset& oiflist_disable_wrongvif,
- uint32_t max_vifs_oiflist,
- const IPvX& rp_addr);
+ int add_mfc(const string& module_instance_name,
+ const IPvX& source, const IPvX& group,
+ uint32_t iif_vif_index, const Mifset& oiflist,
+ const Mifset& oiflist_disable_wrongvif,
+ uint32_t max_vifs_oiflist,
+ const IPvX& rp_addr, uint32_t distance,
+ string& error_msg,
+ bool check_stored_routes);
+
+ int add_mfc_str(const string& module_instance_name,
+ const IPvX& source,
+ const IPvX& group,
+ const string& iif_name,
+ const string& oif_names,
+ uint32_t distance,
+ string& error_msg, bool check_stored_routes);
/**
* Delete Multicast Forwarding Cache (MFC) from the kernel.
@@ -601,8 +647,9 @@ public:
*
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
- int delete_mfc(const string& module_instance_name,
- const IPvX& source, const IPvX& group);
+ int delete_mfc(const string& module_instance_name,
+ const IPvX& source, const IPvX& group,
+ string& error_msg, bool check_stored_routes);
/**
* Add a dataflow monitor entry.
@@ -854,6 +901,13 @@ private:
IfTree _mfea_iftree;
IfConfigUpdateReplicator _mfea_iftree_update_replicator;
+ // Store desired routes. This is a cheap way of doing some of the
+ // RIB logic, but for mcast routes.
+ // Lower distance means higher priority.
+ // key is: source:group, ie: 192.168.1.1:226.0.0.1
+#define MAX_MFEA_DISTANCE 8
+ map<string, MfeaRouteStorage> routes[MAX_MFEA_DISTANCE];
+
//
// Debug and test-related state
//
diff --git a/xorp/fea/xrl_fea_node.hh b/xorp/fea/xrl_fea_node.hh
index 0096d30..31831f3 100644
--- a/xorp/fea/xrl_fea_node.hh
+++ b/xorp/fea/xrl_fea_node.hh
@@ -17,9 +17,6 @@
// XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
// http://xorp.net
-// $XORP: xorp/fea/xrl_fea_node.hh,v 1.15 2008/10/02 21:56:50 bms Exp $
-
-
#ifndef __FEA_XRL_FEA_NODE_HH__
#define __FEA_XRL_FEA_NODE_HH__
@@ -29,9 +26,7 @@
//
#include "libxorp/xorp.h"
-
#include "libxipc/xrl_std_router.hh"
-
#include "cli/xrl_cli_node.hh"
#include "fea_node.hh"
diff --git a/xorp/fea/xrl_mfea_node.cc b/xorp/fea/xrl_mfea_node.cc
index a3db058..2eb10c1 100644
--- a/xorp/fea/xrl_mfea_node.cc
+++ b/xorp/fea/xrl_mfea_node.cc
@@ -895,7 +895,8 @@ XrlMfeaNode::mfea_0_1_add_mfc6(
const vector<uint8_t>& oiflist,
const vector<uint8_t>& oiflist_disable_wrongvif,
const uint32_t& max_vifs_oiflist,
- const IPv6& rp_address)
+ const IPv6& rp_address,
+ const uint32_t& distance)
{
string error_msg;
Mifset mifset;
@@ -930,21 +931,17 @@ XrlMfeaNode::mfea_0_1_add_mfc6(
IPvX(source_address), IPvX(group_address),
iif_vif_index, mifset, mifset_disable_wrongvif,
max_vifs_oiflist,
- IPvX(rp_address))
+ IPvX(rp_address), distance, error_msg, true)
!= XORP_OK) {
- // TODO: must find-out and return the reason for failure
- error_msg = c_format("Cannot add MFC for "
- "source %s and group %s "
- "with iif_vif_index = %u",
- source_address.str().c_str(),
- group_address.str().c_str(),
- XORP_UINT_CAST(iif_vif_index));
+ error_msg += c_format("Cannot add MFC for "
+ "source %s and group %s "
+ "with iif_vif_index = %u",
+ source_address.str().c_str(),
+ group_address.str().c_str(),
+ XORP_UINT_CAST(iif_vif_index));
return XrlCmdError::COMMAND_FAILED(error_msg);
}
- //
- // Success
- //
return XrlCmdError::OKAY();
}
@@ -967,19 +964,16 @@ XrlMfeaNode::mfea_0_1_delete_mfc6(
}
if (MfeaNode::delete_mfc(xrl_sender_name,
- IPvX(source_address), IPvX(group_address))
+ IPvX(source_address), IPvX(group_address),
+ error_msg, true)
!= XORP_OK) {
- // TODO: must find-out and return the reason for failure
- error_msg = c_format("Cannot delete MFC for "
- "source %s and group %s",
- source_address.str().c_str(),
- group_address.str().c_str());
+ error_msg += c_format("Cannot delete MFC for "
+ "source %s and group %s",
+ source_address.str().c_str(),
+ group_address.str().c_str());
return XrlCmdError::COMMAND_FAILED(error_msg);
}
- //
- // Success
- //
return XrlCmdError::OKAY();
}
@@ -1190,7 +1184,8 @@ XrlMfeaNode::mfea_0_1_add_mfc4(
const vector<uint8_t>& oiflist,
const vector<uint8_t>& oiflist_disable_wrongvif,
const uint32_t& max_vifs_oiflist,
- const IPv4& rp_address)
+ const IPv4& rp_address,
+ const uint32_t& distance)
{
string error_msg;
Mifset mifset;
@@ -1225,21 +1220,53 @@ XrlMfeaNode::mfea_0_1_add_mfc4(
IPvX(source_address), IPvX(group_address),
iif_vif_index, mifset, mifset_disable_wrongvif,
max_vifs_oiflist,
- IPvX(rp_address))
+ IPvX(rp_address), distance, error_msg, true)
!= XORP_OK) {
- // TODO: must find-out and return the reason for failure
- error_msg = c_format("Cannot add MFC for "
- "source %s and group %s "
- "with iif_vif_index = %u",
- source_address.str().c_str(),
- group_address.str().c_str(),
- XORP_UINT_CAST(iif_vif_index));
+ error_msg += c_format("Cannot add MFC for "
+ "source %s and group %s "
+ "with iif_vif_index = %u",
+ source_address.str().c_str(),
+ group_address.str().c_str(),
+ XORP_UINT_CAST(iif_vif_index));
return XrlCmdError::COMMAND_FAILED(error_msg);
}
+ return XrlCmdError::OKAY();
+}
+
+XrlCmdError
+XrlMfeaNode::mfea_0_1_add_mfc4_str(
+ // Input values,
+ const string& xrl_sender_name,
+ const IPv4& source_address,
+ const IPv4& group_address,
+ const string& iif_ifname,
+ const string& oif_ifnames,
+ const uint32_t& distance)
+{
+ string error_msg;
+
+ XLOG_INFO("received mfea add-mfc command, sender-name: %s input: %s mcast-addr: %s ifname: %s output_ifs: %s\n",
+ xrl_sender_name.c_str(),
+ source_address.str().c_str(),
+ group_address.str().c_str(),
+ iif_ifname.c_str(),
+ oif_ifnames.c_str());
//
- // Success
+ // Verify the address family
//
+ if (! MfeaNode::is_ipv4()) {
+ error_msg = c_format("Received protocol message with "
+ "invalid address family: IPv4");
+ return XrlCmdError::COMMAND_FAILED(error_msg);
+ }
+
+ if (MfeaNode::add_mfc_str(xrl_sender_name,
+ IPvX(source_address), IPvX(group_address),
+ iif_ifname, oif_ifnames, distance, error_msg, true) != XORP_OK) {
+ return XrlCmdError::COMMAND_FAILED(error_msg);
+ }
+
return XrlCmdError::OKAY();
}
@@ -1262,19 +1289,16 @@ XrlMfeaNode::mfea_0_1_delete_mfc4(
}
if (MfeaNode::delete_mfc(xrl_sender_name,
- IPvX(source_address), IPvX(group_address))
+ IPvX(source_address), IPvX(group_address),
+ error_msg, true)
!= XORP_OK) {
- // TODO: must find-out and return the reason for failure
- error_msg = c_format("Cannot delete MFC for "
- "source %s and group %s",
- source_address.str().c_str(),
- group_address.str().c_str());
+ error_msg += c_format("Cannot delete MFC for "
+ "source %s and group %s",
+ source_address.str().c_str(),
+ group_address.str().c_str());
return XrlCmdError::COMMAND_FAILED(error_msg);
}
- //
- // Success
- //
return XrlCmdError::OKAY();
}
@@ -1435,8 +1459,9 @@ XrlMfeaNode::mfea_0_1_start_vif(
{
string error_msg;
- if (MfeaNode::start_vif(vif_name, error_msg) != XORP_OK)
+ if (MfeaNode::start_vif(vif_name, error_msg) != XORP_OK) {
return XrlCmdError::COMMAND_FAILED(error_msg);
+ }
return XrlCmdError::OKAY();
}
diff --git a/xorp/fea/xrl_mfea_node.hh b/xorp/fea/xrl_mfea_node.hh
index 11efb40..ed9367d 100644
--- a/xorp/fea/xrl_mfea_node.hh
+++ b/xorp/fea/xrl_mfea_node.hh
@@ -269,7 +269,8 @@ protected:
const vector<uint8_t>& oiflist,
const vector<uint8_t>& oiflist_disable_wrongvif,
const uint32_t& max_vifs_oiflist,
- const IPv6& rp_address);
+ const IPv6& rp_address,
+ const uint32_t& distance);
XrlCmdError mfea_0_1_delete_mfc6(
// Input values,
@@ -359,13 +360,23 @@ protected:
const IPv4& source_address,
const IPv4& group_address,
const uint32_t& iif_vif_index,
- const vector<uint8_t>& oiflist,
- const vector<uint8_t>& oiflist_disable_wrongvif,
- const uint32_t& max_vifs_oiflist,
- const IPv4& rp_address);
+ const vector<uint8_t>& oiflist,
+ const vector<uint8_t>& oiflist_disable_wrongvif,
+ const uint32_t& max_vifs_oiflist,
+ const IPv4& rp_address,
+ const uint32_t& distance);
+
+ XrlCmdError mfea_0_1_add_mfc4_str(
+ // Input values,
+ const string& xrl_sender_name,
+ const IPv4& source_address,
+ const IPv4& group_address,
+ const string& iif_ifname,
+ const string& oif_ifnames,
+ const uint32_t& distance);
XrlCmdError mfea_0_1_delete_mfc4(
- // Input values,
+ // Input values,
const string& xrl_sender_name,
const IPv4& source_address,
const IPv4& group_address);
diff --git a/xorp/pim/xrl_pim_node.cc b/xorp/pim/xrl_pim_node.cc
index d5db99a..07a32eb 100644
--- a/xorp/pim/xrl_pim_node.cc
+++ b/xorp/pim/xrl_pim_node.cc
@@ -1656,6 +1656,7 @@ XrlPimNode::send_add_delete_mfc()
oiflist_disable_wrongvif_vector,
max_vifs_oiflist,
rp_addr.get_ipv4(),
+ 1, /* default distance is 1 for PIM */
callback(this, &XrlPimNode::mfea_client_send_add_delete_mfc_cb));
if (success)
return;
@@ -1673,6 +1674,7 @@ XrlPimNode::send_add_delete_mfc()
oiflist_disable_wrongvif_vector,
max_vifs_oiflist,
rp_addr.get_ipv6(),
+ 1, /* default distance is 1 for PIM */
callback(this, &XrlPimNode::mfea_client_send_add_delete_mfc_cb));
if (success)
return;
diff --git a/xorp/xrl/interfaces/mfea.xif b/xorp/xrl/interfaces/mfea.xif
index 00fd6b1..3f778c5 100644
--- a/xorp/xrl/interfaces/mfea.xif
+++ b/xorp/xrl/interfaces/mfea.xif
@@ -1,4 +1,3 @@
-/* $XORP: xorp/xrl/interfaces/mfea.xif,v 1.9 2007/05/19 01:52:48 pavlin Exp $ */
#include <xorp_config.h>
@@ -41,9 +40,9 @@ interface mfea/0.1 {
*
* @param xrl_sender_name the XRL name of the originator of this XRL.
* @param if_name the name of the interface to unregister for the
- * particular protocol.
+ * particular protocol.
* @param vif_name the name of the vif to unregister for the
- * particular protocol.
+ * particular protocol.
*/
unregister_protocol4 ? xrl_sender_name:txt \
& if_name:txt & vif_name:txt;
@@ -55,12 +54,12 @@ interface mfea/0.1 {
* @param source_address the source address of the MFC to add/delete.
* @param group_address the group address of the MFC to add/delete.
* @param iif_vif_index the index of the vif that is the incoming
- * interface.
+ * interface.
* @param oiflist the bit-vector with the set of outgoing interfaces.
* @param oiflist_disable_wrongvif the bit-vector with the set of
- * outgoing interfaces to disable WRONGVIF kernel signal.
+ * outgoing interfaces to disable WRONGVIF kernel signal.
* @param max_vifs_oiflist the number of vifs covered
- * by oiflist or oiflist_disable_wrongvif .
+ * by oiflist or oiflist_disable_wrongvif .
* @param rp_address the RP address of the MFC to add.
*/
add_mfc4 ? xrl_sender_name:txt \
@@ -69,9 +68,20 @@ interface mfea/0.1 {
& oiflist:binary \
& oiflist_disable_wrongvif:binary \
& max_vifs_oiflist:u32 \
- & rp_address:ipv4;
+ & rp_address:ipv4 \
+ & distance:u32;
delete_mfc4 ? xrl_sender_name:txt \
& source_address:ipv4 & group_address:ipv4;
+
+ /**
+ * Use strings instead of indexes. Let mfea do the mapping.
+ */
+ add_mfc4_str ? xrl_sender_name:txt \
+ & source_address:ipv4 \
+ & group_address:ipv4 \
+ & iif_name:txt \
+ & oif_names:txt \
+ & distance:u32;
/**
* Add/delete a dataflow monitor with the MFEA.
@@ -193,7 +203,8 @@ interface mfea/0.1 {
& oiflist:binary \
& oiflist_disable_wrongvif:binary \
& max_vifs_oiflist:u32 \
- & rp_address:ipv6;
+ & rp_address:ipv6 \
+ & distance:u32;
delete_mfc6 ? xrl_sender_name:txt \
& source_address:ipv6 & group_address:ipv6;
add_dataflow_monitor6 ? xrl_sender_name:txt \
diff --git a/xorp/xrl/interfaces/mfea_client.xif b/xorp/xrl/interfaces/mfea_client.xif
index 8cecda3..4100190 100644
--- a/xorp/xrl/interfaces/mfea_client.xif
+++ b/xorp/xrl/interfaces/mfea_client.xif
@@ -1,4 +1,3 @@
-/* $XORP: xorp/xrl/interfaces/mfea_client.xif,v 1.11 2007/05/19 01:52:48 pavlin Exp $ */
#include <xorp_config.h>
diff --git a/xorp/xrl/interfaces/pim.xif b/xorp/xrl/interfaces/pim.xif
index e38806d..617b3e2 100644
--- a/xorp/xrl/interfaces/pim.xif
+++ b/xorp/xrl/interfaces/pim.xif
@@ -1,5 +1,3 @@
-/* $XORP: xorp/xrl/interfaces/pim.xif,v 1.24 2007/07/12 21:35:29 pavlin Exp $ */
-
/*
* Protocol Independent Multicast XRL interface.
*/
--
1.7.7.6
More information about the Xorp-hackers
mailing list