@@ -635,6 +635,37 @@ static enum net_verdict conn_raw_socket(struct net_pkt *pkt,
635
635
return NET_OK ;
636
636
}
637
637
638
+ #if defined(CONFIG_NET_SOCKETS_INET_RAW )
639
+ static void conn_raw_ip_socket (struct net_pkt * pkt , struct net_conn * conn )
640
+ {
641
+ struct net_pkt * raw_pkt ;
642
+ struct net_pkt_cursor cur ;
643
+
644
+ net_pkt_cursor_backup (pkt , & cur );
645
+ net_pkt_cursor_init (pkt );
646
+
647
+ NET_DBG ("[%p] raw IP match found cb %p ud %p" , conn , conn -> cb ,
648
+ conn -> user_data );
649
+
650
+ raw_pkt = net_pkt_clone (pkt , CLONE_TIMEOUT );
651
+ if (!raw_pkt ) {
652
+ return ;
653
+ }
654
+
655
+ if (conn -> cb (conn , raw_pkt , NULL , NULL , conn -> user_data ) == NET_DROP ) {
656
+ net_pkt_unref (raw_pkt );
657
+ }
658
+
659
+ net_pkt_cursor_restore (pkt , & cur );
660
+ }
661
+ #else
662
+ static void conn_raw_ip_socket (struct net_pkt * pkt , struct net_conn * conn )
663
+ {
664
+ ARG_UNUSED (pkt );
665
+ ARG_UNUSED (conn );
666
+ }
667
+ #endif /* defined(CONFIG_NET_SOCKETS_INET_RAW) */
668
+
638
669
enum net_verdict net_conn_input (struct net_pkt * pkt ,
639
670
union net_ip_header * ip_hdr ,
640
671
uint8_t proto ,
@@ -643,14 +674,17 @@ enum net_verdict net_conn_input(struct net_pkt *pkt,
643
674
struct net_if * pkt_iface = net_pkt_iface (pkt );
644
675
uint8_t pkt_family = net_pkt_family (pkt );
645
676
uint16_t src_port = 0U , dst_port = 0U ;
677
+ bool raw_ip_pkt = false;
646
678
647
679
if (!net_pkt_filter_local_in_recv_ok (pkt )) {
648
680
/* drop the packet */
649
681
return NET_DROP ;
650
682
}
651
683
652
684
if (IS_ENABLED (CONFIG_NET_IP ) && (pkt_family == AF_INET || pkt_family == AF_INET6 )) {
653
- if (IS_ENABLED (CONFIG_NET_UDP ) && proto == IPPROTO_UDP ) {
685
+ if (IS_ENABLED (CONFIG_NET_SOCKETS_INET_RAW ) && proto_hdr == NULL ) {
686
+ raw_ip_pkt = true;
687
+ } else if (IS_ENABLED (CONFIG_NET_UDP ) && proto == IPPROTO_UDP ) {
654
688
src_port = proto_hdr -> udp -> src_port ;
655
689
dst_port = proto_hdr -> udp -> dst_port ;
656
690
} else if (IS_ENABLED (CONFIG_NET_TCP ) && proto == IPPROTO_TCP ) {
@@ -660,7 +694,8 @@ enum net_verdict net_conn_input(struct net_pkt *pkt,
660
694
src_port = proto_hdr -> tcp -> src_port ;
661
695
dst_port = proto_hdr -> tcp -> dst_port ;
662
696
}
663
- if (!conn_are_endpoints_valid (pkt , pkt_family , ip_hdr , src_port , dst_port )) {
697
+ if (!raw_ip_pkt && !conn_are_endpoints_valid (pkt , pkt_family , ip_hdr ,
698
+ src_port , dst_port )) {
664
699
NET_DBG ("Dropping invalid src/dst end-points packet" );
665
700
return NET_DROP ;
666
701
}
@@ -693,7 +728,7 @@ enum net_verdict net_conn_input(struct net_pkt *pkt,
693
728
net_conn_cb_t cb = NULL ;
694
729
void * user_data = NULL ;
695
730
696
- if (IS_ENABLED (CONFIG_NET_IP )) {
731
+ if (IS_ENABLED (CONFIG_NET_IP ) && ! raw_ip_pkt ) {
697
732
/* If we receive a packet with multicast destination address, we might
698
733
* need to deliver the packet to multiple recipients.
699
734
*/
@@ -736,7 +771,7 @@ enum net_verdict net_conn_input(struct net_pkt *pkt,
736
771
737
772
if (IS_ENABLED (CONFIG_NET_IPV4_MAPPING_TO_IPV6 )) {
738
773
if (!(conn -> family == AF_INET6 && pkt_family == AF_INET &&
739
- !conn -> v6only )) {
774
+ !conn -> v6only && conn -> type != SOCK_RAW )) {
740
775
continue ;
741
776
}
742
777
} else {
@@ -746,6 +781,11 @@ enum net_verdict net_conn_input(struct net_pkt *pkt,
746
781
/* We might have a match for v4-to-v6 mapping, check more */
747
782
}
748
783
784
+ if (IS_ENABLED (CONFIG_NET_SOCKETS_INET_RAW ) && raw_ip_pkt &&
785
+ conn -> type != SOCK_RAW ) {
786
+ continue ;
787
+ }
788
+
749
789
/* Is the candidate connection matching the packet's protocol within the family? */
750
790
if (conn -> proto != proto ) {
751
791
/* For packet socket data, the proto is set to ETH_P_ALL
@@ -757,6 +797,10 @@ enum net_verdict net_conn_input(struct net_pkt *pkt,
757
797
if (proto != ETH_P_ALL && proto != IPPROTO_RAW ) {
758
798
continue ; /* wrong protocol */
759
799
}
800
+ } else if (IS_ENABLED (CONFIG_NET_SOCKETS_INET_RAW ) && raw_ip_pkt ) {
801
+ if (conn -> proto != 0 ) {
802
+ continue ;
803
+ }
760
804
} else {
761
805
continue ; /* wrong protocol */
762
806
}
@@ -793,6 +837,15 @@ enum net_verdict net_conn_input(struct net_pkt *pkt,
793
837
794
838
continue ; /* packet was consumed */
795
839
}
840
+ } else if (IS_ENABLED (CONFIG_NET_SOCKETS_INET_RAW ) && raw_ip_pkt ) {
841
+ if ((conn -> flags & NET_CONN_LOCAL_ADDR_SET ) &&
842
+ !conn_addr_cmp (pkt , ip_hdr , & conn -> local_addr , false)) {
843
+ continue ; /* wrong local address */
844
+ }
845
+
846
+ conn_raw_ip_socket (pkt , conn );
847
+
848
+ continue ;
796
849
} else if ((IS_ENABLED (CONFIG_NET_UDP ) || IS_ENABLED (CONFIG_NET_TCP )) &&
797
850
(conn_family == AF_INET || conn_family == AF_INET6 ||
798
851
conn_family == AF_UNSPEC )) {
@@ -904,6 +957,11 @@ enum net_verdict net_conn_input(struct net_pkt *pkt,
904
957
}
905
958
}
906
959
960
+ if (IS_ENABLED (CONFIG_NET_SOCKETS_INET_RAW ) && raw_ip_pkt ) {
961
+ /* Raw IP packets are passed further in the stack regardless. */
962
+ return NET_CONTINUE ;
963
+ }
964
+
907
965
if (IS_ENABLED (CONFIG_NET_IP ) && is_mcast_pkt && mcast_pkt_delivered ) {
908
966
/* As one or more multicast packets
909
967
* have already been delivered in the loop above,
0 commit comments