Skip to content

Commit a527e5a

Browse files
committed
Restore iptables for current networks on firewalld reload
Using iptables.OnReloaded to restore individual per-network rules on firewalld reload means rules for deleted networks pop back in to existence (because there was no way to delete the callbacks on network-delete). So, on firewalld reload, walk over current networks and ask them to restore their iptables rules. Signed-off-by: Rob Murray <[email protected]>
1 parent 9ba5c5d commit a527e5a

2 files changed

Lines changed: 77 additions & 22 deletions

File tree

libnetwork/drivers/bridge/bridge_linux.go

Lines changed: 77 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,7 @@ func (d *driver) configure(option map[string]interface{}) error {
544544
})
545545
}
546546
}
547+
iptables.OnReloaded(d.handleFirewalldReload)
547548

548549
var pdc portDriverClient
549550
if config.Rootless {
@@ -899,13 +900,6 @@ func (d *driver) createNetwork(config *networkConfiguration) (err error) {
899900
// Setup Loopback Addresses Routing
900901
{!d.config.EnableUserlandProxy, setupLoopbackAddressesRouting},
901902

902-
// We want to track firewalld configuration so that
903-
// if it is started/reloaded, the rules can be applied correctly
904-
{
905-
(config.EnableIPv4 && d.config.EnableIPTables) || (config.EnableIPv6 && d.config.EnableIP6Tables),
906-
network.setupFirewalld,
907-
},
908-
909903
// Setup DefaultGatewayIPv4
910904
{config.DefaultGatewayIPv4 != nil, setupGatewayIPv4},
911905

@@ -1475,6 +1469,11 @@ func (d *driver) ProgramExternalConnectivity(ctx context.Context, nid, eid strin
14751469
attribute.String("eid", eid)))
14761470
defer span.End()
14771471

1472+
// Make sure the network isn't deleted, or in the middle of a firewalld reload, while
1473+
// updating its iptables rules.
1474+
d.configNetwork.Lock()
1475+
defer d.configNetwork.Unlock()
1476+
14781477
network, err := d.getNetwork(nid)
14791478
if err != nil {
14801479
return err
@@ -1535,6 +1534,11 @@ func (d *driver) ProgramExternalConnectivity(ctx context.Context, nid, eid strin
15351534
}
15361535

15371536
func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
1537+
// Make sure this function isn't deleting iptables rules while handleFirewalldReloadNw
1538+
// is restoring those same rules.
1539+
d.configNetwork.Lock()
1540+
defer d.configNetwork.Unlock()
1541+
15381542
network, err := d.getNetwork(nid)
15391543
if err != nil {
15401544
return err
@@ -1568,6 +1572,72 @@ func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
15681572
return nil
15691573
}
15701574

1575+
func (d *driver) handleFirewalldReload() {
1576+
if !d.config.EnableIPTables && !d.config.EnableIP6Tables {
1577+
return
1578+
}
1579+
1580+
d.Lock()
1581+
nids := make([]string, 0, len(d.networks))
1582+
for _, nw := range d.networks {
1583+
nids = append(nids, nw.id)
1584+
}
1585+
d.Unlock()
1586+
1587+
for _, nid := range nids {
1588+
d.handleFirewalldReloadNw(nid)
1589+
}
1590+
}
1591+
1592+
func (d *driver) handleFirewalldReloadNw(nid string) {
1593+
d.Lock()
1594+
defer d.Unlock()
1595+
1596+
if !d.config.EnableIPTables && !d.config.EnableIP6Tables {
1597+
return
1598+
}
1599+
1600+
// Make sure the network isn't being deleted, and ProgramExternalConnectivity/RevokeExternalConnectivity
1601+
// aren't modifying iptables rules, while restoring the rules.
1602+
d.configNetwork.Lock()
1603+
defer d.configNetwork.Unlock()
1604+
1605+
nw, ok := d.networks[nid]
1606+
if !ok {
1607+
// Network deleted since the reload started, not an error.
1608+
return
1609+
}
1610+
1611+
if err := nw.iptablesNetwork.reapplyNetworkLevelRules(); err != nil {
1612+
log.G(context.Background()).WithFields(log.Fields{
1613+
"nid": nw.id,
1614+
"error": err,
1615+
}).Error("Failed to re-create packet filter on firewalld reload")
1616+
}
1617+
1618+
// Re-add legacy links - only added during ProgramExternalConnectivity, but legacy
1619+
// links are default-bridge-only, and it's not possible to connect a container to
1620+
// the default bridge and a user-defined network. So, the default bridge is always
1621+
// the gateway and, if there are legacy links configured they need to be set up.
1622+
if !nw.config.EnableICC {
1623+
for _, ep := range nw.endpoints {
1624+
if err := d.link(nw, ep, true); err != nil {
1625+
log.G(context.Background()).WithFields(log.Fields{
1626+
"nid": nw.id,
1627+
"eid": ep.id,
1628+
"error": err,
1629+
}).Error("Failed to re-create link on firewalld reload")
1630+
}
1631+
}
1632+
}
1633+
1634+
// Set up per-port rules. These are also only set up during ProgramExternalConnectivity
1635+
// but the network's port bindings are only configured when it's acting as the
1636+
// gateway network. So, this is a no-op for networks that aren't providing endpoints
1637+
// with the gateway.
1638+
nw.reapplyPerPortIptables()
1639+
}
1640+
15711641
func LegacyContainerLinkOptions(parentEndpoints, childEndpoints []string) map[string]interface{} {
15721642
return options.Generic{
15731643
netlabel.GenericData: options.Generic{

libnetwork/drivers/bridge/setup_firewalld.go

Lines changed: 0 additions & 15 deletions
This file was deleted.

0 commit comments

Comments
 (0)