@@ -46,6 +46,11 @@ func (r *autoRedirect) setupNFTables() error {
4646 return err
4747 }
4848
49+ err = r .nftablesCreateLoopbackAddressSets (nft , table )
50+ if err != nil {
51+ return err
52+ }
53+
4954 skipOutput := len (r .tunOptions .IncludeInterface ) > 0 && ! common .Contains (r .tunOptions .IncludeInterface , "lo" ) || common .Contains (r .tunOptions .ExcludeInterface , "lo" )
5055 if ! skipOutput {
5156 chainOutput := nft .AddChain (& nftables.Chain {
@@ -61,8 +66,23 @@ func (r *autoRedirect) setupNFTables() error {
6166 return err
6267 }
6368 r .nftablesCreateUnreachable (nft , table , chainOutput )
64- r .nftablesCreateRedirect (nft , table , chainOutput )
65-
69+ err = r .nftablesCreateRedirect (nft , table , chainOutput )
70+ if err != nil {
71+ return err
72+ }
73+ if len (r .tunOptions .Inet4LoopbackAddress ) > 0 || len (r .tunOptions .Inet6LoopbackAddress ) > 0 {
74+ chainOutputRoute := nft .AddChain (& nftables.Chain {
75+ Name : "output_route" ,
76+ Table : table ,
77+ Hooknum : nftables .ChainHookOutput ,
78+ Priority : nftables .ChainPriorityMangle ,
79+ Type : nftables .ChainTypeRoute ,
80+ })
81+ err = r .nftablesCreateLoopbackReroute (nft , table , chainOutputRoute )
82+ if err != nil {
83+ return err
84+ }
85+ }
6686 chainOutputUDP := nft .AddChain (& nftables.Chain {
6787 Name : "output_udp_icmp" ,
6888 Table : table ,
@@ -77,14 +97,17 @@ func (r *autoRedirect) setupNFTables() error {
7797 r .nftablesCreateUnreachable (nft , table , chainOutputUDP )
7898 r .nftablesCreateMark (nft , table , chainOutputUDP )
7999 } else {
80- r .nftablesCreateRedirect (nft , table , chainOutput , & expr.Meta {
100+ err = r .nftablesCreateRedirect (nft , table , chainOutput , & expr.Meta {
81101 Key : expr .MetaKeyOIFNAME ,
82102 Register : 1 ,
83103 }, & expr.Cmp {
84104 Op : expr .CmpOpEq ,
85105 Register : 1 ,
86106 Data : nftablesIfname (r .tunOptions .Name ),
87107 })
108+ if err != nil {
109+ return err
110+ }
88111 }
89112 }
90113
@@ -100,12 +123,25 @@ func (r *autoRedirect) setupNFTables() error {
100123 return err
101124 }
102125 r .nftablesCreateUnreachable (nft , table , chainPreRouting )
103- r .nftablesCreateRedirect (nft , table , chainPreRouting )
104- if r . tunOptions . AutoRedirectMarkMode {
105- r . nftablesCreateMark ( nft , table , chainPreRouting )
126+ err = r .nftablesCreateRedirect (nft , table , chainPreRouting )
127+ if err != nil {
128+ return err
106129 }
107-
108130 if r .tunOptions .AutoRedirectMarkMode {
131+ r .nftablesCreateMark (nft , table , chainPreRouting )
132+ if len (r .tunOptions .Inet4LoopbackAddress ) > 0 || len (r .tunOptions .Inet6LoopbackAddress ) > 0 {
133+ chainPreRoutingFilter := nft .AddChain (& nftables.Chain {
134+ Name : "prerouting_filter" ,
135+ Table : table ,
136+ Hooknum : nftables .ChainHookPrerouting ,
137+ Priority : nftables .ChainPriorityRef (* nftables .ChainPriorityNATDest + 1 ),
138+ Type : nftables .ChainTypeFilter ,
139+ })
140+ err = r .nftablesCreateLoopbackReroute (nft , table , chainPreRoutingFilter )
141+ if err != nil {
142+ return err
143+ }
144+ }
109145 chainPreRoutingUDP := nft .AddChain (& nftables.Chain {
110146 Name : "prerouting_udp" ,
111147 Table : table ,
0 commit comments