Skip to content

Commit e974c85

Browse files
committed
Add MACsec forward and filters to HostInterfaceInfo
Signed-off-by: Ze Gan <[email protected]>
1 parent f1b1f05 commit e974c85

File tree

6 files changed

+171
-8
lines changed

6 files changed

+171
-8
lines changed

vslib/inc/HostInterfaceInfo.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ extern "C" {
55
}
66

77
#include "EventQueue.h"
8+
#include "TrafficFilterPipes.h"
89

910
#include "swss/selectableevent.h"
1011

@@ -38,6 +39,20 @@ namespace saivs
3839
_In_ const uint8_t *buffer,
3940
_In_ size_t size) const;
4041

42+
bool installEth2TapFilter(
43+
_In_ int priority,
44+
_In_ std::shared_ptr<TrafficFilter> filter);
45+
46+
bool uninstallEth2TapFilter(
47+
_In_ std::shared_ptr<TrafficFilter> filter);
48+
49+
bool installTap2EthFilter(
50+
_In_ int priority,
51+
_In_ std::shared_ptr<TrafficFilter> filter);
52+
53+
bool uninstallTap2EthFilter(
54+
_In_ std::shared_ptr<TrafficFilter> filter);
55+
4156
private:
4257

4358
void veth2tap_fun();
@@ -58,13 +73,16 @@ namespace saivs
5873

5974
std::shared_ptr<EventQueue> m_eventQueue;
6075

61-
private:
62-
6376
int m_tapfd;
6477

78+
private:
79+
6580
std::shared_ptr<std::thread> m_e2t;
6681
std::shared_ptr<std::thread> m_t2e;
6782

83+
TrafficFilterPipes m_e2tFilters;
84+
TrafficFilterPipes m_t2eFilters;
85+
6886
swss::SelectableEvent m_e2tEvent;
6987
swss::SelectableEvent m_t2eEvent;
7088
};

vslib/inc/MACsecForwarder.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#include "HostInterfaceInfo.h"
4+
35
#include "swss/sal.h"
46
#include "swss/selectableevent.h"
57

@@ -14,7 +16,8 @@ namespace saivs
1416
public:
1517
MACsecForwarder(
1618
_In_ const std::string &macsecInterfaceName,
17-
_In_ int tapfd);
19+
_In_ int tapfd,
20+
_In_ std::shared_ptr<HostInterfaceInfo> info);
1821

1922
virtual ~MACsecForwarder();
2023

@@ -33,5 +36,7 @@ namespace saivs
3336
swss::SelectableEvent m_exitEvent;
3437

3538
std::shared_ptr<std::thread> m_forwardThread;
39+
40+
std::shared_ptr<HostInterfaceInfo> m_info;
3641
};
3742
}

vslib/src/HostInterfaceInfo.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,40 @@ void HostInterfaceInfo::async_process_packet_for_fdb_event(
9090
m_eventQueue->enqueue(std::make_shared<Event>(EventType::EVENT_TYPE_PACKET, payload));
9191
}
9292

93+
bool HostInterfaceInfo::installEth2TapFilter(
94+
_In_ int priority,
95+
_In_ std::shared_ptr<TrafficFilter> filter)
96+
{
97+
SWSS_LOG_ENTER();
98+
99+
return m_e2tFilters.installFilter(priority, filter);
100+
}
101+
102+
bool HostInterfaceInfo::uninstallEth2TapFilter(
103+
_In_ std::shared_ptr<TrafficFilter> filter)
104+
{
105+
SWSS_LOG_ENTER();
106+
107+
return m_e2tFilters.uninstallFilter(filter);
108+
}
109+
110+
bool HostInterfaceInfo::installTap2EthFilter(
111+
_In_ int priority,
112+
_In_ std::shared_ptr<TrafficFilter> filter)
113+
{
114+
SWSS_LOG_ENTER();
115+
116+
return m_t2eFilters.installFilter(priority, filter);
117+
}
118+
119+
bool HostInterfaceInfo::uninstallTap2EthFilter(
120+
_In_ std::shared_ptr<TrafficFilter> filter)
121+
{
122+
SWSS_LOG_ENTER();
123+
124+
return m_t2eFilters.uninstallFilter(filter);
125+
}
126+
93127
#define ETH_FRAME_BUFFER_SIZE (0x4000)
94128
#define CONTROL_MESSAGE_BUFFER_SIZE (0x1000)
95129
#define IEEE_8021Q_ETHER_TYPE (0x8100)
@@ -161,6 +195,20 @@ void HostInterfaceInfo::veth2tap_fun()
161195
continue;
162196
}
163197

