@@ -201,8 +201,7 @@ func (p *Protocol) updateTable(nft *nftables.NFTables, tab *nftables.Table, attr
201201// getTable returns a table for the given family.
202202func (p * Protocol ) getTable (nft * nftables.NFTables , attrs map [uint16 ]nlmsg.BytesView , family stack.AddressFamily , msgFlags uint16 , ms * nlmsg.MessageSet ) * syserr.AnnotatedError {
203203 if (msgFlags & linux .NLM_F_DUMP ) != 0 {
204- // TODO: b/434242152 - Support dump requests for tables.
205- return syserr .NewAnnotatedError (syserr .ErrNotSupported , fmt .Sprintf ("Nftables: Table dump is not currently supported" ))
204+ return dumpTables (nft , family , ms )
206205 }
207206
208207 // The table name is required.
@@ -218,18 +217,54 @@ func (p *Protocol) getTable(nft *nftables.NFTables, attrs map[uint16]nlmsg.Bytes
218217 return err
219218 }
220219
220+ return fillTableInfo (tab , ms )
221+ }
222+
223+ // dumpTablesForFamily populates the message set with information about all tables
224+ // for a specific address family.
225+ func dumpTablesForFamily (nft * nftables.NFTables , family stack.AddressFamily , ms * nlmsg.MessageSet ) * syserr.AnnotatedError {
226+ for _ , tab := range nft .GetAddressFamilyTables (family ) {
227+ if err := fillTableInfo (tab , ms ); err != nil {
228+ return err
229+ }
230+ }
231+
232+ return nil
233+ }
234+
235+ // dumpTables populates the message set with information about all tables for
236+ // all address families.
237+ func dumpTables (nft * nftables.NFTables , family stack.AddressFamily , ms * nlmsg.MessageSet ) * syserr.AnnotatedError {
238+ // Dumps are multi-part messages.
239+ ms .Multi = true
240+ if family != stack .Unspec {
241+ return dumpTablesForFamily (nft , family , ms )
242+ }
243+
244+ for family := range stack .NumAFs {
245+ if err := dumpTablesForFamily (nft , family , ms ); err != nil {
246+ return err
247+ }
248+ }
249+
250+ return nil
251+ }
252+
253+ // fillTableInfo populates the message set with information about a table.
254+ func fillTableInfo (tab * nftables.Table , ms * nlmsg.MessageSet ) * syserr.AnnotatedError {
221255 tabName := tab .GetName ()
222256 userFlags , err := tab .GetLinuxUserFlagSet ()
223257 if err != nil {
224258 return err
225259 }
260+
226261 // From net/netfilter/nf_tables_api.c:nf_tables_gettable
227262 m := ms .AddMessage (linux.NetlinkMessageHeader {
228263 Type : uint16 (linux .NFNL_SUBSYS_NFTABLES )<< 8 | uint16 (linux .NFT_MSG_NEWTABLE ),
229264 })
230265
231266 m .Put (& linux.NetFilterGenMsg {
232- Family : uint8 (family ),
267+ Family : uint8 (nftables . AfProtocol ( tab . GetAddressFamily ()) ),
233268 Version : uint8 (linux .NFNETLINK_V0 ),
234269 // Unused, set to 0.
235270 ResourceID : uint16 (0 ),
@@ -548,8 +583,7 @@ func (p *Protocol) chainParseHook(chain *nftables.Chain, family stack.AddressFam
548583// getChain fills the message set with information about a chain.
549584func (p * Protocol ) getChain (nft * nftables.NFTables , attrs map [uint16 ]nlmsg.BytesView , family stack.AddressFamily , msgFlags uint16 , ms * nlmsg.MessageSet ) * syserr.AnnotatedError {
550585 if (msgFlags & linux .NLM_F_DUMP ) != 0 {
551- // TODO: b/434243967 - Support dump requests for chains.
552- return syserr .NewAnnotatedError (syserr .ErrNotSupported , fmt .Sprintf ("Nftables: Chain dump is not currently supported" ))
586+ return dumpChains (nft , family , ms )
553587 }
554588
555589 tabNameBytes , ok := attrs [linux .NFTA_CHAIN_TABLE ]
@@ -577,22 +611,57 @@ func (p *Protocol) getChain(nft *nftables.NFTables, attrs map[uint16]nlmsg.Bytes
577611 return err
578612 }
579613
614+ return fillChainInfo (chain , ms )
615+ }
616+
617+ // dumpChainsForFamily populates the message set with information about all
618+ // chains for a specific address family.
619+ func dumpChainsForFamily (nft * nftables.NFTables , family stack.AddressFamily , ms * nlmsg.MessageSet ) * syserr.AnnotatedError {
620+ for _ , tab := range nft .GetAddressFamilyTables (family ) {
621+ for _ , chain := range tab .GetChains () {
622+ if err := fillChainInfo (chain , ms ); err != nil {
623+ return err
624+ }
625+ }
626+ }
627+ return nil
628+ }
629+
630+ // dumpChains populates the message set with information chains. If no address
631+ // family is specified, all address families are dumped.
632+ func dumpChains (nft * nftables.NFTables , family stack.AddressFamily , ms * nlmsg.MessageSet ) * syserr.AnnotatedError {
633+ ms .Multi = true
634+ if family != stack .Unspec {
635+ return dumpChainsForFamily (nft , family , ms )
636+ }
637+
638+ for family := range stack .NumAFs {
639+ if err := dumpChainsForFamily (nft , family , ms ); err != nil {
640+ return err
641+ }
642+ }
643+
644+ return nil
645+ }
646+
647+ // fillChainInfo populates the message set with information about a chain.
648+ func fillChainInfo (chain * nftables.Chain , ms * nlmsg.MessageSet ) * syserr.AnnotatedError {
580649 m := ms .AddMessage (linux.NetlinkMessageHeader {
581650 Type : uint16 (linux .NFNL_SUBSYS_NFTABLES )<< 8 | uint16 (linux .NFT_MSG_NEWCHAIN ),
582651 })
583652
584653 m .Put (& linux.NetFilterGenMsg {
585- Family : uint8 (family ),
654+ Family : uint8 (nftables . AfProtocol ( chain . GetAddressFamily ()) ),
586655 Version : uint8 (linux .NFNETLINK_V0 ),
587656 // Unused, set to 0.
588657 ResourceID : uint16 (0 ),
589658 })
590- m .PutAttrString (linux .NFTA_CHAIN_TABLE , tabName )
591- m .PutAttrString (linux .NFTA_CHAIN_NAME , chainName )
659+ m .PutAttrString (linux .NFTA_CHAIN_TABLE , chain . GetTable (). GetName () )
660+ m .PutAttrString (linux .NFTA_CHAIN_NAME , chain . GetName () )
592661 m .PutAttr (linux .NFTA_CHAIN_HANDLE , nlmsg .PutU64 (chain .GetHandle ()))
593662
594663 if chain .IsBaseChain () {
595- err := getBaseChainHookInfo (chain , family , m )
664+ err := getBaseChainHookInfo (chain , m )
596665 if err != nil {
597666 return err
598667 }
@@ -884,14 +953,14 @@ func nlaType(hdr linux.NetlinkAttrHeader) uint16 {
884953
885954// getBaseChainHookInfo creates a NFTA_CHAIN_HOOK attribute with all the
886955// corresponding nested attributes.
887- func getBaseChainHookInfo (chain * nftables.Chain , family stack. AddressFamily , m * nlmsg.Message ) * syserr.AnnotatedError {
956+ func getBaseChainHookInfo (chain * nftables.Chain , m * nlmsg.Message ) * syserr.AnnotatedError {
888957 baseChainInfo := chain .GetBaseChainInfo ()
889958 var nestedAttrs nlmsg.NestedAttr
890959
891960 nestedAttrs .PutAttr (linux .NFTA_HOOK_HOOKNUM , nlmsg .PutU32 (baseChainInfo .LinuxHookNum ))
892961 nestedAttrs .PutAttr (linux .NFTA_HOOK_PRIORITY , nlmsg .PutU32 (uint32 (baseChainInfo .Priority .GetValue ())))
893962
894- if isNetDevHook (family , baseChainInfo .LinuxHookNum ) {
963+ if isNetDevHook (chain . GetAddressFamily () , baseChainInfo .LinuxHookNum ) {
895964 return syserr .NewAnnotatedError (syserr .ErrNotSupported , fmt .Sprintf ("Nftables: Netdev basechains or basechains attached to Ingress or Egress are not currently supported for getting" ))
896965 }
897966
0 commit comments