Unexpected behavior of `AdditionalRoutes` property in DynamicStore

Hello,

I experienced a strange (and in my opinion unexpected) behavior from DynamicStore/configd.

In our application we setup the routes in the system by setting AdditionalRoutes property on a specific interface to route part of the network traffic through it.

The routes are set properly, but I noticed that the they are not cleared once removed from AdditionalRoutes. After a while I figured, that the problem lies in the DestinationAddress I set in AdditionalRoutes. I was using the following configuration:

var newRoutes: [[String: NSObject]] = [
    ["DestinationAddress": "10.0.0.1" as NSObject,
     "SubnetMask": "255.0.0.0" as NSObject ]
]

and it resulted in a new route:

10                 link#16            UCS               en0      !

which was not cleared when AdditionalRoutes were reset to the original value. When I changed the DestinationAddress to:

var newRoutes: [[String: NSObject]] = [
    ["DestinationAddress": "10.0.0.0" as NSObject,
     "SubnetMask": "255.0.0.0" as NSObject ]
]

both, setting and clearing routes works as expected. The only difference is changing the DestinationAddress from 10.0.0.1 to 10.0.0.1.

In my opinion this incosistent behavior. Although I can understand that the system might reject 10.0.0.1 as a valid DestinationAddress for creating routes, I don't think it's correct behavior to accept such address, but never clear the routes.

The full source code which might be used to verify my claims:

import Foundation
import SystemConfiguration

let en0ServiceIPv4 = "State:/Network/Service/***/IPv4" as CFString

let store = SCDynamicStoreCreate(nil, "dseditor" as CFString, nil, nil)!
let originalValue = SCDynamicStoreCopyValue(store, en0ServiceIPv4) as! [String: NSObject]
var newValue = originalValue

print("AdditionalRoutes: \(String(describing: originalValue["AdditionalRoutes"]))")

var newRoutes: [[String: NSObject]] = [
    ["DestinationAddress": "10.0.0.1" as NSObject,
     "SubnetMask": "255.0.0.0" as NSObject ]
]
newValue["AdditionalRoutes"] = newRoutes as NSObject

print("newValue: \(newValue)")

var result = SCDynamicStoreSetValue(store, en0ServiceIPv4, newValue as CFPropertyList)

print("set new value: \(result)")
sleep(3)

result = SCDynamicStoreSetValue(store, en0ServiceIPv4, originalValue as CFPropertyList)
print("restore old value: \(result)")

Naturally, the en0ServiceIPv4 needs to be changed and the program needs to be run as root.

Can you please share your thoughts, if this is an OS bug or expected behavior? If it is expected, what is the reasoning behind it?

Replies

In our application we setup the routes in the system by setting AdditionalRoutes property on a specific interface to route part of the network traffic through it.

Just so we’re clear, you’re writing values to the State: domain in the dynamic store?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Yes, exactly, to this particular key:

let en0ServiceIPv4 = "State:/Network/Service/***/IPv4" as CFString

Naturally, *** are replaced with my device id.

Yes, exactly

OK, that’s not something we support. The State: domain is meant to be the dynamic store projection of the preferences (SCPreferences). Modifying it directly is not going to end well.

To advise you further I need some high-level info about your product. What does it actually do?

ps I want to make sure you’ve read System Configuration Programming Guidelines. It’s in the Documentation Archive, so folks often miss it, but it’s critical to understanding how this stuff works.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks for your quick reply! I will take a look at the documentation you provided and see if that helps.

Anyway, for now it seems it's not a bug since you do not support modifying State domain directly.