static void
vlan_settings_changed (GObject    *object,
                       GParamSpec *pspec,
                       gpointer    user_data)
{
	NMEditorVlanWidgetBinding *binding = user_data;
	const char *ifname, *parent;
	char *ifname_parent;
	int ifname_id, id;

	if (binding->updating)
		return;

	ifname = nm_setting_connection_get_interface_name (binding->s_con);
	parent = nm_setting_vlan_get_parent (binding->s_vlan);
	id = nm_setting_vlan_get_id (binding->s_vlan);

	if (!parse_interface_name (ifname, &ifname_parent, &ifname_id))
		return;

	/* If the id in INTERFACE_NAME changed, and ID is either unset, or was previously
	 * in sync with INTERFACE_NAME, then update ID.
	 */
	if (   id != ifname_id
	    && (id == binding->last_ifname_id || id == 0)) {
		binding->updating = TRUE;
		g_object_set (G_OBJECT (binding->s_vlan),
		              NM_SETTING_VLAN_ID, ifname_id,
		              NULL);
		binding->updating = FALSE;
	}

	/* If the PARENT in INTERFACE_NAME changed, and PARENT is either unset, or was
	 * previously in sync with INTERFACE_NAME, then update PARENT.
	 */
	if (   g_strcmp0 (parent, ifname_parent) != 0
	    && (   g_strcmp0 (parent, binding->last_ifname_parent) == 0
	        || !parent || !*parent)) {
		binding->updating = TRUE;
		g_object_set (G_OBJECT (binding->s_vlan),
		              NM_SETTING_VLAN_PARENT, ifname_parent,
		              NULL);
		binding->updating = FALSE;
	}

	g_free (binding->last_ifname_parent);
	binding->last_ifname_parent = ifname_parent;
	binding->last_ifname_id = ifname_id;
}
/**
 * nm_editor_bind_vlan_name:
 * @s_vlan: an #NMSettingVlan
 *
 * Binds together several properties on @s_vlan, so that if the
 * %NM_SETTING_VLAN_INTERFACE_NAME matches %NM_SETTING_VLAN_PARENT
 * and %NM_SETTING_VLAN_ID in the obvious way, then changes to
 * %NM_SETTING_VLAN_INTERFACE_NAME will propagate to the other
 * two properties automatically.
 */
void
nm_editor_bind_vlan_name (NMSettingVlan *s_vlan,
                          NMSettingConnection *s_con)
{
	NMEditorVlanWidgetBinding *binding;
	const char *ifname;

	binding = g_slice_new0 (NMEditorVlanWidgetBinding);
	binding->s_vlan = s_vlan;
	binding->s_con = s_con;

	g_signal_connect (s_con, "notify::" NM_SETTING_CONNECTION_INTERFACE_NAME,
	                  G_CALLBACK (vlan_settings_changed), binding);

	g_object_weak_ref (G_OBJECT (s_vlan), vlan_target_destroyed, binding);

	ifname = nm_setting_connection_get_interface_name (s_con);
	if (!parse_interface_name (ifname, &binding->last_ifname_parent, &binding->last_ifname_id)) {
		binding->last_ifname_parent = NULL;
		binding->last_ifname_id = 0;
	}
}
int parse_pko_config_command(token_list_t *list)
{
	int intf_index = -1;
	int queue_cnt = -1;
	int port_cnt = -1;
	int tok_offset = 0;
	int interfaces[CVMX_HELPER_MAX_IFACE];
	int intf_cnt, i;

	if (SC(TK[1],"command_queue") == 0)
		return (parse_fpa_config_command(list, &pko_fpa_cfg, "pko command queue pool"));
	if  ( (SC(TK[0],"pko") != 0) || (SC(TK[1],"interface") != 0) ||
	      (SC(TK[2],"=") != 0) || (list->token_index < 9) ) {
		cvmx_dprintf("ERROR: invalid pko command :");
		return -1;
		//show_token_list(list);
	}
	intf_cnt = parse_interface_name(TK[3], interfaces,
					CVMX_HELPER_MAX_IFACE);

	if (intf_cnt < 0) {
		cvmx_dprintf("ERROR: invalid interface name = %s \n", TK[3]);
		return -1;
	}

	if (SC(TK[4],"interface_index") == 0)
	{
		if (intf_cnt != 1) {
			cvmx_dprintf("ERROR: cannot specify interface_index"
				     " when using wild card for specifying"
				     " interface name\n");
			return -1;
		}
		if (SC(TK[5],"=") != 0) {
			cvmx_dprintf("ERROR: invalid pko config command : no "
				     "equal sign after interface_index \n");
			return -1;
		}
		tok_offset = 3;
		intf_index = ST(TK[6], 0, 10);
		if ((intf_index >= CVMX_HELPER_CFG_MAX_PORT_PER_IFACE) ||
			(intf_index < 0)) {
			cvmx_dprintf("ERROR: invalid intf_index=%d max=%d\n",
				     intf_index,
				     CVMX_HELPER_CFG_MAX_PORT_PER_IFACE-1);
			return -1;
		}
	}

	if ( (SC(TK[tok_offset + 4],"internal_port_cnt") != 0) ||
	     (SC(TK[tok_offset + 5],"=") != 0) ) {
		cvmx_dprintf("ERROR: invalid pko config command  while looking"
			     "for internal_port_cnt \n");
		return -1;
	}
	if ( (SC(TK[tok_offset+7],"queues_per_internal_port") != 0) ||
	     (SC(TK[tok_offset+8],"=") != 0) )  {
		cvmx_dprintf("ERROR: invalid pko config command while looking"
			     "for queues_per_internal_port\n");
		return -1;
	}
#define PKO_CFG __cvmx_pko_config

	port_cnt = (int) ST(TK[tok_offset+6], 0, 10);
	queue_cnt  = (int) ST(TK[tok_offset+9], 0, 10);

	for(i=0; i<intf_cnt; i++) {
		int intf_num = interfaces[i];
		if (intf_num == -1)
			continue;
		if ( (is_interface_disabled(intf_num) == 1)  && dbg_parse) {
			cvmx_dprintf("skipping config interace_num=%d :",
				     intf_num);
			show_token_list(list);
		}
		if (intf_index != -1) {
			//cvmx_dprintf("%d:%d %d %d \n", intf_num, intf_index, port_cnt, queue_cnt);
			PKO_CFG[intf_num][intf_index].internal_port_cnt = port_cnt;
			PKO_CFG[intf_num][intf_index].queues_per_internal_port = queue_cnt;
		} else {
			int index;
			int port_max = __cvmx_helper_early_ports_on_interface(intf_num);
			for(index=0; index<port_max; index++) {
				PKO_CFG[intf_num][index].internal_port_cnt = port_cnt;
				PKO_CFG[intf_num][index].queues_per_internal_port = queue_cnt;
			}
		}
		if(dbg_parse)
			cvmx_dprintf("interface=%d interface_index=%d queue_cnt"
				     "=%d port_cnt=%d\n", intf_num, intf_index,
				     queue_cnt, port_cnt);
	}
#undef PKO_CFG
	return 0;
}