Skip to content

Commit

Permalink
[copporch] Add submit to ingress port for packet outs
Browse files Browse the repository at this point in the history
Submission containing materials of a third party:
    Copyright Google LLC; Licensed under Apache 2.0

Co-authored-by: Glenn Connery <gconnery@google.com>
Co-authored-by: Yilan Ji <yilanji@google.com>
Co-authored-by: Runming Wu <runmingwu@google.com>

Signed-off-by: Don Newton don@opennetworking.org
  • Loading branch information
PINS Working Group authored and bocon13 committed Oct 28, 2021
1 parent bfba0ad commit cadcb05
Show file tree
Hide file tree
Showing 2 changed files with 191 additions and 7 deletions.
177 changes: 172 additions & 5 deletions orchagent/copporch.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#include <sys/ioctl.h>
#include <net/if.h>

#include "sai.h"
#include "copporch.h"
#include "portsorch.h"
Expand Down Expand Up @@ -427,6 +430,89 @@ bool CoppOrch::createPolicer(string trap_group_name, vector<sai_attribute_t> &po
return true;
}

bool CoppOrch::createSubmitToIngressHostIf(vector<sai_attribute_t> &ingress_attribs)
{
SWSS_LOG_ENTER();

sai_status_t sai_status;
struct ifreq ifr;
int sock_fd;
char *ifname = NULL;
size_t len;

sai_status = sai_hostif_api->create_hostif(&m_submit_to_ingress_id,
gSwitchId,
(uint32_t)ingress_attribs.size(),
ingress_attribs.data()
);

if (sai_status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to create SubmitToIngress hostif, rc=%d",
sai_status);
return false;
}

// Setting CPU port operational status is not working on some of
// the vendor SAI implementations. Using IOCTL to bring the
// netdev up instead.

// find the netdev name
for (uint32_t i = 0; i < (uint32_t)ingress_attribs.size(); i++)
{
if (ingress_attribs[i].id == SAI_HOSTIF_ATTR_NAME)
{
ifname = ingress_attribs[i].value.chardata;
break;
}
}

if (ifname == NULL)
{
SWSS_LOG_ERROR("No interface name found");
(void)removeSubmitToIngressHostIf();
return false;
}

// create a socket
sock_fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (sock_fd < 0)
{
SWSS_LOG_ERROR("Failed to open raw socket, sock_fd=%d",
sock_fd);
(void)removeSubmitToIngressHostIf();
return false;
}

// bind it to the netdev by name
len = strnlen(ifname, IFNAMSIZ);
setsockopt(sock_fd, SOL_SOCKET, SO_BINDTODEVICE, ifname, (socklen_t)len);

// read the flags
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) == -1)
{
SWSS_LOG_ERROR("Unable to read socket flags");
close(sock_fd);
(void)removeSubmitToIngressHostIf();
return false;
}

// set the flags to bring the interface up
ifr.ifr_flags |= IFF_UP|IFF_RUNNING;
if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) == -1)
{
SWSS_LOG_ERROR("Unable to write socket flags");
close(sock_fd);
(void)removeSubmitToIngressHostIf();
return false;
}

close(sock_fd);
return true;
}

bool CoppOrch::createGenetlinkHostIf(string trap_group_name, vector<sai_attribute_t> &genetlink_attribs)
{
SWSS_LOG_ENTER();
Expand All @@ -452,6 +538,31 @@ bool CoppOrch::createGenetlinkHostIf(string trap_group_name, vector<sai_attribut
return true;
}

bool CoppOrch::removeSubmitToIngressHostIf()
{
SWSS_LOG_ENTER();

if (SAI_NULL_OBJECT_ID == m_submit_to_ingress_id)
{
SWSS_LOG_ERROR("Can't delete invalid SubmitToIngress hostif");
return false;
}

sai_status_t sai_status;

sai_status = sai_hostif_api->remove_hostif(m_submit_to_ingress_id);
if (sai_status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to delete SubmitToIngress hostif, rc=%d",
sai_status);
return false;
}

m_submit_to_ingress_id = SAI_NULL_OBJECT_ID;

return true;
}

