@@ -61,8 +61,23 @@ func (r *autoRedirect) setupNFTables() error {
6161 return err
6262 }
6363 r .nftablesCreateUnreachable (nft , table , chainOutput )
64- r .nftablesCreateRedirect (nft , table , chainOutput )
65-
64+ err = r .nftablesCreateRedirect (nft , table , chainOutput )
65+ if err != nil {
66+ return err
67+ }
68+ if len (r .tunOptions .Inet4LocalRedirectAddress ) > 0 || len (r .tunOptions .Inet6LocalRedirectAddress ) > 0 {
69+ chainOutputRoute := nft .AddChain (& nftables.Chain {
70+ Name : "output_route" ,
71+ Table : table ,
72+ Hooknum : nftables .ChainHookOutput ,
73+ Priority : nftables .ChainPriorityMangle ,
74+ Type : nftables .ChainTypeRoute ,
75+ })
76+ err = r .nftablesCreateLocalRedirectReroute (nft , table , chainOutputRoute )
77+ if err != nil {
78+ return err
79+ }
80+ }
6681 chainOutputUDP := nft .AddChain (& nftables.Chain {
6782 Name : "output_udp_icmp" ,
6883 Table : table ,
@@ -77,14 +92,17 @@ func (r *autoRedirect) setupNFTables() error {
7792 r .nftablesCreateUnreachable (nft , table , chainOutputUDP )
7893 r .nftablesCreateMark (nft , table , chainOutputUDP )
7994 } else {
80- r .nftablesCreateRedirect (nft , table , chainOutput , & expr.Meta {
95+ err = r .nftablesCreateRedirect (nft , table , chainOutput , & expr.Meta {
8196 Key : expr .MetaKeyOIFNAME ,
8297 Register : 1 ,
8398 }, & expr.Cmp {
8499 Op : expr .CmpOpEq ,
85100 Register : 1 ,
86101 Data : nftablesIfname (r .tunOptions .Name ),
87102 })
103+ if err != nil {
104+ return err
105+ }
88106 }
89107 }
90108
@@ -100,11 +118,26 @@ func (r *autoRedirect) setupNFTables() error {
100118 return err
101119 }
102120 r .nftablesCreateUnreachable (nft , table , chainPreRouting )
103- r .nftablesCreateRedirect (nft , table , chainPreRouting )
121+ err = r .nftablesCreateRedirect (nft , table , chainPreRouting )
122+ if err != nil {
123+ return err
124+ }
104125 if r .tunOptions .AutoRedirectMarkMode {
105126 r .nftablesCreateMark (nft , table , chainPreRouting )
106127 }
107-
128+ if r .tunOptions .AutoRedirectMarkMode && (len (r .tunOptions .Inet4LocalRedirectAddress ) > 0 || len (r .tunOptions .Inet6LocalRedirectAddress ) > 0 ) {
129+ chainPreRoutingFilter := nft .AddChain (& nftables.Chain {
130+ Name : "prerouting_filter" ,
131+ Table : table ,
132+ Hooknum : nftables .ChainHookPrerouting ,
133+ Priority : nftables .ChainPriorityRef (* nftables .ChainPriorityNATDest + 1 ),
134+ Type : nftables .ChainTypeFilter ,
135+ })
136+ err = r .nftablesCreateLocalRedirectReroute (nft , table , chainPreRoutingFilter )
137+ if err != nil {
138+ return err
139+ }
140+ }
108141 if r .tunOptions .AutoRedirectMarkMode {
109142 chainPreRoutingUDP := nft .AddChain (& nftables.Chain {
110143 Name : "prerouting_udp" ,
0 commit comments