mobile: assume IFF_NOARP when given a /32 prefix

Trying to ARP with no other machines in the broadcast domain
is pretty pointless, and in many cases doesn't work (ZTE MF691
/T-Mobile Rocket 2), so turn it off.
This commit is contained in:
Dan Williams 2012-11-20 17:54:04 -06:00
parent 2a1481112c
commit d3e4930177
5 changed files with 76 additions and 0 deletions

View file

@ -311,6 +311,27 @@ nm_modem_stage3_ip4_config_start (NMModem *self,
return ret;
}
void
nm_modem_ip4_pre_commit (NMModem *modem,
NMDevice *device,
NMIP4Config *config)
{
NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (modem);
/* If the modem has an ethernet-type data interface (ie, not PPP and thus
* not point-to-point) and IP config has a /32 prefix, then we assume that
* ARP will be pointless and we turn it off.
*/
if ( priv->ip_method == MM_MODEM_IP_METHOD_STATIC
|| priv->ip_method == MM_MODEM_IP_METHOD_DHCP) {
NMIP4Address *addr = nm_ip4_config_get_address (config, 0);
g_assert (addr);
if (nm_ip4_address_get_prefix (addr) == 32)
nm_system_iface_set_arp (nm_device_get_ip_ifindex (device), FALSE);
}
}
/*****************************************************************************/
NMActStageReturn

View file

@ -148,6 +148,8 @@ NMActStageReturn nm_modem_stage3_ip6_config_start (NMModem *modem,
NMDeviceClass *device_class,
NMDeviceStateReason *reason);
void nm_modem_ip4_pre_commit (NMModem *modem, NMDevice *device, NMIP4Config *config);
gboolean nm_modem_get_secrets (NMModem *modem,
const char *setting_name,
gboolean request_new,

View file

@ -309,6 +309,12 @@ act_stage3_ip4_config_start (NMDevice *device,
reason);
}
static void
ip4_config_pre_commit (NMDevice *device, NMIP4Config *config)
{
nm_modem_ip4_pre_commit (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, device, config);
}
static NMActStageReturn
act_stage3_ip6_config_start (NMDevice *device,
NMIP6Config **out_config,
@ -509,6 +515,7 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass)
device_class->act_stage2_config = act_stage2_config;
device_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start;
device_class->act_stage3_ip6_config_start = act_stage3_ip6_config_start;
device_class->ip4_config_pre_commit = ip4_config_pre_commit;
device_class->get_enabled = get_enabled;
device_class->set_enabled = set_enabled;

View file

@ -896,6 +896,50 @@ out:
return success;
}
/**
* nm_system_iface_set_arp:
* @ifindex: interface index
* @enable: %TRUE to enable ARP, or %FALSE to disable
*
* Sets a flag to indicate that ARP should or should not be used on the
* interface. Point-to-point or IPv4 /32 interfaces often require that ARP
* be disabled.
*
* Returns: %TRUE on success, %FALSE on failure
**/
gboolean
nm_system_iface_set_arp (int ifindex, gboolean enable)
{
struct rtnl_link *request = NULL, *old = NULL;
struct nl_sock *nlh;
gboolean success = FALSE;
int err;
g_return_val_if_fail (ifindex > 0, FALSE);
if (!(request = rtnl_link_alloc ()))
return FALSE;
if (enable)
rtnl_link_unset_flags (request, IFF_NOARP);
else
rtnl_link_set_flags (request, IFF_NOARP);
old = nm_netlink_index_to_rtnl_link (ifindex);
if (old) {
nlh = nm_netlink_get_default_handle ();
if (nlh) {
err = rtnl_link_change (nlh, old, request, 0);
if (err == 0)
success = TRUE;
}
}
rtnl_link_put (old);
rtnl_link_put (request);
return success;
}
static struct rtnl_route *
add_ip4_route_to_gateway (int ifindex, guint32 gw, guint32 mss)
{

View file

@ -94,6 +94,8 @@ gboolean nm_system_iface_set_mtu (int ifindex, guint32 mtu);
gboolean nm_system_iface_set_mac (int ifindex, const struct ether_addr *mac);
gboolean nm_system_iface_set_arp (int ifindex, gboolean arp);
gboolean nm_system_apply_bonding_config (const char *iface,
NMSettingBond *s_bond);
gboolean nm_system_add_bonding_master (const char *iface);