@@ -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
15371536func (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+
15711641func LegacyContainerLinkOptions (parentEndpoints , childEndpoints []string ) map [string ]interface {} {
15721642 return options.Generic {
15731643 netlabel .GenericData : options.Generic {
0 commit comments