198+
size_t length = static_cast<size_t>(size);
199+
auto ret = m_e2tFilters.execute(buffer, length);
200+
size = static_cast<ssize_t>(length);
201+
202+
if (ret == TrafficFilter::TERMINATE)
203+
{
204+
continue;
205+
}
206+
else if (ret == TrafficFilter::ERROR)
207+
{
208+
// Error log should be recorded in filter
209+
return;
210+
}
211+
164212
struct cmsghdr *cmsg;
165213

166214
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg))
@@ -268,6 +316,20 @@ void HostInterfaceInfo::tap2veth_fun()
268316
continue;
269317
}
270318

319+
size_t length = static_cast<size_t>(size);
320+
auto ret = m_t2eFilters.execute(buffer, length);
321+
size = static_cast<ssize_t>(length);
322+
323+
if (ret == TrafficFilter::TERMINATE)
324+
{
325+
continue;
326+
}
327+
else if (ret == TrafficFilter::ERROR)
328+
{
329+
// Error log should be recorded in filter
330+
return;
331+
}
332+
271333
if (write(m_packet_socket, buffer, (int)size) < 0)
272334
{
273335
if (errno != ENETDOWN)

vslib/src/MACsecForwarder.cpp

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,19 @@
1515
using namespace saivs;
1616

1717
#define ETH_FRAME_BUFFER_SIZE (0x4000)
18+
#define CONTROL_MESSAGE_BUFFER_SIZE (0x1000)
19+
#define IEEE_8021Q_ETHER_TYPE (0x8100)
20+
#define MAC_ADDRESS_SIZE (6)
21+
#define VLAN_TAG_SIZE (4)
1822

1923
MACsecForwarder::MACsecForwarder(
2024
_In_ const std::string &macsecInterfaceName,
21-
_In_ int tapfd):
25+
_In_ int tapfd,
26+
_In_ std::shared_ptr<HostInterfaceInfo> info):
2227
m_tapfd(tapfd),
2328
m_macsecInterfaceName(macsecInterfaceName),
24-
m_runThread(true)
29+
m_runThread(true),
30+
m_info(info)
2531
{
2632
SWSS_LOG_ENTER();
2733

@@ -112,6 +118,25 @@ void MACsecForwarder::forward()
112118

113119
while (m_runThread)
114120
{
121+
struct msghdr msg;
122+
memset(&msg, 0, sizeof(struct msghdr));
123+
124+
struct sockaddr_storage srcAddr;
125+
126+
struct iovec iov[1];
127+
128+
iov[0].iov_base = buffer; // buffer for message
129+
iov[0].iov_len = sizeof(buffer);
130+
131+
char control[CONTROL_MESSAGE_BUFFER_SIZE]; // buffer for control messages
132+
133+
msg.msg_name = &srcAddr;
134+
msg.msg_namelen = sizeof(srcAddr);
135+
msg.msg_iov = iov;
136+
msg.msg_iovlen = 1;
137+
msg.msg_control = control;
138+
msg.msg_controllen = sizeof(control);
139+
115140
swss::Selectable *sel = NULL;
116141
int result = s.select(&sel);
117142

@@ -128,7 +153,7 @@ void MACsecForwarder::forward()
128153
if (sel == &m_exitEvent) // thread end event
129154
break;
130155

131-
ssize_t size = read(m_macsecfd, buffer, sizeof(buffer));
156+
ssize_t size = recvmsg(m_macsecfd, &msg, 0);
132157

133158
if (size < 0)
134159
{
@@ -151,6 +176,55 @@ void MACsecForwarder::forward()
151176

152177
continue;
153178
}
179+
else if (size < (ssize_t)sizeof(ethhdr))
180+
{
181+
SWSS_LOG_ERROR("invalid ethernet frame length: %zu", msg.msg_controllen);
182+
183+
continue;
184+
}
185+
186+
struct cmsghdr *cmsg;
187+
188+
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg))
189+
{
190+
if (cmsg->cmsg_level != SOL_PACKET || cmsg->cmsg_type != PACKET_AUXDATA)
191+
continue;
192+
193+
struct tpacket_auxdata* aux = (struct tpacket_auxdata*)CMSG_DATA(cmsg);
194+
195+
if ((aux->tp_status & TP_STATUS_VLAN_VALID) &&
196+
(aux->tp_status & TP_STATUS_VLAN_TPID_VALID))
197+
{
198+
SWSS_LOG_DEBUG("got vlan tci: 0x%x, vlanid: %d", aux->tp_vlan_tci, aux->tp_vlan_tci & 0xFFF);
199+
200+
// inject vlan tag into frame
201+
202+
// for overlapping buffers
203+
memmove(buffer + 2 * MAC_ADDRESS_SIZE + VLAN_TAG_SIZE,
204+
buffer + 2 * MAC_ADDRESS_SIZE,
205+
size - (2 * MAC_ADDRESS_SIZE));
206+
207+
uint16_t tci = htons(aux->tp_vlan_tci);
208+
uint16_t tpid = htons(IEEE_8021Q_ETHER_TYPE);
209+
210+
uint8_t* pvlan = (uint8_t *)(buffer + 2 * MAC_ADDRESS_SIZE);
211+
memcpy(pvlan, &tpid, sizeof(uint16_t));
212+
memcpy(pvlan + sizeof(uint16_t), &tci, sizeof(uint16_t));
213+
214+
size += VLAN_TAG_SIZE;
215+
216+
break;
217+
}
218+
}
219+
220+
if (m_info == nullptr)
221+
{
222+
SWSS_LOG_ERROR("The HostInterfaceInfo on the MACsec port %s is empty", m_macsecInterfaceName.c_str());
223+
224+
break;
225+
}
226+
227+
m_info->async_process_packet_for_fdb_event(buffer, size);
154228

155229
if (write(m_tapfd, buffer, static_cast<int>(size)) < 0)
156230
{

vslib/src/MACsecManager.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ bool MACsecManager::add_macsec_forwarder(
579579

580580
auto &manager = itr->second;
581581

582-
manager.m_forwarder = std::make_shared<MACsecForwarder>(macsecInterface, manager.m_info->m_tapfd);
582+
manager.m_forwarder = std::make_shared<MACsecForwarder>(macsecInterface, manager.m_info->m_tapfd, manager.m_info);
583583
return true;
584584
}
585585

vslib/src/Makefile.am

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,11 @@ libSaiVS_a_SOURCES = \
5353
SwitchMLNX2700.cpp \
5454
CorePortIndexMap.cpp \
5555
CorePortIndexMapContainer.cpp \
56-
CorePortIndexMapFileParser.cpp
56+
CorePortIndexMapFileParser.cpp \
57+
MACsecFilter.cpp \
58+
MACsecEgressFilter.cpp \
59+
MACsecIngressFilter.cpp \
60+
TrafficFilterPipes.cpp
5761

5862
libsaivs_la_SOURCES = \
5963
sai_vs_fdb.cpp \

0 commit comments

Comments
 (0)