Skip to content

Commit 83f523f

Browse files
Lukasz Majewskijukkar
authored andcommitted
net: Add support for simultaneous UDP/TCP and raw sockets
This patch brings support for AF_PACKET and SOCK_RAW type of sockets. In net_conn_input() function the new flag has been introduced - 'raw_pkt_continue' to indicate if there are other than AF_PACKET connections registered. If we do not have other connections than AF_PACKET, the packet is solely handled in net_conn_input() (or to be more specific in its helper function - conn_raw_socket()). Otherwise, it is passed back to net_conn_input in IPv4/6 processing. Signed-off-by: Lukasz Majewski <[email protected]>
1 parent 1f72b1f commit 83f523f

File tree

1 file changed

+45
-16
lines changed

1 file changed

+45
-16
lines changed

subsys/net/ip/connection.c

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,7 @@ enum net_verdict net_conn_input(struct net_pkt *pkt,
554554
bool is_mcast_pkt = false, mcast_pkt_delivered = false;
555555
bool is_bcast_pkt = false;
556556
bool raw_pkt_delivered = false;
557+
bool raw_pkt_continue = false;
557558
int16_t best_rank = -1;
558559
struct net_conn *conn;
559560
enum net_verdict ret;
@@ -638,6 +639,36 @@ enum net_verdict net_conn_input(struct net_pkt *pkt,
638639

639640
if (conn->family != AF_UNSPEC &&
640641
conn->family != net_pkt_family(pkt)) {
642+
/* If there are other listening connections than
643+
* AF_PACKET, the packet shall be also passed back to
644+
* net_conn_input() in IPv4/6 processing in order to
645+
* re-check if there is any listening socket interested
646+
* in this packet.
647+
*/
648+
if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
649+
conn->family != AF_PACKET) {
650+
raw_pkt_continue = true;
651+
}
652+
653+
continue;
654+
}
655+
656+
/* The code below shall be only executed when one enters
657+
* the net_conn_input() from net_packet_socket() which
658+
* is executed for e.g. AF_PACKET && SOCK_RAW
659+
*
660+
* Here we do need to check if we have ANY connection which
661+
* was setup with AF_PACKET
662+
*/
663+
if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
664+
conn->family == AF_PACKET) {
665+
ret = conn_raw_socket(pkt, conn);
666+
if (ret == NET_DROP) {
667+
goto drop;
668+
} else if (ret == NET_OK) {
669+
raw_pkt_delivered = true;
670+
}
671+
641672
continue;
642673
}
643674

@@ -720,30 +751,28 @@ enum net_verdict net_conn_input(struct net_pkt *pkt,
720751

721752
mcast_pkt_delivered = true;
722753
}
723-
} else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET)) {
724-
ret = conn_raw_socket(pkt, conn);
725-
if (ret == NET_DROP) {
726-
goto drop;
727-
} else if (ret == NET_CONTINUE) {
728-
continue;
729-
} else if (ret == NET_OK) {
730-
raw_pkt_delivered = true;
731-
}
732754
} else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN)) {
733755
best_rank = 0;
734756
best_match = conn;
735757
}
736758
}
737759

738760
if ((is_mcast_pkt && mcast_pkt_delivered) || raw_pkt_delivered) {
739-
/* As one or more multicast or raw socket packets have already
740-
* been delivered in the loop above, we shall not call the
741-
* callback again here.
742-
*/
743-
744-
net_pkt_unref(pkt);
761+
if (raw_pkt_continue) {
762+
/* When there is open connection different than
763+
* AF_PACKET this packet shall be also handled in
764+
* the upper net stack layers.
765+
*/
766+
return NET_CONTINUE;
767+
} else {
768+
/* As one or more multicast or raw socket packets
769+
* have already been delivered in the loop above,
770+
* we shall not call the callback again here.
771+
*/
772+
net_pkt_unref(pkt);
745773

746-
return NET_OK;
774+
return NET_OK;
775+
}
747776
}
748777

749778
conn = best_match;

0 commit comments

Comments
 (0)