bool CoppOrch::removeGenetlinkHostIf(string trap_group_name)
{
SWSS_LOG_ENTER();
Expand Down Expand Up @@ -501,6 +612,7 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
vector<sai_attribute_t> trap_id_attribs;
vector<sai_attribute_t> policer_attribs;
vector<sai_attribute_t> genetlink_attribs;
vector<sai_attribute_t> ingress_attribs;

vector<sai_hostif_trap_type_t> trap_ids;
vector<sai_hostif_trap_type_t> add_trap_ids;
Expand All @@ -520,7 +632,8 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
}

if (!getAttribsFromTrapGroup(fv_tuple, trap_gr_attribs, trap_id_attribs,
policer_attribs, genetlink_attribs))
policer_attribs, genetlink_attribs,
ingress_attribs))
{
return task_process_status::task_invalid_entry;
}
Expand All @@ -531,7 +644,6 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
for (sai_uint32_t ind = 0; ind < trap_gr_attribs.size(); ind++)
{
auto trap_gr_attr = trap_gr_attribs[ind];

sai_status = sai_hostif_api->set_hostif_trap_group_attribute(m_trap_group_map[trap_group_name], &trap_gr_attr);
if (sai_status != SAI_STATUS_SUCCESS)
{
Expand Down Expand Up @@ -572,6 +684,7 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
return task_process_status::task_failed;
}
}

if (!trap_id_attribs.empty())
{
vector<sai_hostif_trap_type_t> group_trap_ids;
Expand Down Expand Up @@ -603,6 +716,7 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
}
m_trap_group_trap_id_attrs[trap_group_name] = trap_attr;
}

if (!genetlink_attribs.empty())
{
if (m_trap_group_hostif_map.find(m_trap_group_map[trap_group_name]) !=
Expand All @@ -623,6 +737,15 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
return task_process_status::task_failed;
}
}

if (!ingress_attribs.empty())
{
if (!createSubmitToIngressHostIf(ingress_attribs))
{
return task_process_status::task_failed;
}
}

if (!trapGroupProcessTrapIdChange(trap_group_name, add_trap_ids, rem_trap_ids))
{
return task_process_status::task_failed;
Expand Down Expand Up @@ -875,6 +998,12 @@ bool CoppOrch::processTrapGroupDel (string trap_group_name)
return false;
}

if (!removeSubmitToIngressHostIf())
{
SWSS_LOG_ERROR("Failed to remove ingress hostif");
return false;
}

/* Reset the trap IDs to default trap group with default attributes */
vector<sai_hostif_trap_type_t> trap_ids_to_reset;
for (auto it : m_syncdTrapIds)
Expand Down Expand Up @@ -920,7 +1049,8 @@ bool CoppOrch::getAttribsFromTrapGroup (vector<FieldValueTuple> &fv_tuple,
vector<sai_attribute_t> &trap_gr_attribs,
vector<sai_attribute_t> &trap_id_attribs,
vector<sai_attribute_t> &policer_attribs,
vector<sai_attribute_t> &genetlink_attribs)
vector<sai_attribute_t> &genetlink_attribs,
vector<sai_attribute_t> &ingress_attribs)
{
sai_attribute_t attr;

Expand Down Expand Up @@ -1034,18 +1164,55 @@ bool CoppOrch::getAttribsFromTrapGroup (vector<FieldValueTuple> &fv_tuple,
genetlink_attribs.push_back(attr);

attr.id = SAI_HOSTIF_ATTR_NAME;
auto size = sizeof(attr.value.chardata);
strncpy(attr.value.chardata, fvValue(*i).c_str(),
sizeof(attr.value.chardata));
size - 1);
attr.value.chardata[size - 1] = '\0';
genetlink_attribs.push_back(attr);

}
else if (fvField(*i) == copp_genetlink_mcgrp_name)
{
attr.id = SAI_HOSTIF_ATTR_GENETLINK_MCGRP_NAME;
auto size = sizeof(attr.value.chardata);
strncpy(attr.value.chardata, fvValue(*i).c_str(),
sizeof(attr.value.chardata));
size - 1);
attr.value.chardata[size - 1] = '\0';
genetlink_attribs.push_back(attr);
}
else if (fvField(*i) == copp_submit_to_ingress_name)
{
sai_status_t status;

attr.id = SAI_HOSTIF_ATTR_TYPE;
attr.value.s32 = SAI_HOSTIF_TYPE_NETDEV;
ingress_attribs.push_back(attr);

attr.id = SAI_HOSTIF_ATTR_NAME;
auto size = sizeof(attr.value.chardata);
strncpy(attr.value.chardata, fvValue(*i).c_str(),
size - 1);
attr.value.chardata[size - 1] = '\0';
ingress_attribs.push_back(attr);

// If this isn't passed in true, the false setting makes
// the device unready for later attempts to set UP/RUNNING
attr.id = SAI_HOSTIF_ATTR_OPER_STATUS;
attr.value.booldata = true;
ingress_attribs.push_back(attr);

// Get CPU port object id to signal submit to ingress
attr.id = SAI_SWITCH_ATTR_CPU_PORT;
status = sai_switch_api->get_switch_attribute(gSwitchId, 1, &attr);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Unable to get CPU port");
return false;
}

