Skip to content

Commit

Permalink
Make table index part of the IP-rule definition.
Browse files Browse the repository at this point in the history
When wwan modem is reset by ModemManager (because it is not responsive),
the wwan interface is recreated and will get a different interface
index. This means that the target routing table index for the port
(calculated as 500 + interface index) will change. However, if the IP
address assigned by the network is the same after the reset (common in
private LTE networks), then only the table index needs to be updated in
the corresponding IP rule. But this will be missed because table index
is not part of the IP rule definition (SrcIPRule struct) and instead it
is calculated on-demand inside the Create/Modify method of the configurator.
As a result, there is no change detected by the SrcIPRule.Equal() method
between the current and the new intended state, hence Modify method is
not called by the reconciler and IP rule is not updated after modem
reset.

In this commit this is fixed by adding the table ID into the IP rule
definition.

In theory, this can also affect wlan or eth interface if there is e.g.
a driver reset and the interface is recreated (while getting the same
IP). However, with cellular modems this is more likely because they
are quite flaky and ModemManager resets them when they get stuck.

Signed-off-by: Milan Lenco <milan@zededa.com>
(cherry picked from commit 695652b)
  • Loading branch information
milan-zededa committed Aug 19, 2024
1 parent 63ef1c8 commit b1597f7
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 18 deletions.
1 change: 1 addition & 0 deletions pkg/pillar/dpcreconciler/linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,7 @@ func (r *LinuxDpcReconciler) getIntendedSrcIPRules(dpc types.DevicePortConfig) d
AdapterIfName: port.IfName,
IPAddr: ipAddr.IP,
Priority: devicenetwork.PbrLocalOrigPrio,
Table: devicenetwork.DPCBaseRTIndex + ifIndex,
}, nil)
}
}
Expand Down
23 changes: 5 additions & 18 deletions pkg/pillar/dpcreconciler/linuxitems/srciprule.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (

"github.com/lf-edge/eve-libs/depgraph"
"github.com/lf-edge/eve/pkg/pillar/base"
"github.com/lf-edge/eve/pkg/pillar/devicenetwork"
"github.com/lf-edge/eve/pkg/pillar/dpcreconciler/genericitems"
"github.com/lf-edge/eve/pkg/pillar/netmonitor"
"github.com/lf-edge/eve/pkg/pillar/utils/netutils"
Expand All @@ -25,6 +24,7 @@ type SrcIPRule struct {
AdapterIfName string
IPAddr net.IP
Priority int
Table int
}

// Name combines interface name with the IP address to construct
Expand All @@ -46,7 +46,7 @@ func (r SrcIPRule) Type() string {
// Equal is a comparison method for two equally-named src-IP-rule instances.
func (r SrcIPRule) Equal(other depgraph.Item) bool {
r2 := other.(SrcIPRule)
return r.Priority == r2.Priority
return r.Priority == r2.Priority && r.Table == r2.Table
}

// External returns false.
Expand All @@ -57,8 +57,8 @@ func (r SrcIPRule) External() bool {
// String describes source-based IP rule.
func (r SrcIPRule) String() string {
return fmt.Sprintf("Source-based IP rule: "+
"{adapter: %s, ifName: %s, ip: %s, prio: %d}",
r.AdapterLL, r.AdapterIfName, r.IPAddr, r.Priority)
"{adapter: %s, ifName: %s, ip: %s, prio: %d, table: %d}",
r.AdapterLL, r.AdapterIfName, r.IPAddr, r.Priority, r.Table)
}

// Dependencies lists the referenced adapter as the only dependency.
Expand Down Expand Up @@ -94,20 +94,7 @@ func (c *SrcIPRuleConfigurator) Create(ctx context.Context, item depgraph.Item)

func (c *SrcIPRuleConfigurator) makeNetlinkRule(rule SrcIPRule) (*netlink.Rule, error) {
r := netlink.NewRule()
ifIdx, exists, err := c.NetworkMonitor.GetInterfaceIndex(rule.AdapterIfName)
if !exists {
// Dependencies should prevent this.
err := fmt.Errorf("missing interface %s", rule.AdapterIfName)
c.Log.Error()
return nil, err
}
if err != nil {
err := fmt.Errorf("GetInterfaceIndex(%s) failed: %v",
rule.AdapterIfName, err)
c.Log.Error()
return nil, err
}
r.Table = devicenetwork.DPCBaseRTIndex + ifIdx
r.Table = rule.Table
r.Priority = rule.Priority
r.Family = netutils.HostFamily(rule.IPAddr)
r.Src = netutils.HostSubnet(rule.IPAddr)
Expand Down

0 comments on commit b1597f7

Please sign in to comment.