Skip to content

Commit

Permalink
nftables: repeat deletion of remaining elements in case of error in a…
Browse files Browse the repository at this point in the history
… batch (ip already expired) (fix #230) (#279)
  • Loading branch information
mmetc committed May 11, 2023
1 parent 3c7c5ff commit b811ee5
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 13 deletions.
14 changes: 10 additions & 4 deletions pkg/nftables/nftables.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,18 @@ func (n *nft) commitDeletedDecisions() error {
}
}

if err := n.v4.deleteElements(ip4); err != nil {
return err
if len(ip4) > 0 {
log.Debugf("removing %d ip%s elements from set", len(ip4), n.v4.version)
if err := n.v4.deleteElements(ip4); err != nil {
return err
}
}

if err := n.v6.deleteElements(ip6); err != nil {
return err
if len(ip6) > 0 {
log.Debugf("removing %d ip%s elements from set", len(ip6), n.v6.version)
if err := n.v6.deleteElements(ip6); err != nil {
return err
}
}

return nil
Expand Down
40 changes: 31 additions & 9 deletions pkg/nftables/nftables_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ type nftContext struct {
setOnly bool
}

// convert a binary representation of an IP (4 or 16 bytes) to a string.
func reprIP(ip []byte) string {
return net.IP(ip).String()
}

func NewNFTV4Context(config *cfg.BouncerConfig) *nftContext {
if !*config.Nftables.Ipv4.Enabled {
log.Debug("nftables: ipv4 disabled")
Expand Down Expand Up @@ -272,19 +277,36 @@ func (c *nftContext) createRule(chain *nftables.Chain, set *nftables.Set,
return r
}

func (c *nftContext) deleteElements(els []nftables.SetElement) error {
for _, chunk := range slicetools.Chunks(els, chunkSize) {
log.Debugf("removing %d ip%s elements from set", len(chunk), c.version)

if err := c.conn.SetDeleteElements(c.set, chunk); err != nil {
return fmt.Errorf("failed to remove ip%s elements from set: %w", c.version, err)
func (c *nftContext) deleteElementChunk(els []nftables.SetElement) error {
if err := c.conn.SetDeleteElements(c.set, els); err != nil {
return fmt.Errorf("failed to remove ip%s elements from set: %w", c.version, err)
}
if err := c.conn.Flush(); err != nil {
if len(els) == 1 {
log.Debugf("deleting %s, failed to flush: %s", reprIP(els[0].Key), err)
return nil
}

if err := c.conn.Flush(); err != nil {
return fmt.Errorf("failed to flush ip%s conn: %w", c.version, err)
log.Infof("failed to flush chunk of %d elements, will retry each one: %s", len(els), err)
for _, el := range els {
if err := c.deleteElementChunk([]nftables.SetElement{el}); err != nil {
return err
}
}
}
return nil
}

func (c *nftContext) deleteElements(els []nftables.SetElement) error {
if len(els) <= chunkSize {
return c.deleteElementChunk(els)
}

log.Debugf("splitting %d elements into chunks of %d", len(els), chunkSize)
for _, chunk := range slicetools.Chunks(els, chunkSize) {
if err := c.deleteElementChunk(chunk); err != nil {
return err
}
}
return nil
}

Expand Down

0 comments on commit b811ee5

Please sign in to comment.