Skip to content

Commit bbad01e

Browse files
rluboskartben
authored andcommitted
tests: net: socket: af_packet: Add more tests to verify binding
In case the receiving packet socket is not bound to any specific interface, or is explicitly bound to "any" interface (at index 0), it should collect packets from all interfaces. Add test cases which verify that. Also, if a packet socket is bound to a specific interface, it should not receive packets from others. Add a test case to verify that as well. Signed-off-by: Robert Lubos <[email protected]>
1 parent 6654f78 commit bbad01e

File tree

1 file changed

+167
-13
lines changed
  • tests/net/socket/af_packet/src

1 file changed

+167
-13
lines changed

tests/net/socket/af_packet/src/main.c

Lines changed: 167 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,16 @@ LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL);
7272
* * (AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)) - The packet is received for all protocols.
7373
* The L2 header is not removed from the data:
7474
* - test_raw_sock_recv_proto_wildcard
75+
* - test_raw_sock_recv_proto_wildcard_bound_other_iface
7576
* - test_raw_sock_recvfrom_proto_wildcard
77+
* - test_raw_sock_recvfrom_proto_wildcard_unbound
7678
*
7779
* * (AF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)) - The packet is received for all protocols.
7880
* The L2 header is removed from the data:
7981
* - test_dgram_sock_recv_proto_wildcard
82+
* - test_dgram_sock_recv_proto_wildcard_bound_other_iface
8083
* - test_dgram_sock_recvfrom_proto_wildcard
84+
* - test_dgram_sock_recvfrom_proto_wildcard_unbound
8185
*/
8286

8387
#if defined(CONFIG_NET_SOCKETS_LOG_LEVEL_DBG)
@@ -128,14 +132,16 @@ static int eth_fake_send(const struct device *dev, struct net_pkt *pkt)
128132
DBG("Sending data (%d bytes) to iface %d\n",
129133
net_pkt_get_len(pkt), net_if_get_by_iface(net_pkt_iface(pkt)));
130134

131-
recv_pkt = net_pkt_rx_clone(pkt, K_NO_WAIT);
132-
133135
if (memcmp(pkt->frags->data, lladdr1, sizeof(lladdr1)) == 0) {
134136
target_iface = eth_fake_data1.iface;
135-
} else {
137+
} else if (memcmp(pkt->frags->data, lladdr2, sizeof(lladdr2)) == 0) {
136138
target_iface = eth_fake_data2.iface;
139+
} else {
140+
return 0;
137141
}
138142

143+
recv_pkt = net_pkt_rx_clone(pkt, K_NO_WAIT);
144+
139145
net_pkt_set_iface(recv_pkt, target_iface);
140146

141147
k_sleep(K_MSEC(10)); /* Let the receiver run */
@@ -201,7 +207,7 @@ static void bind_packet_socket(int sock, struct net_if *iface)
201207

202208
memset(&addr, 0, sizeof(addr));
203209

204-
addr.sll_ifindex = net_if_get_by_iface(iface);
210+
addr.sll_ifindex = (iface == NULL) ? 0 : net_if_get_by_iface(iface);
205211
addr.sll_family = AF_PACKET;
206212

207213
ret = zsock_bind(sock, (struct sockaddr *)&addr, sizeof(addr));
@@ -866,6 +872,20 @@ ZTEST(socket_packet, test_raw_sock_recv_proto_wildcard)
866872
test_recv_common(SOCK_RAW, ETH_P_ALL, true);
867873
}
868874

875+
static void validate_recvfrom_addr(struct sockaddr_ll *ll_rx, socklen_t addrlen,
876+
int iface, uint8_t *lladdr)
877+
{
878+
zassert_equal(addrlen, sizeof(struct sockaddr_ll),
879+
"Invalid address length (%u)", addrlen);
880+
zassert_equal(ll_rx->sll_family, AF_PACKET, "Invalid family");
881+
zassert_equal(ll_rx->sll_protocol, htons(ETH_P_IP), "Invalid protocol");
882+
zassert_equal(ll_rx->sll_ifindex, iface, "Invalid interface");
883+
zassert_equal(ll_rx->sll_hatype, ARPHRD_ETHER, "Invalid hardware type");
884+
zassert_equal(ll_rx->sll_pkttype, PACKET_OTHERHOST, "Invalid packet type");
885+
zassert_equal(ll_rx->sll_halen, NET_ETH_ADDR_LEN, "Invalid address length");
886+
zassert_mem_equal(ll_rx->sll_addr, lladdr, NET_ETH_ADDR_LEN, "Invalid address");
887+
}
888+
869889
static void test_recvfrom_common(int sock_type, int proto)
870890
{
871891
struct sockaddr_ll ll_dst;
@@ -905,15 +925,8 @@ static void test_recvfrom_common(int sock_type, int proto)
905925
"Invalid payload received");
906926
zassert_equal(addrlen, sizeof(struct sockaddr_ll),
907927
"Invalid address length (%u)", addrlen);
908-
zassert_equal(ll_rx.sll_family, AF_PACKET, "Invalid family");
909-
zassert_equal(ll_rx.sll_protocol, htons(ETH_P_IP), "Invalid protocol");
910-
zassert_equal(ll_rx.sll_ifindex, net_if_get_by_iface(ud.first),
911-
"Invalid interface");
912-
zassert_equal(ll_rx.sll_hatype, ARPHRD_ETHER, "Invalid hardware type");
913-
zassert_equal(ll_rx.sll_pkttype, PACKET_OTHERHOST, "Invalid packet type");
914-
zassert_equal(ll_rx.sll_halen, NET_ETH_ADDR_LEN, "Invalid address length");
915-
zassert_mem_equal(ll_rx.sll_addr, &lladdr2, NET_ETH_ADDR_LEN,
916-
"Invalid address");
928+
validate_recvfrom_addr(&ll_rx, addrlen, net_if_get_by_iface(ud.first),
929+
lladdr2);
917930
}
918931

