@@ -529,16 +529,27 @@ func (e *endpoint) WritePacket(r *stack.Route, params stack.NetworkHeaderParams,
529529func (e * endpoint ) writePacket (r * stack.Route , pkt * stack.PacketBuffer ) tcpip.Error {
530530 netHeader := header .IPv4 (pkt .NetworkHeader ().Slice ())
531531 dstAddr := netHeader .DestinationAddress ()
532+ stk := e .protocol .stack
532533
533- // iptables filtering. All packets that reach here are locally
534- // generated.
535- outNicName := e .protocol .stack .FindNICNameFromID (e .nic .ID ())
536- if ok := e .protocol .stack .IPTables ().CheckOutput (pkt , r , outNicName ); ! ok {
534+ // iptables filtering. All packets that reach here are locally generated.
535+ outNicName := stk .FindNICNameFromID (e .nic .ID ())
536+ if ok := stk .IPTables ().CheckOutput (pkt , r , outNicName ); ! ok {
537537 // iptables is telling us to drop the packet.
538538 e .stats .ip .IPTablesOutputDropped .Increment ()
539539 return nil
540540 }
541541
542+ if nft := stk .NFTables (); nft != nil && stk .IsNFTablesConfigured () {
543+ ipCheck := nft .CheckOutput (pkt , stack .IP )
544+ // nftables allows us to use the inet family to apply rules to both IPv4
545+ // and IPv6 packets.
546+ inetCheck := nft .CheckOutput (pkt , stack .Inet )
547+ if ! ipCheck || ! inetCheck {
548+ // nftables is telling us to drop the packet.
549+ return nil
550+ }
551+ }
552+
542553 // If the packet is manipulated as per DNAT Output rules, handle packet
543554 // based on destination address and do not send the packet to link
544555 // layer.
@@ -569,15 +580,25 @@ func (e *endpoint) writePacketPostRouting(r *stack.Route, pkt *stack.PacketBuffe
569580 return nil
570581 }
571582
583+ stk := e .protocol .stack
572584 // Postrouting NAT can only change the source address, and does not alter the
573585 // route or outgoing interface of the packet.
574- outNicName := e . protocol . stack .FindNICNameFromID (e .nic .ID ())
575- if ok := e . protocol . stack .IPTables ().CheckPostrouting (pkt , r , e , outNicName ); ! ok {
586+ outNicName := stk .FindNICNameFromID (e .nic .ID ())
587+ if ok := stk .IPTables ().CheckPostrouting (pkt , r , e , outNicName ); ! ok {
576588 // iptables is telling us to drop the packet.
577589 e .stats .ip .IPTablesPostroutingDropped .Increment ()
578590 return nil
579591 }
580592
593+ if nft := stk .NFTables (); nft != nil && stk .IsNFTablesConfigured () {
594+ ipCheck := nft .CheckOutput (pkt , stack .IP )
595+ inetCheck := nft .CheckOutput (pkt , stack .Inet )
596+ if ! ipCheck || ! inetCheck {
597+ // nftables is telling us to drop the packet.
598+ return nil
599+ }
600+ }
601+
581602 stats := e .stats .ip
582603
583604 networkMTU , err := calculateNetworkMTU (e .nic .MTU (), uint32 (len (pkt .NetworkHeader ().Slice ())))
@@ -688,6 +709,15 @@ func (e *endpoint) forwardPacketWithRoute(route *stack.Route, pkt *stack.PacketB
688709 return nil
689710 }
690711
712+ if nft := stk .NFTables (); nft != nil && stk .IsNFTablesConfigured () {
713+ ipCheck := nft .CheckForward (pkt , stack .IP )
714+ inetCheck := nft .CheckForward (pkt , stack .Inet )
715+ if ! ipCheck || ! inetCheck {
716+ // nftables is telling us to drop the packet.
717+ return nil
718+ }
719+ }
720+
691721 // We need to do a deep copy of the IP packet because
692722 // WriteHeaderIncludedPacket may modify the packet buffer, but we do
693723 // not own it.
@@ -788,6 +818,15 @@ func (e *endpoint) forwardUnicastPacket(pkt *stack.PacketBuffer) ip.ForwardingEr
788818 return nil
789819 }
790820
821+ if nft := stk .NFTables (); nft != nil && stk .IsNFTablesConfigured () {
822+ ipCheck := nft .CheckForward (pkt , stack .IP )
823+ inetCheck := nft .CheckForward (pkt , stack .Inet )
824+ if ! ipCheck || ! inetCheck {
825+ // nftables is telling us to drop the packet.
826+ return nil
827+ }
828+ }
829+
791830 // The packet originally arrived on e so provide its NIC as the input NIC.
792831 ep .handleValidatedPacket (h , pkt , e .nic .Name () /* inNICName */ )
793832 return nil
@@ -855,7 +894,8 @@ func (e *endpoint) HandlePacket(pkt *stack.PacketBuffer) {
855894 }
856895 }
857896
858- if e .protocol .stack .HandleLocal () {
897+ stk := e .protocol .stack
898+ if stk .HandleLocal () {
859899 addressEndpoint := e .AcquireAssignedAddress (header .IPv4 (pkt .NetworkHeader ().Slice ()).SourceAddress (), e .nic .Promiscuous (), stack .CanBePrimaryEndpoint , true /* readOnly */ )
860900 if addressEndpoint != nil {
861901 // The source address is one of our own, so we never should have gotten
@@ -867,12 +907,21 @@ func (e *endpoint) HandlePacket(pkt *stack.PacketBuffer) {
867907 }
868908
869909 // Loopback traffic skips the prerouting chain.
870- inNicName := e . protocol . stack .FindNICNameFromID (e .nic .ID ())
871- if ok := e . protocol . stack .IPTables ().CheckPrerouting (pkt , e , inNicName ); ! ok {
910+ inNicName := stk .FindNICNameFromID (e .nic .ID ())
911+ if ok := stk .IPTables ().CheckPrerouting (pkt , e , inNicName ); ! ok {
872912 // iptables is telling us to drop the packet.
873913 stats .IPTablesPreroutingDropped .Increment ()
874914 return
875915 }
916+
917+ if nft := stk .NFTables (); nft != nil && stk .IsNFTablesConfigured () {
918+ ipCheck := nft .CheckPrerouting (pkt , stack .IP )
919+ inetCheck := nft .CheckPrerouting (pkt , stack .Inet )
920+ if ! ipCheck || ! inetCheck {
921+ // nftables is telling us to drop the packet.
922+ return
923+ }
924+ }
876925 }
877926 // CheckPrerouting can modify the backing storage of the packet, so refresh
878927 // the header.
@@ -1206,14 +1255,24 @@ func (e *endpoint) handleForwardingError(err ip.ForwardingError) {
12061255
12071256func (e * endpoint ) deliverPacketLocally (h header.IPv4 , pkt * stack.PacketBuffer , inNICName string ) {
12081257 stats := e .stats
1258+ stk := e .protocol .stack
12091259 // iptables filtering. All packets that reach here are intended for
12101260 // this machine and will not be forwarded.
1211- if ok := e . protocol . stack .IPTables ().CheckInput (pkt , inNICName ); ! ok {
1261+ if ok := stk .IPTables ().CheckInput (pkt , inNICName ); ! ok {
12121262 // iptables is telling us to drop the packet.
12131263 stats .ip .IPTablesInputDropped .Increment ()
12141264 return
12151265 }
12161266
1267+ if nft := stk .NFTables (); nft != nil && stk .IsNFTablesConfigured () {
1268+ ipCheck := nft .CheckInput (pkt , stack .IP )
1269+ inetCheck := nft .CheckInput (pkt , stack .Inet )
1270+ if ! ipCheck || ! inetCheck {
1271+ // nftables is telling us to drop the packet.
1272+ return
1273+ }
1274+ }
1275+
12171276 if h .More () || h .FragmentOffset () != 0 {
12181277 if pkt .Data ().Size ()+ len (pkt .TransportHeader ().Slice ()) == 0 {
12191278 // Drop the packet as it's marked as a fragment but has
0 commit comments