attr.id = SAI_HOSTIF_ATTR_OBJ_ID;
ingress_attribs.push_back(attr);
}
else
{
SWSS_LOG_ERROR("Unknown copp field specified:%s\n", fvField(*i).c_str());
Expand Down
21 changes: 19 additions & 2 deletions orchagent/copporch.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ const std::string copp_policer_action_yellow_field = "yellow_action";
const std::string copp_genetlink_name = "genetlink_name";
const std::string copp_genetlink_mcgrp_name = "genetlink_mcgrp_name";

// submit_to_ingress fields
const std::string copp_submit_to_ingress_name = "submit_to_ingress_name";

typedef std::map<sai_attr_id_t, sai_attribute_value_t> TrapIdAttribs;
struct copp_trap_objects
{
Expand All @@ -50,7 +53,19 @@ class CoppOrch : public Orch
{
public:
CoppOrch(swss::DBConnector* db, std::string tableName);

inline object_map getTrapGroupMap()
{
return m_trap_group_map;
}

inline TrapGroupHostIfMap getTrapGroupHostIfMap()
{
return m_trap_group_hostif_map;
}
protected:
sai_object_id_t m_submit_to_ingress_id;

object_map m_trap_group_map;

TrapGroupPolicerTable m_trap_group_policer_map;
Expand All @@ -77,6 +92,8 @@ class CoppOrch : public Orch
bool createGenetlinkHostIf(std::string trap_group_name, std::vector<sai_attribute_t> &hostif_attribs);
bool removeGenetlinkHostIf(std::string trap_group_name);
bool createGenetlinkHostIfTable(std::vector<sai_hostif_trap_type_t> &trap_id_list);
bool createSubmitToIngressHostIf(std::vector<sai_attribute_t> &hostif_attribs);
bool removeSubmitToIngressHostIf();
bool removeGenetlinkHostIfTable(std::vector<sai_hostif_trap_type_t> &trap_id_list);
void getTrapAddandRemoveList(std::string trap_group_name, std::vector<sai_hostif_trap_type_t> &trap_ids,
std::vector<sai_hostif_trap_type_t> &add_trap_ids,
Expand All @@ -95,11 +112,11 @@ class CoppOrch : public Orch
std::vector<sai_attribute_t> &trap_gr_attribs,
std::vector<sai_attribute_t> &trap_id_attribs,
std::vector<sai_attribute_t> &policer_attribs,
std::vector<sai_attribute_t> &genetlink_attribs);
std::vector<sai_attribute_t> &genetlink_attribs,
std::vector<sai_attribute_t> &ingress_attribs);

bool trapGroupUpdatePolicer (std::string trap_group_name, std::vector<sai_attribute_t> &policer_attribs);

virtual void doTask(Consumer& consumer);
};
#endif /* SWSS_COPPORCH_H */

0 comments on commit cadcb05

Please sign in to comment.