Skip to content

Commit

Permalink
Author: Akhilesh Samineni <47657796+AkhileshSamineni@users.noreply.gi…
Browse files Browse the repository at this point in the history
…thub.com>

Date:   Thu Aug 5 23:49:44 2021 +0530
    Code changes to support IPv6 Link local enhancements (sonic-net#1463)
  • Loading branch information
liuyuefengcn committed Jan 15, 2024
1 parent b0fb392 commit 544773a
Show file tree
Hide file tree
Showing 8 changed files with 314 additions and 15 deletions.
20 changes: 16 additions & 4 deletions cfgmgr/intfmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ bool IntfMgr::doIntfGeneralTask(const vector<string>& keys,
string nat_zone = "";
string proxy_arp = "";
string grat_arp = "";
string ipv6_link_local_mode = "";

for (auto idx : data)
{
Expand Down Expand Up @@ -477,6 +478,10 @@ bool IntfMgr::doIntfGeneralTask(const vector<string>& keys,
{
nat_zone = value;
}
else if (field == "ipv6_use_link_local_only")
{
ipv6_link_local_mode = value;
}
}

if (op == SET_COMMAND)
Expand Down Expand Up @@ -516,6 +521,13 @@ bool IntfMgr::doIntfGeneralTask(const vector<string>& keys,
{
FieldValueTuple fvTuple("nat_zone", nat_zone);
data.push_back(fvTuple);
}

/* Set ipv6 mode */
if (!ipv6_link_local_mode.empty())
{
FieldValueTuple fvTuple("ipv6_use_link_local_only", ipv6_link_local_mode);
data.push_back(fvTuple);
}
}

Expand Down Expand Up @@ -686,8 +698,8 @@ bool IntfMgr::doIntfAddrTask(const vector<string>& keys,
std::vector<FieldValueTuple> fvVector;
FieldValueTuple f("family", ip_prefix.isV4() ? IPV4_NAME : IPV6_NAME);

// Don't send link local config to AppDB and Orchagent
if (ip_prefix.getIp().getAddrScope() != IpAddress::AddrScope::LINK_SCOPE)
// Don't send ipv4 link local config to AppDB and Orchagent
if ((ip_prefix.isV4() == false) || (ip_prefix.getIp().getAddrScope() != IpAddress::AddrScope::LINK_SCOPE))
{
FieldValueTuple s("scope", "global");
fvVector.push_back(s);
Expand All @@ -700,8 +712,8 @@ bool IntfMgr::doIntfAddrTask(const vector<string>& keys,
{
setIntfIp(alias, "del", ip_prefix);

// Don't send link local config to AppDB and Orchagent
if (ip_prefix.getIp().getAddrScope() != IpAddress::AddrScope::LINK_SCOPE)
// Don't send ipv4 link local config to AppDB and Orchagent
if ((ip_prefix.isV4() == false) || (ip_prefix.getIp().getAddrScope() != IpAddress::AddrScope::LINK_SCOPE))
{
m_appIntfTableProducer.del(appKey);
m_stateIntfTable.del(keys[0] + state_db_key_delimiter + keys[1]);
Expand Down
26 changes: 22 additions & 4 deletions neighsyncd/neighsync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@

#include "neighsync.h"
#include "warm_restart.h"
#include <algorithm>

using namespace std;
using namespace swss;

NeighSync::NeighSync(RedisPipeline *pipelineAppDB, DBConnector *stateDb) :
NeighSync::NeighSync(RedisPipeline *pipelineAppDB, DBConnector *stateDb, DBConnector *cfgDb) :
m_neighTable(pipelineAppDB, APP_NEIGH_TABLE_NAME),
m_stateNeighRestoreTable(stateDb, STATE_NEIGH_RESTORE_TABLE_NAME)
m_stateNeighRestoreTable(stateDb, STATE_NEIGH_RESTORE_TABLE_NAME),
m_cfgInterfaceTable(cfgDb, CFG_INTF_TABLE_NAME),
m_cfgLagInterfaceTable(cfgDb, CFG_LAG_INTF_TABLE_NAME),
m_cfgVlanInterfaceTable(cfgDb, CFG_VLAN_INTF_TABLE_NAME)
{
m_AppRestartAssist = new AppRestartAssist(pipelineAppDB, "neighsyncd", "swss", DEFAULT_NEIGHSYNC_WARMSTART_TIMER);
if (m_AppRestartAssist)
Expand Down Expand Up @@ -57,6 +61,7 @@ void NeighSync::onMsg(int nlmsg_type, struct nl_object *obj)
struct rtnl_neigh *neigh = (struct rtnl_neigh *)obj;
string key;
string family;
string intfName;

if ((nlmsg_type != RTM_NEWNEIGH) && (nlmsg_type != RTM_GETNEIGH) &&
(nlmsg_type != RTM_DELNEIGH))
Expand All @@ -70,12 +75,18 @@ void NeighSync::onMsg(int nlmsg_type, struct nl_object *obj)
return;

key+= LinkCache::getInstance().ifindexToName(rtnl_neigh_get_ifindex(neigh));
intfName = key;
key+= ":";

nl_addr2str(rtnl_neigh_get_dst(neigh), ipStr, MAX_ADDR_SIZE);
/* Ignore IPv6 link-local addresses as neighbors */
/* Ignore IPv6 link-local addresses as neighbors, if ipv6 link local mode is disabled */
if (family == IPV6_NAME && IN6_IS_ADDR_LINKLOCAL(nl_addr_get_binary_addr(rtnl_neigh_get_dst(neigh))))
return;
{
if (isLinkLocalEnabled(intfName) == false)
{
return;
}
}
/* Ignore IPv6 multicast link-local addresses as neighbors */
if (family == IPV6_NAME && IN6_IS_ADDR_MC_LINKLOCAL(nl_addr_get_binary_addr(rtnl_neigh_get_dst(neigh))))
return;
Expand Down Expand Up @@ -124,3 +135,10 @@ void NeighSync::onMsg(int nlmsg_type, struct nl_object *obj)
m_neighTable.set(key, fvVector);
}
}

/* To check the ipv6 link local is enabled on a given port */
bool NeighSync::isLinkLocalEnabled(const string &port)
{
SWSS_LOG_INFO("IPv6 Link local is enabled on %s", port.c_str());
return true;
}
5 changes: 4 additions & 1 deletion neighsyncd/neighsync.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class NeighSync : public NetMsg
public:
enum { MAX_ADDR_SIZE = 64 };

NeighSync(RedisPipeline *pipelineAppDB, DBConnector *stateDb);
NeighSync(RedisPipeline *pipelineAppDB, DBConnector *stateDb, DBConnector *cfgDb);
~NeighSync();

virtual void onMsg(int nlmsg_type, struct nl_object *obj);
Expand All @@ -39,6 +39,9 @@ class NeighSync : public NetMsg
Table m_stateNeighRestoreTable;
ProducerStateTable m_neighTable;
AppRestartAssist *m_AppRestartAssist;
Table m_cfgVlanInterfaceTable, m_cfgLagInterfaceTable, m_cfgInterfaceTable;

bool isLinkLocalEnabled(const std::string &port);
};

}
Expand Down
3 changes: 2 additions & 1 deletion neighsyncd/neighsyncd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ int main(int argc, char **argv)
DBConnector appDb("APPL_DB", 0);
RedisPipeline pipelineAppDB(&appDb);
DBConnector stateDb("STATE_DB", 0);
DBConnector cfgDb("CONFIG_DB", 0);

NeighSync sync(&pipelineAppDB, &stateDb);
NeighSync sync(&pipelineAppDB, &stateDb, &cfgDb);

NetDispatcher::getInstance().registerMessageHandler(RTM_NEWNEIGH, &sync);
NetDispatcher::getInstance().registerMessageHandler(RTM_DELNEIGH, &sync);
Expand Down
13 changes: 13 additions & 0 deletions orchagent/neighorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,19 @@ void NeighOrch::doTask(Consumer &consumer)

IpAddress ip_address(key.substr(found+1));

/* Verify Ipv4 LinkLocal and skip neighbor entry added for RFC5549 */
if ((ip_address.getAddrScope() == IpAddress::LINK_SCOPE) && (ip_address.isV4()))
{
/* Check if this prefix is not a configured ip, if so allow */
IpPrefix ipll_prefix(ip_address.getV4Addr(), 16);
if (!m_intfsOrch->isPrefixSubnet (ipll_prefix, alias))
{
SWSS_LOG_NOTICE("Skip IPv4LL neighbor %s, Intf:%s op: %s ", ip_address.to_string().c_str(), alias.c_str(), op.c_str());
it = consumer.m_toSync.erase(it);
continue;
}
}

NeighborEntry neighbor_entry = { ip_address, alias };

if (op == SET_COMMAND)
Expand Down
25 changes: 23 additions & 2 deletions orchagent/routeorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,15 @@ RouteOrch::RouteOrch(DBConnector *db, string tableName, SwitchOrch *switchOrch,
IpPrefix linklocal_prefix = getLinkLocalEui64Addr();

addLinkLocalRouteToMe(gVirtualRouterId, linklocal_prefix);
SWSS_LOG_NOTICE("Created link local ipv6 route %s to cpu", linklocal_prefix.to_string().c_str());

/* Add fe80::/10 subnet route to forward all link-local packets
* destined to us, to CPU */
IpPrefix default_link_local_prefix("fe80::/10");

addLinkLocalRouteToMe(gVirtualRouterId, default_link_local_prefix);
SWSS_LOG_NOTICE("Created link local ipv6 route %s to cpu", default_link_local_prefix.to_string().c_str());

/* TODO: Add the link-local fe80::/10 route to cpu in every VRF created from
* vrforch::addOperation. */
}

std::string RouteOrch::getLinkLocalEui64Addr(void)
Expand Down Expand Up @@ -205,6 +205,27 @@ void RouteOrch::addLinkLocalRouteToMe(sai_object_id_t vrf_id, IpPrefix linklocal
SWSS_LOG_NOTICE("Created link local ipv6 route %s to cpu", linklocal_prefix.to_string().c_str());
}

void RouteOrch::delLinkLocalRouteToMe(sai_object_id_t vrf_id, IpPrefix linklocal_prefix)
{
sai_route_entry_t unicast_route_entry;
unicast_route_entry.switch_id = gSwitchId;
unicast_route_entry.vr_id = vrf_id;
copy(unicast_route_entry.destination, linklocal_prefix);
subnet(unicast_route_entry.destination, unicast_route_entry.destination);

sai_status_t status = sai_route_api->remove_route_entry(&unicast_route_entry);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to delete link local ipv6 route %s to cpu, rv:%d",
linklocal_prefix.getIp().to_string().c_str(), status);
return;
}

gCrmOrch->decCrmResUsedCounter(CrmResourceType::CRM_IPV6_ROUTE);

SWSS_LOG_NOTICE("Deleted link local ipv6 route %s to cpu", linklocal_prefix.to_string().c_str());
}

bool RouteOrch::hasNextHopGroup(const NextHopGroupKey& nexthops) const
{
return m_syncdNextHopGroups.find(nexthops) != m_syncdNextHopGroups.end();
Expand Down
7 changes: 4 additions & 3 deletions orchagent/routeorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ class RouteOrch : public Orch, public Subject
bool createFineGrainedNextHopGroup(sai_object_id_t &next_hop_group_id, vector<sai_attribute_t> &nhg_attrs);
bool removeFineGrainedNextHopGroup(sai_object_id_t &next_hop_group_id);

void addLinkLocalRouteToMe(sai_object_id_t vrf_id, IpPrefix linklocal_prefix);
void delLinkLocalRouteToMe(sai_object_id_t vrf_id, IpPrefix linklocal_prefix);
std::string getLinkLocalEui64Addr(void);

private:
SwitchOrch *m_switchOrch;
NeighOrch *m_neighOrch;
Expand Down Expand Up @@ -148,9 +152,6 @@ class RouteOrch : public Orch, public Subject
bool addRoutePost(const RouteBulkContext& ctx, const NextHopGroupKey &nextHops);
bool removeRoutePost(const RouteBulkContext& ctx);

std::string getLinkLocalEui64Addr(void);
void addLinkLocalRouteToMe(sai_object_id_t vrf_id, IpPrefix linklocal_prefix);

void doTask(Consumer& consumer);
};

Expand Down
Loading

0 comments on commit 544773a

Please sign in to comment.