@@ -46,6 +46,11 @@ func (r *autoRedirect) setupNFTables() error {
4646 return err
4747 }
4848
49+ err = r .nftablesCreateLocalRedirectAddressSets (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 .Inet4LocalRedirectAddress ) > 0 || len (r .tunOptions .Inet6LocalRedirectAddress ) > 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 .nftablesCreateLocalRedirectReroute (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,11 +123,26 @@ func (r *autoRedirect) setupNFTables() error {
100123 return err
101124 }
102125 r .nftablesCreateUnreachable (nft , table , chainPreRouting )
103- r .nftablesCreateRedirect (nft , table , chainPreRouting )
126+ err = r .nftablesCreateRedirect (nft , table , chainPreRouting )
127+ if err != nil {
128+ return err
129+ }
104130 if r .tunOptions .AutoRedirectMarkMode {
105131 r .nftablesCreateMark (nft , table , chainPreRouting )
106132 }
107-
133+ if r .tunOptions .AutoRedirectMarkMode && (len (r .tunOptions .Inet4LocalRedirectAddress ) > 0 || len (r .tunOptions .Inet6LocalRedirectAddress ) > 0 ) {
134+ chainPreRoutingFilter := nft .AddChain (& nftables.Chain {
135+ Name : "prerouting_filter" ,
136+ Table : table ,
137+ Hooknum : nftables .ChainHookPrerouting ,
138+ Priority : nftables .ChainPriorityRef (* nftables .ChainPriorityNATDest + 1 ),
139+ Type : nftables .ChainTypeFilter ,
140+ })
141+ err = r .nftablesCreateLocalRedirectReroute (nft , table , chainPreRoutingFilter )
142+ if err != nil {
143+ return err
144+ }
145+ }
108146 if r .tunOptions .AutoRedirectMarkMode {
109147 chainPreRoutingUDP := nft .AddChain (& nftables.Chain {
110148 Name : "prerouting_udp" ,
0 commit comments