919932
ZTEST(socket_packet, test_raw_sock_recvfrom_proto_wildcard)
@@ -931,6 +944,147 @@ ZTEST(socket_packet, test_dgram_sock_recvfrom_proto_wildcard)
931944
test_recvfrom_common(SOCK_DGRAM, ETH_P_ALL);
932945
}
933946

947+
static void test_recvfrom_unbound_round(int tx_sock, int rx_sock, int sock_type,
948+
uint8_t *src_addr, struct net_if *src_iface,
949+
uint8_t *dst_addr, struct net_if *dst_iface)
950+
{
951+
uint16_t offset = (sock_type == SOCK_DGRAM) ? sizeof(struct net_eth_hdr) : 0;
952+
struct sockaddr_ll ll_dst;
953+
struct sockaddr_ll ll_rx = { 0 };
954+
socklen_t addrlen = sizeof(ll_rx);
955+
uint16_t pkt_len;
956+
int ret;
957+
958+
prepare_test_packet(SOCK_RAW, ETH_P_IP, src_addr, dst_addr, &pkt_len);
959+
prepare_test_dst_lladdr(&ll_dst, ETH_P_IP, dst_addr, src_iface);
960+
961+
ret = zsock_sendto(packet_sock_1, tx_buf, pkt_len, 0,
962+
(struct sockaddr *)&ll_dst,
963+
sizeof(struct sockaddr_ll));
964+
zassert_not_equal(ret, -1, "Failed to send (%d)", errno);
965+
zassert_equal(ret, pkt_len, "Invalid data length sent (%d/%d)", ret, pkt_len);
966+
967+
pkt_len -= offset;
968+
969+
ret = zsock_recvfrom(packet_sock_2, rx_buf, sizeof(rx_buf), 0,
970+
(struct sockaddr *)&ll_rx, &addrlen);
971+
zassert_not_equal(ret, -1, "Failed to receive packet (%d)", errno);
972+
zassert_equal(ret, pkt_len,
973+
"Invalid data size received (%d, expected %d)",
974+
ret, pkt_len);
975+
zassert_mem_equal(rx_buf, tx_buf + offset, pkt_len,
976+
"Invalid payload received");
977+
validate_recvfrom_addr(&ll_rx, addrlen, net_if_get_by_iface(dst_iface),
978+
src_addr);
979+
}
980+
981+
static void test_recvfrom_common_unbound(int sock_type, bool bind_iface_0)
982+
{
983+
struct sockaddr_ll ll_dst;
984+
static uint8_t dummy_lladdr[] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
985+
uint16_t pkt_len;
986+
int ret;
987+
988+
/* Transmitting sock */
989+
setup_packet_socket(&packet_sock_1, SOCK_RAW, 0);
990+
/* Receiving sock */
991+
setup_packet_socket(&packet_sock_2, sock_type, htons(ETH_P_ALL));
992+
993+
if (bind_iface_0) {
994+
bind_packet_socket(packet_sock_2, NULL);
995+
}
996+
997+
/* Verify we get packet from iface 1 */
998+
test_recvfrom_unbound_round(packet_sock_1, packet_sock_2, sock_type,
999+
lladdr2, ud.second, lladdr1, ud.first);
1000+
1001+
/* Verify we get packet from iface 2 */
1002+
test_recvfrom_unbound_round(packet_sock_1, packet_sock_2, sock_type,
1003+
lladdr1, ud.first, lladdr2, ud.second);
1004+
1005+
/* Send some dummy data into the void on the "receiving" socket and make
1006+
* sure it doesn't get automatically "bound" to the target iface.
1007+
*/
1008+
prepare_test_dst_lladdr(&ll_dst, ETH_P_IP, dummy_lladdr, ud.second);
1009+
prepare_test_packet(sock_type, ETH_P_IP, lladdr2, dummy_lladdr, &pkt_len);
1010+
ret = zsock_sendto(packet_sock_2, tx_buf, pkt_len, 0,
1011+
(struct sockaddr *)&ll_dst,
1012+
sizeof(struct sockaddr_ll));
1013+
zassert_not_equal(ret, -1, "Failed to send (%d)", errno);
1014+
zassert_equal(ret, pkt_len, "Invalid data length sent (%d/%d)", ret, pkt_len);
1015+
1016+
/* And try to receive again. */
1017+
/* Verify we get packet from iface 1 */
1018+
test_recvfrom_unbound_round(packet_sock_1, packet_sock_2, sock_type,
1019+
lladdr2, ud.second, lladdr1, ud.first);
1020+
1021+
/* Verify we get packet from iface 2 */
1022+
test_recvfrom_unbound_round(packet_sock_1, packet_sock_2, sock_type,
1023+
lladdr1, ud.first, lladdr2, ud.second);
1024+
}
1025+
1026+
ZTEST(socket_packet, test_raw_sock_recvfrom_proto_wildcard_unbound)
1027+
{
1028+
test_recvfrom_common_unbound(SOCK_RAW, false);
1029+
}
1030+
1031+
ZTEST(socket_packet, test_dgram_sock_recvfrom_proto_wildcard_unbound)
1032+
{
1033+
test_recvfrom_common_unbound(SOCK_DGRAM, false);
1034+
}
1035+
1036+
ZTEST(socket_packet, test_raw_sock_recvfrom_proto_wildcard_bound_iface_0)
1037+
{
1038+
test_recvfrom_common_unbound(SOCK_RAW, true);
1039+
}
1040+
1041+
ZTEST(socket_packet, test_dgram_sock_recvfrom_proto_wildcard_bound_iface_0)
1042+
{
1043+
test_recvfrom_common_unbound(SOCK_DGRAM, true);
1044+
}
1045+
1046+
static void test_recv_common_bound_other_iface(int sock_type)
1047+
{
1048+
struct sockaddr_ll ll_dst;
1049+
struct sockaddr_in ip_src;
1050+
uint16_t pkt_len;
1051+
int ret;
1052+
1053+
/* Transmitting sock */
1054+
setup_packet_socket(&packet_sock_1, SOCK_RAW, 0);
1055+
prepare_test_packet(SOCK_RAW, ETH_P_IP, lladdr1, lladdr2, &pkt_len);
1056+
prepare_test_dst_lladdr(&ll_dst, ETH_P_IP, lladdr2, ud.first);
1057+
/* Receiving sock */
1058+
setup_packet_socket(&packet_sock_2, sock_type, htons(ETH_P_ALL));
1059+
bind_packet_socket(packet_sock_2, ud.first);
1060+
prepare_udp_socket(&udp_sock_1, &ip_src, DST_PORT);
1061+
1062+
ret = zsock_sendto(packet_sock_1, tx_buf, pkt_len, 0,
1063+
(struct sockaddr *)&ll_dst,
1064+
sizeof(struct sockaddr_ll));
1065+
zassert_not_equal(ret, -1, "Failed to send (%d)", errno);
1066+
zassert_equal(ret, pkt_len, "Invalid data length sent (%d/%d)", ret, pkt_len);
1067+
1068+
/* Packet socket should not get the packet due to different binding */
1069+
ret = zsock_recv(packet_sock_2, rx_buf, sizeof(rx_buf), 0);
1070+
zassert_equal(ret, -1, "Recv should fail");
1071+
zassert_equal(errno, EAGAIN, "Wrong errno");
1072+
1073+
/* But UDP socket should get the packet just fine. */
1074+
ret = zsock_recv(udp_sock_1, rx_buf, sizeof(rx_buf), 0);
1075+
zassert_not_equal(ret, -1, "Failed to receive UDP packet (%d)", errno);
1076+
}
1077+
1078+
ZTEST(socket_packet, test_raw_sock_recv_proto_wildcard_bound_other_iface)
1079+
{
1080+
test_recv_common_bound_other_iface(SOCK_RAW);
1081+
}
1082+
1083+
ZTEST(socket_packet, test_dgram_sock_recv_proto_wildcard_bound_other_iface)
1084+
{
1085+
test_recv_common_bound_other_iface(SOCK_DGRAM);
1086+
}
1087+
9341088
ZTEST(socket_packet, test_raw_dgram_udp_socks_recv)
9351089
{
9361090
struct sockaddr_in ip_src;

0 commit comments

Comments
 (0)